1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { LitTableColumn } from './lit-table-column'; 17import { LitProgressBar } from './../progress-bar/LitProgressBar'; 18import { BaseElement, element } from '../BaseElement'; 19import '../utils/Template'; 20import { TableRowObject } from './TableRowObject'; 21import { 22 addCopyEventListener, 23 addSelectAllBox, 24 createDownUpSvg, 25 exportData, 26 fixed, 27 formatExportData, 28 formatName, 29 iconPadding, 30 iconWidth, 31 litPageTableHtml, 32} from './LitTableHtml'; 33import { LitIcon } from '../icon/LitIcon'; 34 35@element('lit-page-table') 36export class LitPageTable extends BaseElement { 37 meauseRowElement: HTMLDivElement | undefined; 38 currentRecycleList: HTMLDivElement[] = []; 39 currentTreeDivList: HTMLDivElement[] = []; 40 public rememberScrollTop = false; 41 public getItemTextColor?: (data: unknown) => string; 42 public itemTextHandleMap: Map<string, (value: unknown) => string> = new Map<string, (value: unknown) => string>(); 43 public exportLoading: boolean = false; 44 public exportTextHandleMap: Map<string, (value: unknown) => string> = new Map<string, (value: unknown) => string>(); 45 public ds: Array<unknown> = []; 46 public recycleDs: Array<unknown> = []; 47 public tableColumns: NodeListOf<LitTableColumn> | undefined; 48 public tableElement: HTMLDivElement | null | undefined; 49 public columns: Array<Element> | null | undefined; 50 public exportProgress: LitProgressBar | null | undefined; 51 private gridTemplateColumns: Array<string> = []; 52 private st: HTMLSlotElement | null | undefined; 53 private theadElement: HTMLDivElement | null | undefined; 54 private tbodyElement: HTMLDivElement | undefined | null; 55 private treeElement: HTMLDivElement | undefined | null; 56 private previousDiv: HTMLDivElement | undefined | null; 57 private nextDiv: HTMLDivElement | undefined | null; 58 private currentPageDiv: HTMLDivElement | undefined | null; 59 private targetPageInput: HTMLInputElement | undefined | null; 60 private jumpDiv: HTMLDivElement | undefined | null; 61 private colCount: number = 0; 62 private isScrollXOutSide: boolean = false; 63 private currentPage: number = 0; 64 startSkip: number = 0; 65 66 static get observedAttributes(): string[] { 67 return [ 68 'scroll-y', 69 'selectable', 70 'no-head', 71 'grid-line', 72 'defaultOrderColumn', 73 'hideDownload', 74 'loading', 75 'pagination', 76 ]; 77 } 78 79 set loading(value: boolean) { 80 this.exportProgress!.loading = value; 81 } 82 83 get hideDownload(): boolean { 84 return this.hasAttribute('hideDownload'); 85 } 86 87 set hideDownload(value) { 88 if (value) { 89 this.setAttribute('hideDownload', ''); 90 } else { 91 this.removeAttribute('hideDownload'); 92 } 93 } 94 95 get selectable(): boolean { 96 return this.hasAttribute('selectable'); 97 } 98 99 set selectable(value) { 100 if (value) { 101 this.setAttribute('selectable', ''); 102 } else { 103 this.removeAttribute('selectable'); 104 } 105 } 106 107 get scrollY(): string { 108 return this.getAttribute('scroll-y') || 'auto'; 109 } 110 111 set scrollY(value) { 112 this.setAttribute('scroll-y', value); 113 } 114 get recycleDataSource(): unknown[] { 115 return this.ds || []; 116 } 117 118 set recycleDataSource(value) { 119 this.isScrollXOutSide = this.tableElement!.scrollWidth > this.tableElement!.clientWidth; 120 this.ds = value; 121 this.toTop(); 122 this.currentPage = 0; 123 this.pagination = value.length > 0 && Array.isArray(value[0]); 124 if (this.pagination) { 125 this.currentPageDiv!.textContent = `第 ${this.currentPage + 1} 页,共 ${this.ds.length} 页`; 126 this.targetPageInput!.value = ''; 127 } 128 if (this.hasAttribute('tree')) { 129 this.recycleDs = this.meauseTreeRowElement(value); 130 } else { 131 // @ts-ignore 132 this.recycleDs = this.meauseAllRowHeight(this.pagination ? value[0] : value); 133 } 134 } 135 136 set pagination(value: boolean) { 137 if (value) { 138 this.setAttribute('pagination', ''); 139 } else { 140 this.removeAttribute('pagination'); 141 } 142 } 143 144 get pagination(): boolean { 145 return this.hasAttribute('pagination'); 146 } 147 148 initElements(): void { 149 this.tableElement = this.shadowRoot?.querySelector('.table'); 150 this.st = this.shadowRoot?.querySelector('#slot'); 151 this.theadElement = this.shadowRoot?.querySelector('.thead'); 152 this.exportProgress = this.shadowRoot?.querySelector('#export_progress_bar'); 153 this.treeElement = this.shadowRoot?.querySelector('.tree'); 154 this.tbodyElement = this.shadowRoot?.querySelector('.body'); 155 this.tableColumns = this.querySelectorAll<LitTableColumn>('lit-table-column'); 156 this.previousDiv = this.shadowRoot?.querySelector<HTMLDivElement>('#previousPage'); 157 this.nextDiv = this.shadowRoot?.querySelector<HTMLDivElement>('#nextPage'); 158 this.currentPageDiv = this.shadowRoot?.querySelector<HTMLDivElement>('#currentPage'); 159 this.targetPageInput = this.shadowRoot?.querySelector<HTMLInputElement>('#targetPage'); 160 this.jumpDiv = this.shadowRoot?.querySelector<HTMLDivElement>('#jumpPage'); 161 this.initPageEventListener(); 162 } 163 164 initPageEventListener(): void { 165 this.previousDiv!.onclick = (): void => { 166 if (this.currentPage > 0) { 167 this.currentPage = Math.max(this.currentPage - 1, 0); 168 this.showCurrentPageData(); 169 } 170 }; 171 this.nextDiv!.onclick = (): void => { 172 if (this.currentPage < this.ds.length - 1) { 173 this.currentPage = Math.min(this.currentPage + 1, this.ds.length - 1); 174 this.showCurrentPageData(); 175 } 176 }; 177 this.jumpDiv!.onclick = (): void => { 178 let value = this.targetPageInput!.value; 179 let reg = /^[0-9]*$/; 180 if (value.length > 0 && reg.test(value)) { 181 let target = parseInt(value); 182 if (target < 1) { 183 target = 1; 184 } 185 if (target > this.ds.length) { 186 target = this.ds.length; 187 } 188 this.targetPageInput!.value = `${target}`; 189 if (this.currentPage !== target - 1) { 190 this.currentPage = target - 1; 191 this.showCurrentPageData(); 192 } 193 } else { 194 this.targetPageInput!.value = ''; 195 } 196 }; 197 } 198 199 toTop(): void { 200 if (this.rememberScrollTop) { 201 this.tableElement!.scrollTop = 0; 202 this.tableElement!.scrollLeft = 0; 203 } else { 204 this.tableElement!.scrollTop = 0; 205 } 206 } 207 208 showCurrentPageData(): void { 209 this.toTop(); 210 this.currentPageDiv!.textContent = `第 ${(this.currentPage || 0) + 1} 页,共 ${this.ds.length} 页`; 211 if (this.hasAttribute('tree')) { 212 // @ts-ignore 213 this.recycleDs = this.meauseTreeRowElement(this.ds[this.currentPage]); 214 } else { 215 // @ts-ignore 216 this.recycleDs = this.meauseAllRowHeight(this.ds[this.currentPage]); 217 } 218 } 219 220 initHtml(): string { 221 return litPageTableHtml; 222 } 223 224 dataExportInit(): void { 225 let exportDiv = this.shadowRoot!.querySelector<HTMLDivElement>('.export'); 226 exportDiv && 227 (exportDiv.onclick = (): void => { 228 this.exportData(); 229 }); 230 } 231 232 exportData(): void { 233 exportData(this); 234 } 235 236 formatExportData(dataSource: unknown[]): unknown[] { 237 return formatExportData(dataSource, this); 238 } 239 240 //当 custom element首次被插入文档DOM时,被调用。 241 connectedCallback(): void { 242 this.dataExportInit(); 243 addCopyEventListener(this); 244 this.colCount = this.tableColumns!.length; 245 this.st?.addEventListener('slotchange', () => { 246 this.theadElement!.innerHTML = ''; 247 setTimeout(() => { 248 this.columns = this.st!.assignedElements(); 249 let rowElement = document.createElement('div'); 250 rowElement.classList.add('th'); 251 this.gridTemplateColumns = []; 252 let pageArea: Array<unknown> = []; 253 addSelectAllBox(rowElement, this); 254 this.resolvingArea(this.columns, 0, 0, pageArea, rowElement); 255 pageArea.forEach((rows, j, array) => { 256 for (let i = 0; i < this.colCount; i++) { 257 // @ts-ignore 258 if (!rows[i]) { 259 // @ts-ignore 260 rows[i] = array[j - 1][i]; 261 } 262 } 263 }); 264 if (this.selectable) { 265 // @ts-ignore 266 let s = pageArea.map((a) => '"_checkbox_ ' + a.map((aa: unknown) => aa.t).join(' ') + '"').join(' '); 267 rowElement.style.gridTemplateColumns = '60px ' + this.gridTemplateColumns.join(' '); 268 rowElement.style.gridTemplateRows = `repeat(${pageArea.length},1fr)`; 269 rowElement.style.gridTemplateAreas = s; 270 } else { 271 // @ts-ignore 272 let s = pageArea.map((a) => '"' + a.map((aa: unknown) => aa.t).join(' ') + '"').join(' '); 273 rowElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); 274 rowElement.style.gridTemplateRows = `repeat(${pageArea.length},1fr)`; 275 rowElement.style.gridTemplateAreas = s; 276 } 277 this.theadElement!.innerHTML = ''; 278 this.theadElement!.append(rowElement); 279 this.treeElement!.style.top = this.theadElement?.clientHeight + 'px'; 280 }); 281 }); 282 this.shadowRoot!.addEventListener('load', function (event) {}); 283 this.tableElement!.addEventListener('mouseout', (ev) => this.mouseOut()); 284 } 285 286 resolvingArea(columns: unknown, x: unknown, y: unknown, area: Array<unknown>, rowElement: HTMLDivElement): void { 287 // @ts-ignore 288 columns.forEach((a: unknown, i: unknown) => { 289 // @ts-ignore 290 if (!area[y]) { 291 // @ts-ignore 292 area[y] = []; 293 } // @ts-ignore 294 let key = a.getAttribute('key') || a.getAttribute('title'); // @ts-ignore 295 if (a.tagName === 'LIT-TABLE-GROUP') { 296 // @ts-ignore 297 let childList = [...a.children].filter((a) => a.tagName !== 'TEMPLATE'); // @ts-ignore 298 let len = a.querySelectorAll('lit-table-column').length; 299 if (childList.length > 0) { 300 // @ts-ignore 301 this.resolvingArea(childList, x, y + 1, area, rowElement); 302 } 303 for (let j = 0; j < len; j++) { 304 // @ts-ignore 305 area[y][x] = { x, y, t: key }; // @ts-ignore 306 x++; 307 } 308 let head = document.createElement('div'); 309 head.classList.add('td'); // @ts-ignore 310 head.style.justifyContent = a.getAttribute('align'); 311 head.style.borderBottom = '1px solid #f0f0f0'; 312 head.style.gridArea = key; // @ts-ignore 313 head.innerText = a.title; // @ts-ignore 314 if (a.hasAttribute('fixed')) { 315 // @ts-ignore 316 fixed(head, a.getAttribute('fixed'), '#42b983'); 317 } 318 rowElement.append(head); // @ts-ignore 319 } else if (a.tagName === 'LIT-TABLE-COLUMN') { 320 // @ts-ignore 321 area[y][x] = { x, y, t: key }; // @ts-ignore 322 x++; 323 let h: unknown = document.createElement('div'); // @ts-ignore 324 h.classList.add('td'); // @ts-ignore 325 if (i > 0) { 326 let resizeDiv: HTMLDivElement = document.createElement('div'); 327 resizeDiv.classList.add('resize'); // @ts-ignore 328 h.appendChild(resizeDiv); // @ts-ignore 329 this.resizeEventHandler(rowElement, resizeDiv, i); 330 } // @ts-ignore 331 this.resolvingAreaColumnOrder(a, i, key, h); // @ts-ignore 332 h.style.justifyContent = a.getAttribute('align'); // @ts-ignore 333 this.gridTemplateColumns.push(a.getAttribute('width') || '1fr'); // @ts-ignore 334 h.style.gridArea = key; 335 let titleLabel = document.createElement('label'); // @ts-ignore 336 titleLabel.textContent = a.title; // @ts-ignore 337 h.appendChild(titleLabel); // @ts-ignore 338 if (a.hasAttribute('fixed')) { 339 // @ts-ignore 340 fixed(h, a.getAttribute('fixed'), '#42b983'); 341 } // @ts-ignore 342 rowElement.append(h); 343 } 344 }); 345 } 346 347 resolvingAreaColumnOrder(column: unknown, index: number, key: string, head: unknown): void { 348 // @ts-ignore 349 if (column.hasAttribute('order')) { 350 // @ts-ignore 351 (head as unknown).sortType = 0; // @ts-ignore 352 head.classList.add('td-order'); // @ts-ignore 353 head.style.position = 'relative'; 354 let { upSvg, downSvg } = createDownUpSvg(index, head); // @ts-ignore 355 head.onclick = (): void => { 356 if (this.isResize || this.resizeColumnIndex !== -1) { 357 return; 358 } 359 this?.shadowRoot?.querySelectorAll('.td-order svg').forEach((it: unknown) => { 360 // @ts-ignore 361 it.setAttribute('fill', 'let(--dark-color1,#212121)'); // @ts-ignore 362 it.sortType = 0; // @ts-ignore 363 it.style.display = 'none'; 364 }); // @ts-ignore 365 if (head.sortType === undefined || head.sortType === null) { 366 // @ts-ignore 367 head.sortType = 0; // @ts-ignore 368 } else if (head.sortType === 2) { 369 // @ts-ignore 370 head.sortType = 0; 371 } else { 372 // @ts-ignore 373 head.sortType += 1; 374 } 375 upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); 376 downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); // @ts-ignore 377 upSvg.style.display = head.sortType === 1 ? 'block' : 'none'; // @ts-ignore 378 downSvg.style.display = head.sortType === 2 ? 'block' : 'none'; // @ts-ignore 379 switch (head.sortType) { 380 case 1: 381 this.theadElement!.setAttribute('sort', ''); 382 break; 383 case 2: 384 break; 385 default: 386 this.theadElement!.removeAttribute('sort'); 387 break; 388 } 389 this.dispatchEvent( 390 new CustomEvent('column-click', { 391 detail: { 392 // @ts-ignore 393 sort: head.sortType, 394 key: key, 395 }, 396 composed: true, 397 }) 398 ); 399 }; 400 } 401 } 402 403 private isResize: boolean = false; 404 private resizeColumnIndex: number = -1; 405 private resizeDownX: number = 0; 406 private columnMinWidth: number = 50; 407 private beforeResizeWidth: number = 0; 408 409 resizeMouseMoveEventHandler(header: HTMLDivElement): void { 410 header.addEventListener('mousemove', (event) => { 411 if (this.isResize) { 412 header.style.cursor = 'col-resize'; 413 let width = event.clientX - this.resizeDownX; 414 let prePageWidth = Math.max(this.beforeResizeWidth + width, this.columnMinWidth); 415 for (let i = 0; i < header.childNodes.length; i++) { 416 let node = header.childNodes.item(i) as HTMLDivElement; 417 this.gridTemplateColumns[i] = `${node.clientWidth}px`; 418 } 419 this.gridTemplateColumns[this.resizeColumnIndex - 1] = `${prePageWidth}px`; 420 let lastNode = header.childNodes.item(header.childNodes.length - 1) as HTMLDivElement; 421 let totalWidth = 0; 422 this.gridTemplateColumns.forEach((it) => { 423 totalWidth += parseInt(it); 424 }); 425 totalWidth = Math.max(totalWidth, this.shadowRoot!.querySelector<HTMLDivElement>('.table')!.scrollWidth); 426 this.gridTemplateColumns[this.gridTemplateColumns.length - 1] = `${totalWidth - lastNode.offsetLeft - 1}px`; 427 header.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); 428 let preNode = header.childNodes.item(this.resizeColumnIndex - 1) as HTMLDivElement; 429 preNode.style.width = `${prePageWidth}px`; 430 this.shadowRoot!.querySelectorAll<HTMLDivElement>('.tr').forEach((tr) => { 431 tr.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); 432 }); 433 event.preventDefault(); 434 event.stopPropagation(); 435 } else { 436 header.style.cursor = 'pointer'; 437 } 438 }); 439 } 440 441 resizeEventHandler(header: HTMLDivElement, element: HTMLDivElement, index: number): void { 442 this.resizeMouseMoveEventHandler(header); 443 header.addEventListener('mouseup', (event) => { 444 this.resizeDownX = 0; 445 this.isResize = false; 446 header.style.cursor = 'pointer'; 447 setTimeout(() => { 448 this.resizeColumnIndex = -1; 449 }, 100); 450 event.stopPropagation(); 451 event.preventDefault(); 452 }); 453 header.addEventListener('mouseleave', (event) => { 454 event.stopPropagation(); 455 event.preventDefault(); 456 this.isResize = false; 457 this.resizeDownX = 0; 458 this.resizeColumnIndex = -1; 459 header.style.cursor = 'pointer'; 460 }); 461 element.addEventListener('mousedown', (event) => { 462 if (event.button === 0) { 463 this.resizeColumnIndex = index; 464 this.isResize = true; 465 this.resizeDownX = event.clientX; 466 let pre = header.childNodes.item(this.resizeColumnIndex - 1) as HTMLDivElement; 467 this.beforeResizeWidth = pre.clientWidth; 468 event.stopPropagation(); 469 } 470 }); 471 element.addEventListener('click', (event) => { 472 event.stopPropagation(); 473 }); 474 } 475 476 // Is called when the custom element is removed from the document DOM. 477 disconnectedCallback(): void {} 478 479 // It is called when the custom element is moved to a new document. 480 adoptedCallback(): void {} 481 482 // It is called when a custom element adds, deletes, or modifies its own properties. 483 attributeChangedCallback(name: string, oldValue: string, newValue: string): void {} 484 485 meauseElementHeight(rowData: unknown): number { 486 return 27; 487 } 488 489 meauseTreeElementHeight(rowData: unknown, depth: number): number { 490 return 27; 491 } 492 493 meauseAllRowHeight(list: unknown[]): TableRowObject[] { 494 this.tbodyElement!.innerHTML = ''; 495 this.meauseRowElement = undefined; 496 this.startSkip = 0; 497 let head = this.shadowRoot!.querySelector('.th'); 498 this.tbodyElement && (this.tbodyElement.style.width = head?.clientWidth + 'px'); 499 this.currentRecycleList = []; 500 let headHeight = 0; 501 let totalHeight = headHeight; 502 let visibleObjects: TableRowObject[] = []; 503 let itemHandler = (rowData: unknown, index: number): void => { 504 let height = this.meauseElementHeight(rowData); 505 let tableRowObject = new TableRowObject(); 506 tableRowObject.height = height; 507 tableRowObject.top = totalHeight; 508 tableRowObject.data = rowData; 509 tableRowObject.rowIndex = index; 510 if ( 511 Math.max(totalHeight, this.tableElement!.scrollTop + headHeight) <= 512 Math.min(totalHeight + height, this.tableElement!.scrollTop + this.tableElement!.clientHeight + headHeight) 513 ) { 514 let newTableElement = this.createNewTableElement(tableRowObject); 515 newTableElement.style.transform = `translateY(${totalHeight}px)`; 516 this.tbodyElement?.append(newTableElement); 517 this.currentRecycleList.push(newTableElement); 518 } 519 totalHeight += height; 520 visibleObjects.push(tableRowObject); 521 }; 522 let realIndex = 0; 523 list.forEach((item, index) => { 524 if (Array.isArray(item)) { 525 item.forEach((rowData, childIndex) => { 526 itemHandler(rowData, realIndex); 527 realIndex++; 528 }); 529 } else { 530 itemHandler(item, index); 531 } 532 }); 533 this.tbodyElement && (this.tbodyElement.style.height = totalHeight + (this.isScrollXOutSide ? 0 : 0) + 'px'); 534 this.addOnScrollListener(visibleObjects); 535 return visibleObjects; 536 } 537 538 addOnScrollListener(visibleObjList: TableRowObject[]): void { 539 this.tableElement && 540 (this.tableElement.onscroll = (event): void => { 541 let tblScrollTop = this.tableElement!.scrollTop; 542 let skip = 0; 543 for (let i = 0; i < visibleObjList.length; i++) { 544 if ( 545 visibleObjList[i].top <= tblScrollTop && 546 visibleObjList[i].top + visibleObjList[i].height >= tblScrollTop 547 ) { 548 skip = i; 549 break; 550 } 551 } 552 let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); 553 if (reduce === 0) { 554 return; 555 } 556 while ( 557 reduce <= this.tableElement!.clientHeight && 558 this.currentRecycleList.length + skip < visibleObjList.length 559 ) { 560 let newTableElement = this.createNewTableElement(visibleObjList[skip]); 561 this.tbodyElement?.append(newTableElement); 562 this.currentRecycleList.push(newTableElement); 563 reduce += newTableElement.clientHeight; 564 } 565 this.startSkip = skip; 566 for (let i = 0; i < this.currentRecycleList.length; i++) { 567 this.freshCurrentLine(this.currentRecycleList[i], visibleObjList[i + skip]); 568 } 569 }); 570 } 571 572 measureReset(): void { 573 this.meauseRowElement = undefined; 574 this.tbodyElement!.innerHTML = ''; 575 this.treeElement!.innerHTML = ''; 576 this.currentRecycleList = []; 577 this.currentTreeDivList = []; 578 } 579 580 meauseTreeRowElement(list: unknown[]): TableRowObject[] { 581 this.measureReset(); 582 let headHeight = this.theadElement?.clientHeight || 0; 583 let totalHeight = 0; 584 let visibleObjects: TableRowObject[] = []; 585 let resetAllHeight = (list: unknown[], depth: number, parentNode?: TableRowObject): void => { 586 list.forEach((item) => { 587 let tableRowObject = new TableRowObject(); 588 tableRowObject.depth = depth; 589 tableRowObject.data = item; 590 tableRowObject.top = totalHeight; 591 tableRowObject.height = this.meauseTreeElementHeight(tableRowObject, depth); 592 if (parentNode !== undefined) { 593 parentNode.children.push(tableRowObject); 594 } 595 let maxHeight = Math.max(totalHeight, this.tableElement!.scrollTop); 596 let minHeight = Math.min( 597 totalHeight + tableRowObject.height, 598 this.tableElement!.scrollTop + this.tableElement!.clientHeight - headHeight 599 ); 600 if (maxHeight <= minHeight) { 601 let newTableElement = this.createNewTreeTableElement(tableRowObject); // @ts-ignore 602 newTableElement.style.transform = `translateY(${totalHeight}px)`; // @ts-ignore 603 this.tbodyElement?.append(newTableElement); 604 if (this.treeElement?.lastChild) { 605 (this.treeElement?.lastChild as HTMLElement).style.height = tableRowObject.height + 'px'; 606 } // @ts-ignore 607 this.currentRecycleList.push(newTableElement); 608 } 609 totalHeight += tableRowObject.height; 610 visibleObjects.push(tableRowObject); // @ts-ignore 611 if (item.hasNext) { 612 // @ts-ignore 613 if (item.parents !== undefined && item.parents.length > 0 && item.status) { 614 // @ts-ignore 615 resetAllHeight(item.parents, depth + 1, tableRowObject); // @ts-ignore 616 } else if (item.children !== undefined && item.children.length > 0 && item.status) { 617 // @ts-ignore 618 resetAllHeight(item.children, depth + 1, tableRowObject); 619 } 620 } else { 621 // @ts-ignore 622 if (item.children !== undefined && item.children.length > 0) { 623 // @ts-ignore 624 resetAllHeight(item.children, depth + 1, tableRowObject); 625 } 626 } 627 }); 628 }; 629 resetAllHeight(list, 0); 630 this.tbodyElement && (this.tbodyElement.style.height = totalHeight + 'px'); 631 this.treeElement!.style.height = this.tableElement!.clientHeight - this.theadElement!.clientHeight + 'px'; 632 this.addTreeRowScrollListener(); 633 return visibleObjects; 634 } 635 636 addTreeRowScrollListener(): void { 637 this.tableElement && 638 (this.tableElement.onscroll = (event): void => { 639 let visibleObjs = this.recycleDs.filter((item) => { 640 // @ts-ignore 641 return !item.rowHidden; 642 }); 643 let top = this.tableElement!.scrollTop; 644 this.treeElement!.style.transform = `translateY(${top}px)`; 645 let skip = 0; 646 for (let index = 0; index < visibleObjs.length; index++) { 647 // @ts-ignore 648 if (visibleObjs[index].top <= top && visibleObjs[index].top + visibleObjs[index].height >= top) { 649 skip = index; 650 break; 651 } 652 } 653 let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); 654 if (reduce === 0) { 655 return; 656 } 657 while (reduce <= this.tableElement!.clientHeight) { 658 // @ts-ignore 659 let newTableElement = this.createNewTreeTableElement(visibleObjs[skip]); // @ts-ignore 660 this.tbodyElement?.append(newTableElement); 661 if (this.treeElement?.lastChild) { 662 // @ts-ignore 663 (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjs[skip].height + 'px'; 664 } // @ts-ignore 665 this.currentRecycleList.push(newTableElement); // @ts-ignore 666 reduce += newTableElement.clientHeight; 667 } 668 for (let i = 0; i < this.currentRecycleList.length; i++) { 669 this.freshCurrentLine( 670 this.currentRecycleList[i], // @ts-ignore 671 visibleObjs[i + skip], 672 this.treeElement?.children[i] as HTMLElement 673 ); 674 } 675 }); 676 } 677 678 createNewTreeTableElement(rowData: TableRowObject): unknown { 679 let newTableElement = document.createElement('div'); 680 newTableElement.classList.add('tr'); 681 let treeTop = 0; 682 if (this.treeElement!.children?.length > 0) { 683 let transX = Number((this.treeElement?.lastChild as HTMLElement).style.transform.replace(/[^0-9]/gi, '')); 684 treeTop += transX + rowData.height; 685 } 686 this?.columns?.forEach((column: unknown, index) => { 687 // @ts-ignore 688 let dataIndex = column.getAttribute('data-index') || '1'; 689 let td: unknown; 690 if (index === 0) { 691 td = this.firstElementTdHandler(newTableElement, dataIndex, rowData, column); 692 } else { 693 td = this.otherElementHandler(dataIndex, rowData, column); // @ts-ignore 694 newTableElement.append(td); 695 } 696 }); 697 let lastChild = this.treeElement?.lastChild as HTMLElement; 698 if (lastChild) { 699 lastChild.style.transform = `translateY(${treeTop}px)`; 700 } // @ts-ignore 701 (newTableElement as unknown).data = rowData.data; 702 newTableElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); 703 newTableElement.style.position = 'absolute'; 704 newTableElement.style.top = '0px'; 705 newTableElement.style.left = '0px'; 706 newTableElement.style.cursor = 'pointer'; //@ts-ignore 707 this.setHighLight(rowData.data.isSearch, newTableElement); 708 this.addRowElementEvent(newTableElement, rowData); 709 return newTableElement; 710 } 711 712 addRowElementEvent(newTableElement: HTMLDivElement, rowData: unknown): void { 713 newTableElement.onmouseenter = (): void => { 714 // @ts-ignore 715 if ((newTableElement as unknown).data.isSelected) { 716 return; 717 } 718 let indexOf = this.currentRecycleList.indexOf(newTableElement); 719 this.currentTreeDivList.forEach((row) => { 720 row.classList.remove('mouse-in'); 721 }); 722 if (indexOf >= 0 && indexOf < this.treeElement!.children.length) { 723 this.setMouseIn(true, [this.treeElement?.children[indexOf] as HTMLElement]); 724 } 725 }; 726 newTableElement.onmouseleave = (): void => { 727 // @ts-ignore 728 if ((newTableElement as unknown).data.isSelected) { 729 return; 730 } 731 let indexOf = this.currentRecycleList.indexOf(newTableElement); 732 if (indexOf >= 0 && indexOf < this.treeElement!.children.length) { 733 this.setMouseIn(false, [this.treeElement?.children[indexOf] as HTMLElement]); 734 } 735 }; 736 newTableElement.onclick = (e): void => { 737 let indexOf = this.currentRecycleList.indexOf(newTableElement); 738 this.dispatchRowClickEvent(rowData, [this.treeElement?.children[indexOf] as HTMLElement, newTableElement]); 739 }; 740 } 741 742 firstElementTdHandler( 743 newTableElement: HTMLDivElement, 744 dataIndex: string, 745 rowData: unknown, 746 column: unknown 747 ): HTMLDivElement { 748 let td: unknown; // @ts-ignore 749 let text = formatName(dataIndex, rowData.data[dataIndex], this); // @ts-ignore 750 if (column.template) { 751 // @ts-ignore 752 td = column.template.render(rowData.data).content.cloneNode(true); // @ts-ignore 753 td.template = column.template; // @ts-ignore 754 td.title = text; 755 } else { 756 td = document.createElement('div'); // @ts-ignore 757 td.innerHTML = text; // @ts-ignore 758 td.dataIndex = dataIndex; // @ts-ignore 759 td.title = text; 760 } // @ts-ignore 761 if (rowData.data.children && rowData.data.children.length > 0 && !rowData.data.hasNext) { 762 let btn = this.createExpandBtn(rowData); // @ts-ignore 763 td.insertBefore(btn, td.firstChild); 764 } // @ts-ignore 765 if (rowData.data.hasNext) { 766 // @ts-ignore 767 td.title = rowData.data.objectName; 768 let btn = this.createBtn(rowData); // @ts-ignore 769 td.insertBefore(btn, td.firstChild); 770 } // @ts-ignore 771 td.style.paddingLeft = rowData.depth * iconWidth + 'px'; // @ts-ignore 772 if (!rowData.data.children || rowData.data.children.length === 0) { 773 // @ts-ignore 774 td.style.paddingLeft = iconWidth * rowData.depth + iconWidth + iconPadding * 2 + 'px'; 775 } // @ts-ignore 776 (td as unknown).data = rowData.data; // @ts-ignore 777 td.classList.add('tree-first-body'); // @ts-ignore 778 td.style.position = 'absolute'; // @ts-ignore 779 td.style.top = '0px'; // @ts-ignore 780 td.style.left = '0px'; // @ts-ignore 781 this.addFirstElementEvent(td, newTableElement, rowData); // @ts-ignore 782 this.setHighLight(rowData.data.isSearch, td); // @ts-ignore 783 this.treeElement!.style.width = column.getAttribute('width'); // @ts-ignore 784 this.treeElement?.append(td); // @ts-ignore 785 this.currentTreeDivList.push(td); // @ts-ignore 786 return td; 787 } 788 789 addFirstElementEvent(td: HTMLDivElement, tr: HTMLDivElement, rowData: unknown): void { 790 td.onmouseenter = (): void => { 791 let indexOf = this.currentTreeDivList.indexOf(td); 792 this.currentRecycleList.forEach((row) => { 793 row.classList.remove('mouse-in'); 794 }); 795 if (indexOf >= 0 && indexOf < this.currentRecycleList.length && td.innerHTML !== '') { 796 this.setMouseIn(true, [td]); 797 } 798 }; 799 td.onmouseleave = (): void => { 800 let indexOf = this.currentTreeDivList.indexOf(td); 801 if (indexOf >= 0 && indexOf < this.currentRecycleList.length) { 802 this.setMouseIn(false, [td]); 803 } 804 }; 805 td.onclick = (): void => { 806 let indexOf = this.currentTreeDivList.indexOf(td); 807 this.dispatchRowClickEvent(rowData, [td, tr]); 808 }; 809 } 810 811 otherElementHandler(dataIndex: string, rowData: unknown, column: unknown): HTMLDivElement { 812 // @ts-ignore 813 let text = formatName(dataIndex, rowData.data[dataIndex], this); 814 let td: unknown = document.createElement('div'); 815 td = document.createElement('div'); // @ts-ignore 816 td.classList.add('td'); // @ts-ignore 817 td.style.overflow = 'hidden'; // @ts-ignore 818 td.style.textOverflow = 'ellipsis'; // @ts-ignore 819 td.style.whiteSpace = 'nowrap'; // @ts-ignore 820 td.title = text; // @ts-ignore 821 td.dataIndex = dataIndex; // @ts-ignore 822 td.style.justifyContent = column.getAttribute('align') || 'flex-start'; // @ts-ignore 823 if (column.template) { 824 // @ts-ignore 825 td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); // @ts-ignore 826 td.template = column.template; 827 } else { 828 // @ts-ignore 829 td.innerHTML = text; 830 } // @ts-ignore 831 return td; 832 } 833 834 createBtn(row: unknown): unknown { 835 let btn: unknown = document.createElement('lit-icon'); // @ts-ignore 836 btn.classList.add('tree-icon'); // @ts-ignore 837 if (row.data.expanded) { 838 // @ts-ignore 839 btn.name = 'plus-square'; 840 } else { 841 // @ts-ignore 842 btn.name = 'minus-square'; 843 } // @ts-ignore 844 btn.addEventListener('click', (e: unknown) => { 845 // @ts-ignore 846 row.data.status = false; 847 const resetNodeHidden = (hidden: boolean, rowData: unknown): void => { 848 if (hidden) { 849 // @ts-ignore 850 rowData.children.forEach((child: unknown) => { 851 // @ts-ignore 852 child.rowHidden = false; 853 }); 854 } else { 855 // @ts-ignore 856 rowData.children.forEach((child: unknown) => { 857 // @ts-ignore 858 child.rowHidden = true; 859 resetNodeHidden(hidden, child); 860 }); 861 } 862 }; 863 // @ts-ignore 864 if (row.data.expanded) { 865 // @ts-ignore 866 row.data.status = true; 867 this.dispatchRowClickEventIcon(row, [btn]); // @ts-ignore 868 row.data.expanded = false; 869 resetNodeHidden(true, row); 870 } else { 871 // @ts-ignore 872 row.data.expanded = true; // @ts-ignore 873 row.data.status = false; 874 resetNodeHidden(false, row); 875 } 876 this.reMeauseHeight(); // @ts-ignore 877 e.stopPropagation(); 878 }); 879 return btn; 880 } 881 882 createExpandBtn(row: unknown): LitIcon { 883 let btn: unknown = document.createElement('lit-icon'); // @ts-ignore 884 btn.classList.add('tree-icon'); 885 // @ts-ignore 886 if (row.expanded) { 887 // @ts-ignore 888 btn.name = 'minus-square'; 889 } else { 890 // @ts-ignore 891 btn.name = 'plus-square'; 892 } // @ts-ignore 893 btn.onclick = (e: Event): void => { 894 const resetNodeHidden = (hidden: boolean, rowData: unknown): void => { 895 // @ts-ignore 896 if (rowData.children.length > 0) { 897 if (hidden) { 898 // @ts-ignore 899 rowData.children.forEach((child: unknown) => { 900 // @ts-ignore 901 child.rowHidden = true; 902 resetNodeHidden(hidden, child); 903 }); 904 } else { 905 // @ts-ignore 906 rowData.children.forEach((child: unknown) => { 907 // @ts-ignore 908 child.rowHidden = !rowData.expanded; // @ts-ignore 909 if (rowData.expanded) { 910 resetNodeHidden(hidden, child); 911 } 912 }); 913 } 914 } 915 }; 916 // @ts-ignore 917 if (row.expanded) { 918 // @ts-ignore 919 row.expanded = false; 920 resetNodeHidden(true, row); 921 } else { 922 // @ts-ignore 923 row.expanded = true; 924 resetNodeHidden(false, row); 925 } 926 this.reMeauseHeight(); 927 e.stopPropagation(); 928 }; // @ts-ignore 929 return btn; 930 } 931 932 getVisibleObjs(): { visibleObjs: unknown[]; skip: number; reduce: number } { 933 let totalH = 0; 934 this.recycleDs.forEach((it) => { 935 // @ts-ignore 936 if (!it.rowHidden) { 937 // @ts-ignore 938 it.top = totalH; // @ts-ignore 939 totalH += it.height; 940 } 941 }); 942 this.tbodyElement && (this.tbodyElement.style.height = totalH + (this.isScrollXOutSide ? 0 : 0) + 'px'); 943 this.treeElement!.style.height = this.tableElement!.clientHeight - this.theadElement!.clientHeight + 'px'; 944 let visibleObjs = this.recycleDs.filter((item) => { 945 // @ts-ignore 946 return !item.rowHidden; 947 }); 948 let top = this.tableElement!.scrollTop; 949 let skip = 0; 950 for (let i = 0; i < visibleObjs.length; i++) { 951 // @ts-ignore 952 if (visibleObjs[i].top <= top && visibleObjs[i].top + visibleObjs[i].height >= top) { 953 skip = i; 954 break; 955 } 956 } 957 let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); 958 return { visibleObjs, skip, reduce }; 959 } 960 961 reMeauseHeight(): void { 962 if (this.currentRecycleList.length === 0) { 963 return; 964 } 965 let { visibleObjs, skip, reduce } = this.getVisibleObjs(); 966 if (reduce === 0) { 967 return; 968 } 969 while (reduce <= this.tableElement!.clientHeight + 1) { 970 let rowElement; 971 if (this.hasAttribute('tree')) { 972 // @ts-ignore 973 rowElement = this.createNewTreeTableElement(visibleObjs[skip]); 974 } else { 975 rowElement = this.createNewTableElement(visibleObjs[skip]); 976 } // @ts-ignore 977 this.tbodyElement?.append(rowElement); 978 if (this.hasAttribute('tree')) { 979 if (this.treeElement?.lastChild) { 980 // @ts-ignore 981 (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjs[skip].height + 'px'; 982 } 983 } // @ts-ignore 984 this.currentRecycleList.push(rowElement); // @ts-ignore 985 reduce += rowElement.clientHeight; 986 } 987 for (let i = 0; i < this.currentRecycleList.length; i++) { 988 if (this.hasAttribute('tree')) { 989 this.freshCurrentLine( 990 this.currentRecycleList[i], // @ts-ignore 991 visibleObjs[i + skip], 992 this.treeElement?.children[i] as HTMLElement 993 ); 994 } else { 995 // @ts-ignore 996 this.freshCurrentLine(this.currentRecycleList[i], visibleObjs[i + skip]); 997 } 998 } 999 } 1000 1001 createNewTableElement(rowData: unknown): HTMLDivElement { 1002 let rowElement = document.createElement('div'); 1003 rowElement.classList.add('tr'); 1004 this?.columns?.forEach((column: unknown) => { 1005 // @ts-ignore 1006 let dataIndex = column.getAttribute('data-index') || '1'; 1007 let td: unknown; 1008 td = document.createElement('div'); // @ts-ignore 1009 td.classList.add('td'); // @ts-ignore 1010 td.style.overflow = 'hidden'; // @ts-ignore 1011 td.style.textOverflow = 'ellipsis'; // @ts-ignore 1012 td.style.whiteSpace = 'nowrap'; // @ts-ignore 1013 td.dataIndex = dataIndex; // @ts-ignore 1014 td.style.justifyContent = column.getAttribute('align') || 'flex-start'; // @ts-ignore 1015 let text = formatName(dataIndex, rowData.data[dataIndex], this); // @ts-ignore 1016 td.title = text; // @ts-ignore 1017 if (column.template) { 1018 // @ts-ignore 1019 td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); // @ts-ignore 1020 td.template = column.template; 1021 } else { 1022 // @ts-ignore 1023 td.innerHTML = text; 1024 } // @ts-ignore 1025 rowElement.append(td); 1026 }); 1027 rowElement.onclick = (): void => { 1028 this.dispatchRowClickEvent(rowData, [rowElement]); 1029 }; 1030 rowElement.onmouseover = (): void => { 1031 this.dispatchRowHoverEvent(rowData, [rowElement]); 1032 }; // @ts-ignore 1033 if (rowData.data.isSelected !== undefined) { 1034 // @ts-ignore 1035 this.setSelectedRow(rowData.data.isSelected, [rowElement]); 1036 } // @ts-ignore 1037 (rowElement as unknown).data = rowData.data; 1038 rowElement.style.cursor = 'pointer'; 1039 rowElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); 1040 rowElement.style.position = 'absolute'; 1041 rowElement.style.top = '0px'; 1042 rowElement.style.left = '0px'; // @ts-ignore 1043 rowElement.style.height = `${rowData.height}px`; 1044 if (this.getItemTextColor) { 1045 // @ts-ignore 1046 rowElement.style.color = this.getItemTextColor(rowData.data); 1047 } 1048 return rowElement; 1049 } 1050 1051 freshCurrentLine(element: HTMLElement, rowObject: TableRowObject, firstElement?: HTMLElement): void { 1052 if (!rowObject) { 1053 if (firstElement) { 1054 firstElement.style.display = 'none'; 1055 } 1056 element.style.display = 'none'; 1057 return; 1058 } 1059 let childIndex = -1; //@ts-ignore 1060 this.setHighLight(rowObject.data.isSearch, element); 1061 element.childNodes.forEach((child) => { 1062 if (child.nodeType !== 1) { 1063 return; 1064 } 1065 childIndex++; 1066 let idx = firstElement !== undefined ? childIndex + 1 : childIndex; 1067 this.freshLineFirstElementHandler(firstElement, rowObject, childIndex); 1068 //@ts-ignore 1069 let dataIndex = this.columns![idx].getAttribute('data-index') || '1'; //@ts-ignore 1070 let text = formatName(dataIndex, rowObject.data[dataIndex], this); // @ts-ignore 1071 if ((this.columns![idx] as unknown).template) { 1072 (child as HTMLElement).innerHTML = ''; 1073 (child as HTMLElement).appendChild( 1074 // @ts-ignore 1075 (this.columns![idx] as unknown).template.render(rowObject.data).content.cloneNode(true) 1076 ); 1077 // @ts-ignore 1078 (child as HTMLElement).title = text; 1079 } else { 1080 //@ts-ignore 1081 (child as HTMLElement).innerHTML = text; //@ts-ignore 1082 (child as HTMLElement).title = text; 1083 } 1084 }); 1085 this.freshLineStyleAndEvents(element, rowObject, firstElement); 1086 } 1087 1088 freshLineFirstElementHandler(rowFirstElement: unknown, rowObject: TableRowObject, childIndex: number): void { 1089 if (rowFirstElement !== undefined && childIndex === 0) { 1090 //@ts-ignore 1091 this.setHighLight(rowObject.data.isSearch, rowFirstElement); // @ts-ignore 1092 (rowFirstElement as unknown).data = rowObject.data; // @ts-ignore 1093 if ((this.columns![0] as unknown).template) { 1094 // @ts-ignore 1095 rowFirstElement.innerHTML = (this.columns![0] as unknown).template 1096 .render(rowObject.data) 1097 .content.cloneNode(true).innerHTML; 1098 } else { 1099 let dataIndex = this.columns![0].getAttribute('data-index') || '1'; //@ts-ignore 1100 let text = formatName(dataIndex, rowObject.data[dataIndex], this); // @ts-ignore 1101 rowFirstElement.innerHTML = text; // @ts-ignore 1102 rowFirstElement.title = text; 1103 } //@ts-ignore 1104 if (rowObject.children && rowObject.children.length > 0 && !rowObject.data.hasNext) { 1105 let btn = this.createExpandBtn(rowObject); // @ts-ignore 1106 rowFirstElement.insertBefore(btn, rowFirstElement.firstChild); 1107 } // @ts-ignore 1108 rowFirstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px'; 1109 if (!rowObject.children || rowObject.children.length === 0) { 1110 // @ts-ignore 1111 rowFirstElement.style.paddingLeft = iconWidth * rowObject.depth + iconWidth + iconPadding * 2 + 'px'; 1112 } //@ts-ignore 1113 if (rowObject.data.hasNext) { 1114 let btn = this.createBtn(rowObject); // @ts-ignore 1115 rowFirstElement.title = rowObject.data.objectName; // @ts-ignore 1116 rowFirstElement.insertBefore(btn, rowFirstElement.firstChild); // @ts-ignore 1117 rowFirstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px'; 1118 } // @ts-ignore 1119 rowFirstElement.onclick = (): void => { 1120 this.dispatchRowClickEvent(rowObject, [rowFirstElement, element]); 1121 }; // @ts-ignore 1122 rowFirstElement.style.transform = `translateY(${rowObject.top - this.tableElement!.scrollTop}px)`; //@ts-ignore 1123 if (rowObject.data.isSelected !== undefined) { 1124 //@ts-ignore 1125 this.setSelectedRow(rowObject.data.isSelected, [rowFirstElement]); 1126 } else { 1127 this.setSelectedRow(false, [rowFirstElement]); 1128 } 1129 } 1130 } 1131 1132 freshLineStyleAndEvents(element: HTMLElement, rowData: TableRowObject, firstElement?: HTMLElement): void { 1133 if (element.style.display === 'none') { 1134 element.style.display = 'grid'; 1135 } 1136 element.style.transform = `translateY(${rowData.top}px)`; 1137 if (firstElement && firstElement.style.display === 'none') { 1138 firstElement.style.display = 'flex'; 1139 } 1140 element.onclick = (e): void => { 1141 if (firstElement !== undefined) { 1142 this.dispatchRowClickEvent(rowData, [firstElement, element]); 1143 } else { 1144 this.dispatchRowClickEvent(rowData, [element]); 1145 } 1146 }; 1147 element.onmouseenter = (): void => { 1148 this.dispatchRowHoverEvent(rowData, [element]); 1149 }; 1150 // @ts-ignore 1151 (element as unknown).data = rowData.data; //@ts-ignore 1152 if (rowData.data.isSelected !== undefined) { 1153 //@ts-ignore 1154 this.setSelectedRow(rowData.data.isSelected, [element]); 1155 } else { 1156 this.setSelectedRow(false, [element]); 1157 } //@ts-ignore 1158 if (rowData.data.isHover !== undefined) { 1159 //@ts-ignore 1160 this.setMouseIn(rowData.data.isHover, [element]); 1161 } else { 1162 this.setMouseIn(false, [element]); 1163 } 1164 if (this.getItemTextColor) { 1165 // @ts-ignore 1166 element.style.color = this.getItemTextColor((element as unknown).data); 1167 } 1168 } 1169 1170 setSelectedRow(isSelected: boolean, rows: unknown[]): void { 1171 if (isSelected) { 1172 rows.forEach((row) => { 1173 // @ts-ignore 1174 if (row.classList.contains('mouse-in')) { 1175 // @ts-ignore 1176 row.classList.remove('mouse-in'); 1177 } // @ts-ignore 1178 row.classList.add('mouse-select'); 1179 }); 1180 } else { 1181 rows.forEach((row) => { 1182 // @ts-ignore 1183 row.classList.remove('mouse-select'); 1184 }); 1185 } 1186 } 1187 1188 setMouseIn(isMouseIn: boolean, rows: unknown[]): void { 1189 if (isMouseIn) { 1190 rows.forEach((row) => { 1191 // @ts-ignore 1192 row.classList.add('mouse-in'); 1193 }); 1194 } else { 1195 rows.forEach((row) => { 1196 // @ts-ignore 1197 row.classList.remove('mouse-in'); 1198 }); 1199 } 1200 } 1201 1202 scrollToData(data: unknown): void { 1203 if (this.recycleDs.length > 0) { 1204 let filter = this.recycleDs.filter((item) => { 1205 // @ts-ignore 1206 return item.data === data; 1207 }); 1208 if (filter.length > 0) { 1209 // @ts-ignore 1210 this.tableElement!.scrollTop = filter[0].top; 1211 } 1212 this.setCurrentSelection(data); 1213 } 1214 } 1215 1216 expandList(datasource: unknown[]): void { 1217 let source = this.recycleDs.filter((item) => { 1218 // @ts-ignore 1219 return datasource.indexOf(item.data) !== -1; 1220 }); 1221 if (source.length > 0) { 1222 source.forEach((item) => { 1223 // @ts-ignore 1224 item.expanded = true; // @ts-ignore 1225 item.rowHidden = false; 1226 }); 1227 } 1228 this.reMeauseHeight(); 1229 } 1230 1231 clearAllSelection(rowObjectData: unknown = undefined): void { 1232 this.recycleDs.forEach((item) => { 1233 // @ts-ignore 1234 if (rowObjectData || (item.data !== rowObjectData && item.data.isSelected)) { 1235 // @ts-ignore 1236 item.data.isSelected = false; 1237 } 1238 }); 1239 this.setSelectedRow(false, this.currentTreeDivList); 1240 this.setSelectedRow(false, this.currentRecycleList); 1241 } 1242 1243 clearAllHover(rowObjectData: unknown): void { 1244 this.recycleDs.forEach((item) => { 1245 // @ts-ignore 1246 if (item.data !== rowObjectData && item.data.isHover) { 1247 // @ts-ignore 1248 item.data.isHover = false; 1249 } 1250 }); 1251 this.setMouseIn(false, this.currentTreeDivList); 1252 this.setMouseIn(false, this.currentRecycleList); 1253 } 1254 1255 mouseOut(): void { 1256 // @ts-ignore 1257 this.recycleDs.forEach((item) => (item.data.isHover = false)); 1258 this.setMouseIn(false, this.currentTreeDivList); 1259 this.setMouseIn(false, this.currentRecycleList); 1260 this.dispatchEvent( 1261 new CustomEvent('row-hover', { 1262 detail: { 1263 data: undefined, 1264 }, 1265 composed: true, 1266 }) 1267 ); 1268 } 1269 1270 setCurrentSelection(data: unknown): void { 1271 // @ts-ignore 1272 if (data.isSelected !== undefined) { 1273 this.currentTreeDivList.forEach((item) => { 1274 // @ts-ignore 1275 if ((item as unknown).data === data) { 1276 // @ts-ignore 1277 this.setSelectedRow(data.isSelected, [item]); 1278 } 1279 }); 1280 this.currentRecycleList.forEach((item) => { 1281 // @ts-ignore 1282 if ((item as unknown).data === data) { 1283 // @ts-ignore 1284 this.setSelectedRow(data.isSelected, [item]); 1285 } 1286 }); 1287 } 1288 } 1289 1290 setCurrentHover(data: unknown): void { 1291 this.setMouseIn(false, this.currentTreeDivList); 1292 this.setMouseIn(false, this.currentRecycleList); // @ts-ignore 1293 if (data.isHover !== undefined) { 1294 this.currentTreeDivList.forEach((item) => { 1295 // @ts-ignore 1296 if ((item as unknown).data === data) { 1297 // @ts-ignore 1298 this.setMouseIn(data.isHover, [item]); 1299 } 1300 }); 1301 this.currentRecycleList.forEach((item) => { 1302 // @ts-ignore 1303 if ((item as unknown).data === data) { 1304 // @ts-ignore 1305 this.setMouseIn(data.isHover, [item]); 1306 } 1307 }); 1308 } 1309 } 1310 1311 dispatchRowClickEventIcon(rowObject: unknown, elements: unknown[]): void { 1312 this.dispatchEvent( 1313 new CustomEvent('icon-click', { 1314 detail: { 1315 // @ts-ignore 1316 ...rowObject.data, // @ts-ignore 1317 data: rowObject.data, 1318 callBack: (isSelected: boolean): void => { 1319 //是否爲单选 1320 if (isSelected) { 1321 // @ts-ignore 1322 this.clearAllSelection(rowObject.data); 1323 } // @ts-ignore 1324 this.setSelectedRow(rowObject.data.isSelected, elements); 1325 }, 1326 }, 1327 composed: true, 1328 }) 1329 ); 1330 } 1331 1332 dispatchRowClickEvent(rowObject: unknown, elements: unknown[]): void { 1333 this.dispatchEvent( 1334 new CustomEvent('row-click', { 1335 detail: { 1336 // @ts-ignore 1337 ...rowObject.data, // @ts-ignore 1338 data: rowObject.data, 1339 callBack: (isSelected: boolean): void => { 1340 //是否爲单选 1341 if (isSelected) { 1342 // @ts-ignore 1343 this.clearAllSelection(rowObject.data); 1344 } 1345 // @ts-ignore 1346 rowObject.data.isSelected = true; 1347 // @ts-ignore 1348 this.setSelectedRow(rowObject.data.isSelected, elements); 1349 }, 1350 }, 1351 composed: true, 1352 }) 1353 ); 1354 } 1355 1356 dispatchRowHoverEvent(rowObject: unknown, elements: unknown[]): void { 1357 this.dispatchEvent( 1358 new CustomEvent('row-hover', { 1359 detail: { 1360 // @ts-ignore 1361 data: rowObject.data, 1362 callBack: (): void => { 1363 // @ts-ignore 1364 this.clearAllHover(rowObject.data); // @ts-ignore 1365 this.setMouseIn(rowObject.data.isHover, elements); 1366 }, 1367 }, 1368 composed: true, 1369 }) 1370 ); 1371 } 1372 setHighLight(isSearch: boolean, element: unknown): void { 1373 if (isSearch) { 1374 // @ts-ignore 1375 element.setAttribute('high-light', ''); 1376 } else { 1377 // @ts-ignore 1378 element.removeAttribute('high-light'); 1379 } 1380 } 1381} 1382 1383if (!customElements.get('lit-page-table')) { 1384 customElements.define('lit-page-table', LitPageTable); 1385} 1386