UNPKG

@delon/abc

Version:

Common business components of ng-alain.

749 lines 175 kB
import { DecimalPipe, DOCUMENT } from '@angular/common'; import { booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, EventEmitter, inject, Input, numberAttribute, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Router } from '@angular/router'; import { isObservable, of, filter, catchError, map, finalize, throwError, lastValueFrom } from 'rxjs'; import { ALAIN_I18N_TOKEN, DatePipe, DelonLocaleService, DrawerHelper, ModalHelper, YNPipe } from '@delon/theme'; import { deepCopy, deepMergeKey } from '@delon/util/other'; import { NzContextMenuService } from 'ng-zorro-antd/dropdown'; import { STColumnSource } from './st-column-source'; import { STDataSource } from './st-data-source'; import { STExport } from './st-export'; import { STRowSource } from './st-row.directive'; import { ST_DEFAULT_CONFIG } from './st.config'; import * as i0 from "@angular/core"; import * as i1 from "@delon/util/config"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; import * as i4 from "@delon/abc/let"; import * as i5 from "ng-zorro-antd/table"; import * as i6 from "ng-zorro-antd/icon"; import * as i7 from "ng-zorro-antd/checkbox"; import * as i8 from "ng-zorro-antd/menu"; import * as i9 from "ng-zorro-antd/dropdown"; import * as i10 from "ng-zorro-antd/tooltip"; import * as i11 from "ng-zorro-antd/resizable"; import * as i12 from "./st-filter.component"; import * as i13 from "@delon/abc/cell"; import * as i14 from "ng-zorro-antd/popconfirm"; import * as i15 from "ng-zorro-antd/badge"; import * as i16 from "ng-zorro-antd/divider"; import * as i17 from "ng-zorro-antd/radio"; import * as i18 from "ng-zorro-antd/tag"; import * as i19 from "./st-widget-host.directive"; export class STComponent { get req() { return this._req; } set req(value) { this._req = deepMergeKey({}, true, this.cog.req, value); } /** 返回体配置 */ get res() { return this._res; } set res(value) { const item = (this._res = deepMergeKey({}, true, this.cog.res, value)); const reName = item.reName; if (typeof reName !== 'function') { if (!Array.isArray(reName.list)) reName.list = reName.list.split('.'); if (!Array.isArray(reName.total)) reName.total = reName.total.split('.'); } this._res = item; } get page() { return this._page; } set page(value) { this._page = { ...this.cog.page, ...value }; this.updateTotalTpl(); } get multiSort() { return this._multiSort; } set multiSort(value) { if ((typeof value === 'boolean' && !booleanAttribute(value)) || (typeof value === 'object' && Object.keys(value).length === 0)) { this._multiSort = undefined; return; } this._multiSort = { ...(typeof value === 'object' ? value : {}) }; } set widthMode(value) { this._widthMode = { ...this.cog.widthMode, ...value }; } get widthMode() { return this._widthMode; } set widthConfig(val) { this._widthConfig = val; this.customWidthConfig = val && val.length > 0; } set resizable(val) { this._resizable = typeof val === 'object' ? val : { disabled: !booleanAttribute(val) }; } /** * Get the number of the current page */ get count() { return this._data.length; } /** * Get the data of the current page */ get list() { return this._data; } get noColumns() { return this.columns == null; } constructor(configSrv) { this.i18nSrv = inject(ALAIN_I18N_TOKEN); this.el = inject(ElementRef).nativeElement; this.cdr = inject(ChangeDetectorRef); this.doc = inject(DOCUMENT); this.exportSrv = inject(STExport); this.columnSource = inject(STColumnSource); this.dataSource = inject(STDataSource); this.delonI18n = inject(DelonLocaleService); this.cms = inject(NzContextMenuService, { optional: true }); this.destroy$ = inject(DestroyRef); this.totalTpl = ``; this.inied = false; this.customWidthConfig = false; this._widthConfig = []; this.locale = {}; this._loading = false; this._data = []; this._statistical = {}; this._isPagination = true; this._allChecked = false; this._allCheckedDisabled = false; this._indeterminate = false; this._headers = []; this._columns = []; this.contextmenuList = []; this.ps = 10; this.pi = 1; this.total = 0; this.loading = null; this.loadingDelay = 0; this.loadingIndicator = null; this.bordered = false; this.scroll = { x: null, y: null }; this.showHeader = true; this.expandRowByClick = false; this.expandAccordion = false; this.expand = null; this.responsive = true; this.error = new EventEmitter(); this.change = new EventEmitter(); this.virtualScroll = false; this.virtualItemSize = 54; this.virtualMaxBufferPx = 200; this.virtualMinBufferPx = 100; this.virtualForTrackBy = index => index; this.trackBy = (_, item) => item; this.delonI18n.change.pipe(takeUntilDestroyed()).subscribe(() => { this.locale = this.delonI18n.getData('st'); if (this._columns.length > 0) { this.updateTotalTpl(); this.cd(); } }); this.i18nSrv.change .pipe(takeUntilDestroyed(), filter(() => this._columns.length > 0)) .subscribe(() => this.refreshColumns()); this.setCog(configSrv.merge('st', ST_DEFAULT_CONFIG)); } setCog(cog) { const copyMultiSort = { ...cog.multiSort }; // Because multiSort.global will affect the result, it should be removed first, and multiSort will be operated again after processing. delete cog.multiSort; this.cog = cog; Object.assign(this, cog); if (copyMultiSort.global !== false) { this.multiSort = copyMultiSort; } this.columnSource.setCog(cog); this.dataSource.setCog(cog); } cd() { this.cdr.detectChanges(); return this; } refreshData() { this._data = [...this._data]; return this.cd(); } renderTotal(total, range) { return this.totalTpl ? this.totalTpl.replace('{{total}}', total).replace('{{range[0]}}', range[0]).replace('{{range[1]}}', range[1]) : ''; } changeEmit(type, data) { const res = { type, pi: this.pi, ps: this.ps, total: this.total }; if (data != null) { res[type] = data; } this.change.emit(res); } // #region data /** * 获取过滤后所有数据 * - 本地数据:包含排序、过滤后不分页数据 * - 远程数据:不传递 `pi`、`ps` 两个参数 */ get filteredData() { return this.loadData({ paginator: false }).pipe(map(res => res.list)); } updateTotalTpl() { const { total } = this.page; if (typeof total === 'string' && total.length) { this.totalTpl = total; } else if (booleanAttribute(total)) { this.totalTpl = this.locale.total; } else { this.totalTpl = ''; } } setLoading(val) { if (this.loading == null) { this._loading = val; this.cdr.detectChanges(); } } loadData(options) { const { pi, ps, data, req, res, page, total, singleSort, multiSort, rowClassName, _columns, _headers } = this; return this.dataSource .process({ pi, ps, total, data, req, res, page, columns: _columns, headers: _headers, singleSort, multiSort, rowClassName, paginator: true, customRequest: this.customRequest || this.cog.customRequest, ...options }) .pipe(takeUntilDestroyed(this.destroy$)); } loadPageData() { this.setLoading(true); return this.loadData().pipe(finalize(() => this.setLoading(false)), catchError(error => { this.error.emit({ type: 'req', error }); return throwError(() => error); }), map(result => { const undefinedString = 'undefined'; if (typeof result.pi !== undefinedString) { this.pi = result.pi; } if (typeof result.ps !== undefinedString) { this.ps = result.ps; } if (typeof result.total !== undefinedString) { this.total = result.total; } if (typeof result.pageShow !== undefinedString) { this._isPagination = result.pageShow; } this._data = result.list ?? []; this._statistical = result.statistical; // Should be re-render in next tike when using virtual scroll // https://github.com/ng-alain/ng-alain/issues/1836 if (this.cdkVirtualScrollViewport != null) { Promise.resolve().then(() => this.cdkVirtualScrollViewport?.checkViewportSize()); } this._refCheck(); this.changeEmit('loaded', result.list); return this; })); } /** 清空所有数据 */ clear(cleanStatus = true) { if (cleanStatus) { this.clearStatus(); } this._data = []; return this.cd(); } /** 清空所有状态 */ clearStatus() { return this.clearCheck().clearRadio().clearFilter().clearSort(); } /** * 根据页码重新加载数据 * * @param pi 指定当前页码,默认:`1` * @param extraParams 重新指定 `extraParams` 值 * @param options 选项 */ load(pi = 1, extraParams, options) { if (pi !== -1) this.pi = pi; if (typeof extraParams !== 'undefined') { this.req.params = options && options.merge ? { ...this.req.params, ...extraParams } : extraParams; } this._change('pi', options); return this; } /** * 重新刷新当前页 * * @param extraParams 重新指定 `extraParams` 值 */ reload(extraParams, options) { return this.load(-1, extraParams, options); } /** * 重置且重新设置 `pi` 为 `1`,包含以下值: * - `check` 数据 * - `radio` 数据 * - `sort` 数据 * - `fileter` 数据 * * @param extraParams 重新指定 `extraParams` 值 */ reset(extraParams, options) { this.clearStatus().load(1, extraParams, options); return this; } _toTop(enforce) { if (!(enforce == null ? this.page.toTop : enforce)) return; const el = this.el; el.scrollIntoView(); // fix header height this.doc.documentElement.scrollTop -= this.page.toTopOffset; if (this.scroll) { if (this.cdkVirtualScrollViewport) { this.cdkVirtualScrollViewport.scrollTo({ top: 0, left: 0 }); } else { el.querySelector('.ant-table-body, .ant-table-content')?.scrollTo(0, 0); } } } _change(type, options) { if (type === 'pi' || (type === 'ps' && this.pi <= Math.ceil(this.total / this.ps))) { this.loadPageData().subscribe(() => this._toTop(options?.toTop)); } this.changeEmit(type); } closeOtherExpand(item) { if (this.expandAccordion === false) return; this._data.filter(i => i !== item).forEach(i => (i.expand = false)); } _rowClick(e, item, index, dbl) { const el = e.target; if (el.nodeName === 'INPUT') return; const { expand, expandRowByClick } = this; if (!!expand && item.showExpand !== false && expandRowByClick) { item.expand = !item.expand; this.closeOtherExpand(item); this.changeEmit('expand', item); return; } const data = { e, item, index }; if (dbl) { this.changeEmit('dblClick', data); } else { this._clickRowClassName(el, item, index); this.changeEmit('click', data); } } _clickRowClassName(el, item, index) { const cr = this.clickRowClassName; if (cr == null) return; const config = { exclusive: false, ...(typeof cr === 'string' ? { fn: () => cr } : cr) }; const className = config.fn(item, index); const trEl = el.closest('tr'); if (config.exclusive) { trEl.parentElement.querySelectorAll('tr').forEach((a) => a.classList.remove(className)); } if (trEl.classList.contains(className)) { trEl.classList.remove(className); } else { trEl.classList.add(className); } } _expandChange(item, expand) { item.expand = expand; this.closeOtherExpand(item); this.changeEmit('expand', item); } _stopPropagation(ev) { ev.stopPropagation(); } _refColAndData() { this._columns.forEach(c => { this._data.forEach((i, idx) => { const values = i._values; if (c.type === 'no') { const text = `${this.dataSource.getNoIndex(i, c, idx)}`; values[c.__point] = { text, _text: text, org: idx, safeType: 'text' }; } values[c.__point].props = this.dataSource.getCell(c, i, idx); }); }); return this.refreshData(); } /** * Add a rows in the table, like this: * * ``` * this.st.addRow(stDataItem) * ``` * * **TIPS:** Don't change the `total` value, it is recommended to use the `reload` method if needed */ addRow(data, options) { if (!Array.isArray(data)) data = [data]; this._data.splice(options?.index ?? 0, 0, ...data); return this.optimizeData()._refColAndData(); } /** * Remove a row in the table, like this: * * ``` * this.st.removeRow(0) * this.st.removeRow(stDataItem) * ``` * * **TIPS:** Don't change the `total` value, it is recommended to use the `reload` method if needed */ removeRow(data) { if (typeof data === 'number') { this._data.splice(data, 1); } else { if (!Array.isArray(data)) { data = [data]; } const curData = this._data; for (var i = curData.length; i--;) { if (data.indexOf(curData[i]) !== -1) { curData.splice(i, 1); } } } return this._refCheck()._refColAndData(); } /** * Sets the row value for the `index` in the table, like this: * * - `optinos.refreshSchema` Whether to refresh of st schemas * - `optinos.emitReload` Whether to trigger a reload http request when data is url * * ``` * this.st.setRow(0, { price: 100 }) * this.st.setRow(0, { price: 100, name: 'asdf' }) * this.st.setRow(item, { price: 100 }) * ``` */ setRow(index, item, options) { options = { refreshSchema: false, emitReload: false, ...options }; if (typeof index !== 'number') { index = this._data.indexOf(index); } this._data[index] = deepMergeKey(this._data[index], false, item); this.optimizeData(); if (options.refreshSchema) { this.resetColumns({ emitReload: options.emitReload }); return this; } return this.refreshData(); } // #endregion // #region sort sort(col, value) { if (this.multiSort) { col._sort.default = value; col._sort.tick = this.dataSource.nextSortTick; } else { this._headers.forEach(row => { row.forEach(item => (item.column._sort.default = item.column === col ? value : null)); }); } this.cdr.detectChanges(); this.loadPageData().subscribe(() => { const res = { value, map: this.dataSource.getReqSortMap(this.singleSort, this.multiSort, this._headers), column: col }; this.changeEmit('sort', res); }); } clearSort() { this._headers.forEach(row => { row.forEach(item => (item.column._sort.default = null)); }); return this; } // #endregion // #region filter _handleFilter(col, confirm) { if (!confirm) { this.columnSource.cleanFilter(col); } // 过滤表示一种数据的变化应重置页码为 `1` this.pi = 1; this.columnSource.updateDefault(col.filter); this.loadPageData().subscribe(() => this.changeEmit('filter', col)); } handleFilterNotify(value) { this.changeEmit('filterChange', value); } clearFilter() { this._columns.filter(w => w.filter && w.filter.default === true).forEach(col => this.columnSource.cleanFilter(col)); return this; } // #endregion // #region checkbox /** 清除所有 `checkbox` */ clearCheck() { return this.checkAll(false); } _refCheck() { const validData = this._data.filter(w => !w.disabled); const checkedList = validData.filter(w => w.checked === true); this._allChecked = checkedList.length > 0 && checkedList.length === validData.length; const allUnChecked = validData.every(value => !value.checked); this._indeterminate = !this._allChecked && !allUnChecked; this._allCheckedDisabled = this._data.length === this._data.filter(w => w.disabled).length; return this.cd(); } checkAll(checked) { checked = typeof checked === 'undefined' ? this._allChecked : checked; this._data.filter(w => !w.disabled).forEach(i => (i.checked = checked)); return this._refCheck()._checkNotify().refreshData(); } _rowSelection(row) { row.select(this._data); return this._refCheck()._checkNotify(); } _checkNotify() { const res = this._data.filter(w => !w.disabled && w.checked === true); this.changeEmit('checkbox', res); return this; } // #endregion // #region radio /** 清除所有 `radio` */ clearRadio() { this._data.filter(w => w.checked).forEach(item => (item.checked = false)); this.changeEmit('radio', null); return this.refreshData(); } // #endregion _handleTd(ev) { switch (ev.type) { case 'checkbox': this._refCheck()._checkNotify(); break; case 'radio': this.changeEmit('radio', ev.item); this.refreshData(); break; } } // #region export /** * 导出当前页,确保已经注册 `XlsxModule` * * @param newData 重新指定数据;若为 `true` 表示使用 `filteredData` 数据 * @param opt 额外参数 */ export(newData, opt) { const data = Array.isArray(newData) ? this.dataSource.optimizeData({ columns: this._columns, result: newData }) : this._data; (newData === true ? this.filteredData : of(data)).subscribe((res) => this.exportSrv.export({ columens: this._columns, ...opt, data: res })); } // #endregion // #region resizable colResize({ width }, column) { column.width = `${width}px`; this.changeEmit('resize', column); } // #endregion // #region contextmenu onContextmenu(event) { if (!this.contextmenu) { return; } event.preventDefault(); event.stopPropagation(); const colEl = event.target.closest('[data-col-index]'); if (!colEl) { return; } const colIndex = Number(colEl.dataset.colIndex); const rowIndex = Number(colEl.closest('tr').dataset.index); const isTitle = isNaN(rowIndex); const obs$ = this.contextmenu({ event, type: isTitle ? 'head' : 'body', rowIndex: isTitle ? null : rowIndex, colIndex, data: isTitle ? null : this.list[rowIndex], column: this._columns[colIndex] }); (isObservable(obs$) ? obs$ : of(obs$)) .pipe(takeUntilDestroyed(this.destroy$), filter(res => res.length > 0)) .subscribe(res => { this.contextmenuList = res.map(i => { if (!Array.isArray(i.children)) { i.children = []; } return i; }); this.cdr.detectChanges(); this.cms?.create(event, this.contextmenuTpl); }); } // #endregion get cdkVirtualScrollViewport() { return this.orgTable?.cdkVirtualScrollViewport; } _resetColumns(options) { options = { emitReload: true, preClearData: false, ...options }; if (typeof options.columns !== 'undefined') { this.columns = options.columns; } if (typeof options.pi !== 'undefined') { this.pi = options.pi; } if (typeof options.ps !== 'undefined') { this.ps = options.ps; } if (options.emitReload) { // Should clean data, Because of changing columns may cause inaccurate data options.preClearData = true; } if (options.preClearData) { this._data = []; } this.refreshColumns(); if (options.emitReload) { return this.loadPageData(); } else { this.cd(); return of(this); } } resetColumns(options) { return lastValueFrom(this._resetColumns(options)); } refreshColumns() { const res = this.columnSource.process(this.columns, { widthMode: this.widthMode, resizable: this._resizable, safeType: this.cog.safeType }); this._columns = res.columns; this._headers = res.headers; if (this.customWidthConfig === false && res.headerWidths != null) { this._widthConfig = res.headerWidths; } return this; } optimizeData() { this._data = this.dataSource.optimizeData({ columns: this._columns, result: this._data, rowClassName: this.rowClassName }); return this; } /** * Return pure data, `st` internally maintains a set of data for caching, this part of data may affect the backend * * 返回纯净数据,`st` 内部会维护一组用于缓存的数据,这部分数据可能会影响后端 */ pureItem(itemOrIndex) { if (typeof itemOrIndex === 'number') { itemOrIndex = this._data[itemOrIndex]; } if (!itemOrIndex) { return null; } const copyItem = deepCopy(itemOrIndex); ['_values', '_rowClassName'].forEach(key => delete copyItem[key]); return copyItem; } ngAfterViewInit() { this.refreshColumns(); if (!this.req.lazyLoad) this.loadPageData().subscribe(); this.inied = true; } ngOnChanges(changes) { if (changes.loading) { this._loading = changes.loading.currentValue; } if (!this.inied) return; if (changes.columns) { this.refreshColumns().optimizeData(); } if (changes.data) { this.loadPageData().subscribe(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: STComponent, deps: [{ token: i1.AlainConfigService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: STComponent, selector: "st", inputs: { req: "req", res: "res", page: "page", data: "data", columns: "columns", contextmenu: "contextmenu", ps: ["ps", "ps", (v) => numberAttribute(v, 10)], pi: ["pi", "pi", (v) => numberAttribute(v, 1)], total: ["total", "total", (v) => numberAttribute(v, 0)], loading: "loading", loadingDelay: ["loadingDelay", "loadingDelay", numberAttribute], loadingIndicator: "loadingIndicator", bordered: ["bordered", "bordered", booleanAttribute], size: "size", scroll: "scroll", singleSort: "singleSort", multiSort: "multiSort", rowClassName: "rowClassName", clickRowClassName: "clickRowClassName", widthMode: "widthMode", widthConfig: "widthConfig", resizable: "resizable", header: "header", showHeader: ["showHeader", "showHeader", booleanAttribute], footer: "footer", bodyHeader: "bodyHeader", body: "body", expandRowByClick: ["expandRowByClick", "expandRowByClick", booleanAttribute], expandAccordion: ["expandAccordion", "expandAccordion", booleanAttribute], expand: "expand", noResult: "noResult", responsive: ["responsive", "responsive", booleanAttribute], responsiveHideHeaderFooter: ["responsiveHideHeaderFooter", "responsiveHideHeaderFooter", booleanAttribute], virtualScroll: ["virtualScroll", "virtualScroll", booleanAttribute], virtualItemSize: ["virtualItemSize", "virtualItemSize", numberAttribute], virtualMaxBufferPx: ["virtualMaxBufferPx", "virtualMaxBufferPx", numberAttribute], virtualMinBufferPx: ["virtualMinBufferPx", "virtualMinBufferPx", numberAttribute], customRequest: "customRequest", virtualForTrackBy: "virtualForTrackBy", trackBy: "trackBy" }, outputs: { error: "error", change: "change" }, host: { properties: { "class.st": "true", "class.st__p-left": "page.placement === 'left'", "class.st__p-center": "page.placement === 'center'", "class.st__width-strict": "widthMode.type === 'strict'", "class.st__row-class": "rowClassName", "class.ant-table-rep": "responsive", "class.ant-table-rep__hide-header-footer": "responsiveHideHeaderFooter" } }, providers: [STDataSource, STRowSource, STColumnSource, STExport, DatePipe, YNPipe, DecimalPipe], viewQueries: [{ propertyName: "orgTable", first: true, predicate: ["table"], descendants: true }, { propertyName: "contextmenuTpl", first: true, predicate: ["contextmenuTpl"], descendants: true }], exportAs: ["st"], usesOnChanges: true, ngImport: i0, template: "<ng-template #titleTpl let-i>\n <span [innerHTML]=\"i._text\"></span>\n @if (i.optional) {\n <small class=\"st__head-optional\" [innerHTML]=\"i.optional\"></small>\n }\n @if (i.optionalHelp) {\n <i class=\"st__head-tip\" nz-tooltip [nzTooltipTitle]=\"i.optionalHelp\" nz-icon nzType=\"question-circle\"></i>\n }\n</ng-template>\n<ng-template #chkAllTpl let-custom>\n <label\n nz-checkbox\n class=\"st__checkall\"\n [nzDisabled]=\"_allCheckedDisabled\"\n [(ngModel)]=\"_allChecked\"\n [nzIndeterminate]=\"_indeterminate\"\n (ngModelChange)=\"checkAll()\"\n [class.ant-table-selection-select-all-custom]=\"custom\"\n ></label>\n</ng-template>\n<nz-table\n #table\n [nzData]=\"_data\"\n [(nzPageIndex)]=\"pi\"\n (nzPageIndexChange)=\"_change('pi')\"\n [(nzPageSize)]=\"ps\"\n (nzPageSizeChange)=\"_change('ps')\"\n [nzTotal]=\"total\"\n [nzShowPagination]=\"_isPagination\"\n [nzFrontPagination]=\"false\"\n [nzBordered]=\"bordered\"\n [nzSize]=\"size\"\n [nzLoading]=\"noColumns || _loading\"\n [nzLoadingDelay]=\"loadingDelay\"\n [nzLoadingIndicator]=\"loadingIndicator\"\n [nzTitle]=\"header!\"\n [nzFooter]=\"footer!\"\n [nzScroll]=\"scroll\"\n [nzVirtualItemSize]=\"virtualItemSize\"\n [nzVirtualMaxBufferPx]=\"virtualMaxBufferPx\"\n [nzVirtualMinBufferPx]=\"virtualMinBufferPx\"\n [nzVirtualForTrackBy]=\"virtualForTrackBy\"\n [nzNoResult]=\"noResult!\"\n [nzPageSizeOptions]=\"page.pageSizes!\"\n [nzShowQuickJumper]=\"page.showQuickJumper\"\n [nzShowSizeChanger]=\"page.showSize\"\n [nzPaginationPosition]=\"page.position!\"\n [nzPaginationType]=\"page.type!\"\n [nzItemRender]=\"page.itemRender!\"\n [nzSimple]=\"page.simple\"\n [nzShowTotal]=\"totalTpl\"\n [nzWidthConfig]=\"_widthConfig\"\n (contextmenu)=\"onContextmenu($event)\"\n [class.st__no-column]=\"noColumns\"\n>\n @if (showHeader) {\n <thead>\n @for (row of _headers; track row) {\n <tr>\n @if ($first && expand) {\n <th nzWidth=\"50px\" [rowSpan]=\"_headers.length\"></th>\n }\n @for (h of row; track h; let index = $index; let last = $last) {\n <th\n *let=\"h.column as _c\"\n [colSpan]=\"h.colSpan\"\n [rowSpan]=\"h.rowSpan\"\n [nzWidth]=\"$any(_c).width\"\n [nzLeft]=\"_c._left!\"\n [nzRight]=\"_c._right!\"\n [ngClass]=\"_c._className\"\n [attr.data-col]=\"_c.indexKey\"\n [attr.data-col-index]=\"index\"\n [nzShowSort]=\"_c._sort.enabled\"\n [nzSortOrder]=\"$any(_c)._sort.default\"\n (nzSortOrderChange)=\"sort(_c, $event)\"\n [nzCustomFilter]=\"!!_c.filter\"\n [class.st__has-filter]=\"_c.filter\"\n nz-resizable\n [nzDisabled]=\"last || $any(_c).resizable.disabled\"\n [nzMaxWidth]=\"$any(_c).resizable.maxWidth\"\n [nzMinWidth]=\"$any(_c).resizable.minWidth\"\n [nzBounds]=\"$any(_c).resizable.bounds\"\n [nzPreview]=\"$any(_c).resizable.preview\"\n (nzResizeEnd)=\"colResize($event, _c)\"\n >\n @if ($any(!last && !$any(_c).resizable.disabled)) {\n <nz-resize-handle nzDirection=\"right\" (click)=\"_stopPropagation($event)\">\n <i></i>\n </nz-resize-handle>\n }\n @if (_c.__renderTitle) {\n <ng-template\n [ngTemplateOutlet]=\"_c.__renderTitle!\"\n [ngTemplateOutletContext]=\"{ $implicit: h.column, index: index }\"\n />\n } @else {\n @switch (_c.type) {\n @case ('checkbox') {\n @if (_c.selections!.length === 0) {\n <ng-template [ngTemplateOutlet]=\"chkAllTpl\" [ngTemplateOutletContext]=\"{ $implicit: false }\" />\n } @else {\n <div class=\"ant-table-selection\">\n <ng-template [ngTemplateOutlet]=\"chkAllTpl\" [ngTemplateOutletContext]=\"{ $implicit: true }\" />\n @if (_c.selections!.length) {\n <div class=\"ant-table-selection-extra\">\n <div\n nz-dropdown\n nzPlacement=\"bottomLeft\"\n [nzDropdownMenu]=\"selectionMenu\"\n class=\"ant-table-selection-down st__checkall-selection\"\n >\n <i nz-icon nzType=\"down\"></i>\n </div>\n </div>\n }\n <nz-dropdown-menu #selectionMenu=\"nzDropdownMenu\">\n <ul nz-menu class=\"ant-table-selection-menu\">\n @for (rw of _c.selections; track $index) {\n <li nz-menu-item (click)=\"_rowSelection(rw)\" [innerHTML]=\"rw.text\"></li>\n }\n </ul>\n </nz-dropdown-menu>\n </div>\n }\n }\n @default {\n <ng-template [ngTemplateOutlet]=\"titleTpl\" [ngTemplateOutletContext]=\"{ $implicit: _c.title }\" />\n }\n }\n }\n @if (_c.filter) {\n <st-filter\n nz-th-extra\n [col]=\"h.column\"\n [f]=\"_c.filter\"\n [locale]=\"locale\"\n (n)=\"handleFilterNotify($event)\"\n (handle)=\"_handleFilter(_c, $event)\"\n />\n }\n </th>\n }\n </tr>\n }\n </thead>\n }\n <tbody class=\"st__body\">\n @if (!_loading) {\n <ng-template [ngTemplateOutlet]=\"bodyHeader!\" [ngTemplateOutletContext]=\"{ $implicit: _statistical }\" />\n }\n <ng-template #bodyTpl let-i let-index=\"index\">\n <tr\n [attr.data-index]=\"index\"\n (click)=\"_rowClick($event, i, index, false)\"\n (dblclick)=\"_rowClick($event, i, index, true)\"\n [ngClass]=\"i._rowClassName\"\n >\n @if (expand) {\n <td\n [nzShowExpand]=\"expand && i.showExpand !== false\"\n [nzExpand]=\"i.expand\"\n (nzExpandChange)=\"_expandChange(i, $event)\"\n (click)=\"_stopPropagation($event)\"\n nzWidth=\"50px\"\n ></td>\n }\n @for (c of _columns; track cIdx; let cIdx = $index) {\n @if (i._values[cIdx].props?.colSpan > 0 && i._values[cIdx].props?.rowSpan > 0) {\n <td\n [nzLeft]=\"!!c._left\"\n [nzRight]=\"!!c._right\"\n [attr.data-col-index]=\"cIdx\"\n [ngClass]=\"c._className\"\n [attr.colspan]=\"i._values[cIdx].props?.colSpan === 1 ? null : i._values[cIdx].props?.colSpan\"\n [attr.rowspan]=\"i._values[cIdx].props?.rowSpan === 1 ? null : i._values[cIdx].props?.rowSpan\"\n >\n @if (responsive) {\n <span class=\"ant-table-rep__title\">\n <ng-template [ngTemplateOutlet]=\"titleTpl\" [ngTemplateOutletContext]=\"{ $implicit: c.title }\" />\n </span>\n }\n <st-td [data]=\"_data\" [i]=\"i\" [index]=\"index\" [c]=\"c\" [cIdx]=\"cIdx\" (n)=\"_handleTd($event)\" />\n </td>\n }\n }\n </tr>\n <tr [nzExpand]=\"i.expand\">\n <ng-template [ngTemplateOutlet]=\"expand\" [ngTemplateOutletContext]=\"{ $implicit: i, index: index }\" />\n </tr>\n </ng-template>\n @if (virtualScroll) {\n <ng-template nz-virtual-scroll let-i let-index=\"index\">\n <ng-template [ngTemplateOutlet]=\"bodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: i, index: index }\" />\n </ng-template>\n } @else {\n @for (i of _data; track trackBy($index, i)) {\n <ng-template [ngTemplateOutlet]=\"bodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: i, index: $index }\" />\n }\n }\n @if (!_loading) {\n <ng-template [ngTemplateOutlet]=\"body!\" [ngTemplateOutletContext]=\"{ $implicit: _statistical }\" />\n }\n </tbody>\n <ng-template #totalTpl let-range=\"range\" let-total>{{ renderTotal(total, range) }}</ng-template>\n</nz-table>\n<nz-dropdown-menu #contextmenuTpl=\"nzDropdownMenu\">\n <ul nz-menu class=\"st__contextmenu\">\n @for (i of contextmenuList; track $index) {\n @if (i.children!.length === 0) {\n <li nz-menu-item (click)=\"i.fn!(i)\" [innerHTML]=\"i.text\"></li>\n } @else {\n <li nz-submenu [nzTitle]=\"i.text\">\n <ul>\n @for (ci of i.children; track $index) {\n <li nz-menu-item (click)=\"ci.fn!(ci)\" [innerHTML]=\"ci.text\"></li>\n }\n </ul>\n </li>\n }\n }\n </ul>\n</nz-dropdown-menu>\n", dependencies: [{ kind: "directive", type: i0.forwardRef(() => i2.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(() => i2.NgTemplateOutlet), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(() => i3.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i3.NgModel), selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i0.forwardRef(() => i4.LetDirective), selector: "[let]", inputs: ["let"] }, { kind: "component", type: i0.forwardRef(() => i5.NzTableComponent), selector: "nz-table", inputs: ["nzTableLayout", "nzShowTotal", "nzItemRender", "nzTitle", "nzFooter", "nzNoResult", "nzPageSizeOptions", "nzVirtualItemSize", "nzVirtualMaxBufferPx", "nzVirtualMinBufferPx", "nzVirtualForTrackBy", "nzLoadingDelay", "nzPageIndex", "nzPageSize", "nzTotal", "nzWidthConfig", "nzData", "nzCustomColumn", "nzPaginationPosition", "nzScroll", "noDataVirtualHeight", "nzPaginationType", "nzFrontPagination", "nzTemplateMode", "nzShowPagination", "nzLoading", "nzOuterBordered", "nzLoadingIndicator", "nzBordered", "nzSize", "nzShowSizeChanger", "nzHideOnSinglePage", "nzShowQuickJumper", "nzSimple"], outputs: ["nzPageSizeChange", "nzPageIndexChange", "nzQueryParams", "nzCurrentPageDataChange", "nzCustomColumnChange"], exportAs: ["nzTable"] }, { kind: "component", type: i0.forwardRef(() => i5.NzThAddOnComponent), selector: "th[nzColumnKey], th[nzSortFn], th[nzSortOrder], th[nzFilters], th[nzShowSort], th[nzShowFilter], th[nzCustomFilter]", inputs: ["nzColumnKey", "nzFilterMultiple", "nzSortOrder", "nzSortPriority", "nzSortDirections", "nzFilters", "nzSortFn", "nzFilterFn", "nzShowSort", "nzShowFilter", "nzCustomFilter"], outputs: ["nzCheckedChange", "nzSortOrderChange", "nzFilterChange"] }, { kind: "directive", type: i0.forwardRef(() => i5.NzTableCellDirective), selector: "th:not(.nz-disable-th):not([mat-cell]), td:not(.nz-disable-td):not([mat-cell])" }, { kind: "directive", type: i0.forwardRef(() => i5.NzThMeasureDirective), selector: "th", inputs: ["nzWidth", "colspan", "colSpan", "rowspan", "rowSpan"] }, { kind: "component", type: i0.forwardRef(() => i5.NzTdAddOnComponent), selector: "td[nzChecked], td[nzDisabled], td[nzIndeterminate], td[nzIndentSize], td[nzExpand], td[nzShowExpand], td[nzShowCheckbox]", inputs: ["nzChecked", "nzDisabled", "nzIndeterminate", "nzLabel", "nzIndentSize", "nzShowExpand", "nzShowCheckbox", "nzExpand", "nzExpandIcon"], outputs: ["nzCheckedChange", "nzExpandChange"] }, { kind: "component", type: i0.forwardRef(() => i5.NzTheadComponent), selector: "thead:not(.ant-table-thead)", outputs: ["nzSortOrderChange"] }, { kind: "component", type: i0.forwardRef(() => i5.NzTbodyComponent), selector: "tbody" }, { kind: "directive", type: i0.forwardRef(() => i5.NzTrDirective), selector: "tr:not([mat-row]):not([mat-header-row]):not([nz-table-measure-row]):not([nzExpand]):not([nz-table-fixed-row])" }, { kind: "directive", type: i0.forwardRef(() => i5.NzTableVirtualScrollDirective), selector: "[nz-virtual-scroll]", exportAs: ["nzVirtualScroll"] }, { kind: "directive", type: i0.forwardRef(() => i5.NzCellFixedDirective), selector: "td[nzRight],th[nzRight],td[nzLeft],th[nzLeft]", inputs: ["nzRight", "nzLeft", "colspan", "colSpan"] }, { kind: "directive", type: i0.forwardRef(() => i5.NzTrExpandDirective), selector: "tr[nzExpand]", inputs: ["nzExpand"] }, { kind: "component", type: i0.forwardRef(() => i5.NzTableFixedRowComponent), selector: "tr[nz-table-fixed-row], tr[nzExpand]" }, { kind: "directive", type: i0.forwardRef(() => i6.NzIconDirective), selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "component", type: i0.forwardRef(() => i7.NzCheckboxComponent), selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }, { kind: "directive", type: i0.forwardRef(() => i8.NzMenuDirective), selector: "[nz-menu]", inputs: ["nzInlineIndent", "nzTheme", "nzMode", "nzInlineCollapsed", "nzSelectable"], outputs: ["nzClick"], exportAs: ["nzMenu"] }, { kind: "component", type: i0.forwardRef(() => i8.NzMenuItemComponent), selector: "[nz-menu-item]", inputs: ["nzPaddingLeft", "nzDisabled", "nzSelected", "nzDanger", "nzMatchRouterExact", "nzMatchRouter"], exportAs: ["nzMenuItem"] }, { kind: "component", type: i0.forwardRef(() => i8.NzSubMenuComponent), selector: "[nz-submenu]", inputs: ["nzMenuClassName", "nzPaddingLeft", "nzTitle", "nzIcon", "nzOpen", "nzDisabled", "nzPlacement"], outputs: ["nzOpenChange"], exportAs: ["nzSubmenu"] }, { kind: "directive", type: i0.forwardRef(() => i9.NzDropDownDirective), selector: "[nz-dropdown]", inputs: ["nzDropdownMenu", "nzTrigger", "nzMatchWidthElement", "nzBackdrop", "nzClickHide", "nzDisabled", "nzVisible", "nzOverlayClassName", "nzOverlayStyle", "nzPlacement"], outputs: ["nzVisibleChange"], exportAs: ["nzDropdown"] }, { kind: "component", type: i0.forwardRef(() => i9.NzDropdownMenuComponent), selector: "nz-dropdown-menu", exportAs: ["nzDropdownMenu"] }, { kind: "directive", type: i0.forwardRef(() => i10.NzTooltipDirective), selector: "[nz-tooltip]", inputs: ["nzTooltipTitle", "nzTooltipTitleContext", "nz-tooltip", "nzTooltipTrigger", "nzTooltipPlacement", "nzTooltipOrigin", "nzTooltipVisible", "nzTooltipMouseEnterDelay", "nzTooltipMouseLeaveDelay", "nzTooltipOverlayClassName", "nzTooltipOverlayStyle", "nzTooltipArrowPointAtCenter", "cdkConnectedOverlayPush", "nzTooltipColor"], outputs: ["nzTooltipVisibleChange"], exportAs: ["nzTooltip"] }, { kind: "directive", type: i0.forwardRef(() => i11.NzResizableDirective), selector: "[nz-resizable]", inputs: ["nzBounds", "nzMaxHeight", "nzMaxWidth", "nzMinHeight", "nzMinWidth", "nzGridColumnCount", "nzMaxColumn", "nzMinColumn", "nzLockAspectRatio", "nzPreview", "nzDisabled"], outputs: ["nzResize", "nzResizeEnd", "nzResizeStart"], exportAs: ["nzResizable"] }, { kind: "component", type: i0.forwardRef(() => i11.NzResizeHandleComponent), selector: "nz-resize-handle, [nz-resize-handle]", inputs: ["nzDirection", "nzCursorType"], outputs: ["nzMouseDown"], exportAs: ["nzResizeHandle"] }, { kind: "component", type: i0.forwardRef(() => i12.STFilterComponent), selector: "st-filter", inputs: ["col", "locale", "f"], outputs: ["n", "handle"] }, { kind: "component", type: i0.forwardRef(() => STTdComponent), selector: "st-td", inputs: ["c", "cIdx", "data", "i", "index"], outputs: ["n"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: STComponent, decorators: [{ type: Component, args: [{ selector: 'st', exportAs: 'st', providers: [STDataSource, STRowSource, STColumnSource, STExport, DatePipe, YNPipe, DecimalPipe], host: { '[class.st]': `true`, '[class.st__p-left]': `page.placement === 'left'`, '[class.st__p-center]': `page.placement === 'center'`, '[class.st__width-strict]': `widthMode.type === 'strict'`, '[class.st__row-class]': `rowClassName`, '[class.ant-table-rep]': `responsive`, '[class.ant-table-rep__hide-header-footer]': `responsiveHideHeaderFooter` }, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-template #titleTpl let-i>\n <span [innerHTML]=\"i._text\"></span>\n @if (i.optional) {\n <small class=\"st__head-optional\" [innerHTML]=\"i.optional\"></small>\n }\n @if (i.optionalHelp) {\n <i class=\"st__head-tip\" nz-tooltip [nzTooltipTitle]=\"i.optionalHelp\" nz-icon nzType=\"question-circle\"></i>\n }\n</ng-template>\n<ng-template #chkAllTpl let-custom>\n <label\n nz-checkbox\n class=\"st__checkall\"\n [nzDisabled]=\"_allCheckedDisabled\"\n [(ngModel)]=\"_allChecked\"\n [nzIndeterminate]=\"_indeterminate\"\n (ngModelChange)=\"checkAll()\"\n [class.ant-table-selection-select-all-custom]=\"custom\"\n ></label>\n</ng-template>\n<nz-table\n #table\n [nzData]=\"_data\"\n [(nzPageIndex)]=\"pi\"\n (nzPageIndexChange)=\"_change('pi')\"\n [(nzPageSize)]=\"ps\"\n (nzPageSizeChange)=\"_change('ps')\"\n [nzTotal]=\"total\"\n [nzShowPagination]=\"_isPagination\"\n [nzFrontPagination]=\"false\"\n [nzBordered]=\"bordered\"\n [nzSize]=\"size\"\n [nzLoading]=\"noColumns || _loading\"\n [nzLoadingDelay]=\"loadingDelay\"\n [nzLoadingIndicator]=\"loadingIndicator\"\n [nzTitle]=\"header!\"\n [nzFooter]=\"footer!\"\n [nzScroll]=\"scroll\"\n [nzVirtualItemSize]=\"virtualItemSize\"\n [nzVirtualMaxBufferPx]=\"virtualMaxBufferPx\"\n [nzVirtualMinBufferPx]=\"virtualMinBufferPx\"\n [nzVirtualForTrackBy]=\"virtualForTrackBy\"\n [nzNoResult]=\"noResult!\"\n [nzPageSizeOptions]=\"page.pageSizes!\"\n [nzShowQuickJumper]=\"page.showQuickJumper\"\n [nzShowSizeChanger]=\"page.showSize\"\n [nzPaginationPosition]=\"page.position!\"\n [nzPaginationType]=\"page.type!\"\n [nzItemRender]=\"page.itemRender!\"\n [nzSimple]=\"page.simple\"\n [nzShowTotal]=\"totalTpl\"\n [nzWidthConfig]=\"_widthConfig\"\n (contextmenu)=\"onContextmenu($event)\"\n [class.st__no-column]=\"noColumns\"\n>\n @if (showHeader) {\n <thead>\n @for (row of _headers; track row) {\n <tr>\n @if ($first && expand) {\n <th nzWidth=\"50px\" [rowSpan]=\"_headers.length\"></th>\n }\n @for (h of row; track h; let index = $index; let last = $last) {\n <th\n *let=\"h.column as _c\"\n [colSpan]=\"h.colSpan\"\n [rowSpan]=\"h.rowSpan\"\n [nzWidth]=\"$any(_c).width\"\n [nzLeft]=\"_c._left!\"\n [nzRight]=\"_c._right!\"\n [ngClass]=\"_c._className\"\n [attr.data-col]=\"_c.indexKey\"\n [attr.data-col-index]=\"index\"\n [nzShowSort]=\"_c._sort.enabled\"\n [nzSortOrder]=\"$any(_c)._sort.default\"\n (nzSortOrderChange)=\"sort(_c, $event)\"\n [nzCustomFilter]=\"!!_c.filter\"\n [class.st__has-filter]=\"_c.filter\"\n nz-resizable\n [nzDisabled]=\"last || $any(_c).resizable.disabled\"\n [nzMaxWidth]=\"$any(_c).resizable.maxWidth\"\n [nzMinWidth]=\"$any(_c).resizable.minWidth\"\n [nzBounds]=\"$any(_c).resizable.bounds\"\n [nzPreview]=\"$any(_c).resizable.preview\"\n (nzResizeEnd)=\"colResize($event, _c)\"\n >\n @if ($any(!last && !$any(_c).resizable.disabled)) {\n <nz-resize-handle nzDirection=\"right\" (click)=\"_stopPropagation($event)\">\n <i></i>\n </nz-resize-handle>\n }\n @if (_c.__renderTitle) {\n <ng-template\n [ngTemplateOutlet]=\"_c.__renderTitle!\"\n [ngTemplateOutletContext]=\"{ $implicit: h.column, index: index }\"\n />\n } @else {\n @switch (_c.type) {\n @case ('checkbox') {\n @if (_c.selections!.length === 0) {\n <ng-template [ngTemplateOutlet]=\"chkAllTpl\" [ngTemplateOutletContext]=\"{ $implicit: false }\" />\n } @else {\n <div class=\"ant-table-selection\">\n <ng-template [ngTemplateOutlet]=\"chkAllTpl\" [ngTemplateOutletContext]=\"{ $implicit: true }\" />\n @if (_c.selections!.length) {\n <div class=\"ant-table-selection-extra\">\n <div\n nz-dropdown\n nzPlacement=\"bottomLeft\"\n [nzDropdownMenu]=\"selectionMenu\"\n class=\"ant-table-selection-down st__checkall-selection\"\n >\n <i nz-icon nzType=\"down\"></i>\n </div>\n </div>\n }\n <nz-dropdown-menu #selectionMenu=\"nzDropdownMenu\">\n <ul nz-menu class=\"ant-table-selection-menu\">\n @for (rw of _c.selections; track $index) {\n <li nz-menu-item (click)=\"_rowSelection(rw)\" [innerHTML]=\"rw.text\"></li>\n }\n </ul>\n </nz-dropdown-menu>\n </div>\n }\n }\n @default {\n <ng-template [ngTemplateOutlet]=\"titleTpl\" [ngTemplateOutletContext]=\"{ $implicit: _c.title }\" />\n }\n }\n }\n @if (_c.filter) {\n <st-filter\n nz-th-extra\n [col]=\"h.column\"\n [f]=\"_c.filter\"\n [locale]=\"locale\"\n (n)=\"handleFilterNotify($event)\"\n (handle)=\"_handleFilter(_c, $event)\"\n />\n }\n </th>\n }\n </tr>\n }\n </thead>\n }\n <tbody class=\"st__body\">\n @if (!_loading) {\n <ng-template [ngTemplateOutlet]=\"