Update and fixes

This commit is contained in:
trading_peter 2023-01-13 11:52:10 +01:00
parent 1f7f38932f
commit 98fbf98a7f
3 changed files with 38 additions and 54 deletions

View File

@ -13,7 +13,7 @@
"author": "trading_peter", "author": "trading_peter",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@lit-labs/virtualizer": "^0.7.0", "@lit-labs/virtualizer": "^1.0.1",
"@tp/helpers": "^1.1.3", "@tp/helpers": "^1.1.3",
"@tp/tp-checkbox": "^1.0.4", "@tp/tp-checkbox": "^1.0.4",
"@tp/tp-icon": "^1.0.1", "@tp/tp-icon": "^1.0.1",

View File

@ -69,13 +69,13 @@ class TpTableItem extends BaseElement {
} }
render() { render() {
const { columns, item } = this; const { columns, item, selected } = this;
return html` return html`
<div id="grid" class="wrap" part="row"> <div id="grid" class="wrap" part="row">
${this.selectable ? html` ${this.selectable ? html`
<div class="chk" part="chk"> <div class="chk" part="chk">
<tp-checkbox id="selectionChk" @click=${this._updateSelectionState}></tp-checkbox> <tp-checkbox id="selectionChk" .checked=${selected} @click=${this._updateSelectionState}></tp-checkbox>
</div> </div>
` : null} ` : null}
${Array.isArray(columns) ? columns.map((column, idx) => { ${Array.isArray(columns) ? columns.map((column, idx) => {
@ -93,6 +93,7 @@ class TpTableItem extends BaseElement {
item: { type: Object, hasChanged: () => true }, item: { type: Object, hasChanged: () => true },
columns: { type: Array }, columns: { type: Array },
selectable: { type: Boolean }, selectable: { type: Boolean },
selected: { type: Boolean, reflect: true },
}; };
} }
@ -101,10 +102,6 @@ class TpTableItem extends BaseElement {
} }
async updated(changes) { async updated(changes) {
if (changes.has('item') && this.selectable) {
this.$.selectionChk.checked = Boolean(this.item.__selected__);
}
if (changes.has('columns') && Array.isArray(this.columns)) { if (changes.has('columns') && Array.isArray(this.columns)) {
let colWidths = this.columns.filter(col => col.required || col.visible).map(col => col.width).join(' '); let colWidths = this.columns.filter(col => col.required || col.visible).map(col => col.width).join(' ');
@ -135,9 +132,8 @@ class TpTableItem extends BaseElement {
_updateSelectionState(e) { _updateSelectionState(e) {
const target = e.target; const target = e.target;
setTimeout(() => { this.selected = e.target.checked;
this.dispatchEvent(new CustomEvent('selection-changed', { detail: { item: this.item, selected: target.checked }, bubbles: true, composed: true })); this.dispatchEvent(new CustomEvent('row-selection-changed', { detail: { item: this.item, selected: target.checked }, bubbles: true, composed: true }));
}, 0);
} }
} }

View File

@ -184,13 +184,13 @@ export class TpTable extends DomQuery(LitElement) {
<div class="wrap"> <div class="wrap">
<div id="tableHeader" part="header" class="list-headline" @track=${this._colResizeTracked}> <div id="tableHeader" part="header" class="list-headline" @track=${this._colResizeTracked}>
${this.selectable ? html` ${this.selectable ? html`
<div class="select-col" part="chkAll"><tp-checkbox @checked-changed=${e => this._checkedChanged(e)}></tp-checkbox></div> <div class="select-col" part="chkAll"><tp-checkbox @toggled=${e => this._checkedChanged(e)}></tp-checkbox></div>
` : null} ` : null}
${columns.map(column => this.renderColumnHeader(column))} ${columns.map(column => this.renderColumnHeader(column))}
</div> </div>
<div class="list"> <div class="list" @row-selection-changed=${(e) => this._selectionChanged(e)}>
${this._emptyMessage} ${this._emptyMessage}
<lit-virtualizer id="virtualList" part="list" @scroll=${this._onScroll} scroller .items=${items} .renderItem=${(item, idx) => this.renderItem(item, idx, columns)}></lit-virtualizer> <lit-virtualizer id="virtualList" part="list" @scroll=${this._onScroll} scroller .items=${items} .renderItem=${(item, idx) => this.renderItem(item, idx, columns, this._selItems.has(this.getItemId(item)))}></lit-virtualizer>
</div> </div>
<tp-scroll-threshold id="threshold" lowerThreshold="40"></tp-scroll-threshold> <tp-scroll-threshold id="threshold" lowerThreshold="40"></tp-scroll-threshold>
@ -231,16 +231,16 @@ export class TpTable extends DomQuery(LitElement) {
return svg`<path fill="var(--tp-table-icon-color)" d="M7,15L12,10L17,15H7Z">`; return svg`<path fill="var(--tp-table-icon-color)" d="M7,15L12,10L17,15H7Z">`;
} }
renderItem(item, idx, columns) { renderItem(item, idx, columns, selected) {
return html` return html`
<tp-table-item <tp-table-item
exportparts="cell,odd,row,chk" exportparts="cell,odd,row,chk"
item item
.index=${idx} .index=${idx}
.item=${item} .item=${item}
.selected=${selected}
.selectable=${this.selectable} .selectable=${this.selectable}
.columns=${columns} .columns=${columns}>
@selection-changed=${(e) => this._selectionChanged(e)}>
</tp-table-item> </tp-table-item>
`; `;
} }
@ -250,7 +250,7 @@ export class TpTable extends DomQuery(LitElement) {
sorting: { type: Object }, sorting: { type: Object },
selectable: { type: Boolean }, selectable: { type: Boolean },
columns: { type: Array }, columns: { type: Array },
_selItems: { type: Array }, _selItems: { type: Map },
_visibleColumns: { type: Array }, _visibleColumns: { type: Array },
items: { type: Array }, items: { type: Array },
_advFilters: { type: Array }, _advFilters: { type: Array },
@ -263,7 +263,7 @@ export class TpTable extends DomQuery(LitElement) {
constructor() { constructor() {
super(); super();
this._selItems = []; this._selItems = new Map();
} }
updated(changes) { updated(changes) {
@ -301,8 +301,13 @@ export class TpTable extends DomQuery(LitElement) {
this.reloadPagedList(); this.reloadPagedList();
} }
scrollToIndex(idx) { // Override this to change how the table derives item ids.
this.$.virtualList.scrollToIndex(idx); getItemId(item) {
return item._id || item.id;
}
scrollToIndex(idx, position) {
this.$.virtualList.scrollToIndex(idx, position);
} }
firstUpdated() { firstUpdated() {
@ -392,60 +397,43 @@ export class TpTable extends DomQuery(LitElement) {
} else { } else {
this._selectNone(); this._selectNone();
} }
this.items = [...this.items];
} }
_selectAll() { _selectAll() {
this.items = this.items.map((entry) => { this._selItems = new Map();
entry.__selected__ = true; this.items.forEach(item => {
return entry; this._selItems.set(this.getItemId(item), item);
}); });
this.requestUpdate('items');
this._selectionChanged(); this._selectionChanged();
} }
_selectNone() { _selectNone() {
this.items = this.items.map((entry) => { this._selItems = new Map();
entry.__selected__ = false;
return entry;
});
this._selectionChanged(); this._selectionChanged();
} }
_selectionChanged(e) { _selectionChanged(e) {
if (this.__restoringSelection) return;
if (e !== undefined) { if (e !== undefined) {
const item = this.items.find(item => item._id === e.detail.item._id); if (e.detail.selected) {
item.__selected__ = e.detail.selected; this._selItems.set(this.getItemId(e.detail.item), e.detail.item);
} else {
this._selItems.delete(this.getItemId(e.detail.item));
}
} }
this._selItems = this.items.filter(entry => entry.__selected__ === true); this.dispatchEvent(new CustomEvent('item-selection-changed', { detail: Array.from(this._selItems.values()), bubbles: true, composed: true }));
this.dispatchEvent(new CustomEvent('item-selection-changed', { detail: this._selItems, bubbles: true, composed: true }));
} }
_updateSelEntries() { _updateSelEntries() {
this._hiddenSelection = 0;
if (!this.items) { if (!this.items) {
this._selItems = []; this._selItems = new Map();
} else { }
this._selItems.forEach(sel => {
const idx = this.items.findIndex(entry => entry._id === sel._id); for (const selItem of this._selItems.values()) {
if (idx > -1) { if (this.items.findIndex(item => this.getItemId(item) === this.getItemId(selItem)) > -1) {
// Suppress rebuild of the selected invoices list.
// When we restore the selection on a filtered list of invoices we would loose the selection of hidden onces
// when _selectionChanged is triggered. So we set a flag that the observer is skipped.
this.__restoringSelection = true;
this.items[idx].__selected__ = true;
this.__restoringSelection = false;
} else {
this._hiddenSelection++;
} }
});
} }
} }
} }