diff --git a/pl-grid-column.js b/pl-grid-column.js index c5d08df..2ef3c61 100644 --- a/pl-grid-column.js +++ b/pl-grid-column.js @@ -65,6 +65,9 @@ class PlGridColumn extends PlElement { }, _cellTemplate: { type: Object + }, + _footerTemplate: { + type: Object } } @@ -142,11 +145,16 @@ class PlGridColumn extends PlElement { connectedCallback() { super.connectedCallback(); - let tplEl = [...this.childNodes].find(n => n.nodeType === document.COMMENT_NODE && n.textContent.startsWith('tpl:')); - if (tplEl) { - // host context can be assigned to template - this._cellTemplate = tplEl?._tpl; - this._cellTemplate._hctx = [...tplEl._hctx, this]; + let tplEls = [...this.childNodes].filter(n => n.nodeType === document.COMMENT_NODE && n.textContent.startsWith('tpl:')); + let footerTpl = tplEls.find(tplEl => tplEl._tpl.tpl.getAttribute('is') == 'footer'); + if(footerTpl) { + this._footerTemplate = footerTpl?._tpl; + this._footerTemplate._hctx = [...footerTpl._hctx, this]; + } + let cellTpl = tplEls.find(tplEl => !tplEl._tpl.tpl.hasAttribute('is')); + if(cellTpl) { + this._cellTemplate = cellTpl?._tpl; + this._cellTemplate._hctx = [...cellTpl._hctx, this]; } else { this._cellTemplate = html`[[_getValue(row, field, kind, format)]]`; diff --git a/pl-grid.js b/pl-grid.js index da682c1..490e0e6 100644 --- a/pl-grid.js +++ b/pl-grid.js @@ -6,7 +6,7 @@ import "@plcmp/pl-icon"; import "@plcmp/pl-iconset-default"; import "@plcmp/pl-data-tree"; -import { PlResizeableMixin, throttle } from '@plcmp/utils'; +import { PlResizeableMixin, throttle, PlaceHolder } from '@plcmp/utils'; import "./pl-grid-column.js"; @@ -19,7 +19,9 @@ class PlGrid extends PlResizeableMixin(PlElement) { _columns: { type: Array, value: () => [] }, keyField: { type: String }, pkeyField: { type: String }, - hasChildField: { type: String, value: '_haschildren' } + hasChildField: { type: String, value: '_haschildren' }, + + _hasFooter: { type: Boolean, value: false } } static css = css` @@ -40,9 +42,11 @@ class PlGrid extends PlResizeableMixin(PlElement) { #container { width: 100%; height: 100%; - overflow: auto; + display: flex; + flex-direction: column; position: relative; contain: strict; + overflow:auto; } #headerContainer{ @@ -50,10 +54,21 @@ class PlGrid extends PlResizeableMixin(PlElement) { width: 100%; position: sticky; background-color: var(--grey-lightest); - z-index: 1; + z-index: 2; top: 0; } + #footerContainer { + display: flex; + width: 100%; + background-color: var(--grey-lightest); + z-index: 2; + bottom: 0; + will-change: bottom; + height: 32px; + position: absolute; + } + #header{ display: var(--pl-grid-header-display, flex); border-bottom: 1px solid var(--grey-light); @@ -63,17 +78,43 @@ class PlGrid extends PlResizeableMixin(PlElement) { will-change: width; } + #footer{ + display: var(--pl-grid-header-display, flex); + border-top: 1px solid var(--grey-base); + position: sticky; + bottom: 0; + flex: 1; + will-change: width; + } + + .footerEl { + display: flex; + align-items: center; + height: 100%; + padding: var(--space-sm); + box-sizing: border-box; + font: var(--header-font); + color: var(--header-color); + } + + .footerCell{ + overflow: hidden; + text-overflow: ellipsis; + } + .headerEl[fixed], - .headerEl[action] { + .headerEl[action], + .footerEl[fixed], + .footerEl[action] { position: sticky; z-index: 3; } - .headerEl[action] { + .headerEl[action], .footerEl[action] { right: 0; } - .headerEl[hidden] { + .headerEl[hidden], .footerEl[hidden] { display: none; } @@ -83,6 +124,8 @@ class PlGrid extends PlResizeableMixin(PlElement) { position: relative; display: flex; flex-direction: column; + flex-shrink:0; + padding-bottom: var(--footer-padding, 0); } .row { @@ -93,6 +136,19 @@ class PlGrid extends PlResizeableMixin(PlElement) { background-color: var(--background-color); width: 100%; box-sizing: border-box; + position: relative; + } + + .row[loading]::after { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left:0; + display: flex; + content:'Загрузка...'; + align-items: center; + justify-content: center; } .cell { @@ -114,6 +170,7 @@ class PlGrid extends PlResizeableMixin(PlElement) { text-overflow: ellipsis; overflow: hidden; line-height: 24px; + width: 100%; } .cell[fixed] { @@ -148,7 +205,6 @@ class PlGrid extends PlResizeableMixin(PlElement) { z-index: 1; } - .top-toolbar ::slotted(*) { width: 100%; padding: var(--space-sm); @@ -168,6 +224,21 @@ class PlGrid extends PlResizeableMixin(PlElement) { } `; static treeFirstCellTemplate = html``; + static footerTemplate = html` +
+ +
` + + static template = html`
@@ -185,7 +256,7 @@ class PlGrid extends PlResizeableMixin(PlElement) {