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 {JSONToCSV} from "../utils/CSVFormater"; 17 18export const iconWidth = 20; 19export const iconPadding = 5; 20 21export const litPageTableHtml = ` 22 <style> 23 :host{ 24 display: grid; 25 grid-template-columns: repeat(1,1fr); 26 width: 100%; 27 position: relative; 28 font-weight: 500; 29 flex:1; 30 } 31 .tr{ 32 display: grid; 33 grid-column-gap: 5px; 34 min-width:100%; 35 } 36 .tr:nth-of-type(even){ 37 } 38 .tr{ 39 background-color: var(--dark-background,#FFFFFF); 40 } 41 .tr:hover{ 42 background-color: var(--dark-background6,#DEEDFF); 43 } 44 .tr[selected]{ 45 background-color: var(--dark-background6,#DEEDFF); 46 } 47 .tr[high-light]{ 48 font-weight: 600; 49 } 50 .td{ 51 box-sizing: border-box; 52 padding: 3px; 53 display: flex; 54 justify-content: flex-start; 55 align-items: center; 56 width: 100%; 57 height: auto; 58 cursor: pointer; 59 } 60 .td label{ 61 overflow: hidden; 62 text-overflow: ellipsis; 63 white-space: normal; 64 } 65 .td text{ 66 overflow: hidden; 67 text-overflow: ellipsis; 68 white-space: nowrap; 69 } 70 .td-order{ 71 } 72 .td-order:before{ 73 74 } 75 :host([grid-line]) .td{ 76 border-left: 1px solid #f0f0f0; 77 } 78 :host([grid-line]) .td:last-of-type{ 79 border-right: 1px solid #f0f0f0; 80 } 81 .table{ 82 width: 100%; 83 color: var(--dark-color2,#262626); 84 } 85 .thead{ 86 display: grid; 87 position: sticky; 88 top: 0; 89 font-weight: bold; 90 font-size: .9rem; 91 color: var(--dark-color1,#000); 92 background-color: var(--dark-background,#FFFFFF); 93 z-index: 1; 94 } 95 .tbody{ 96 width: 100%; 97 top: 0; 98 left: 0; 99 right:0; 100 bottom:0; 101 padding-bottom: 30px; 102 display: flex; 103 flex-direction: row 104 row-gap: 1px; 105 column-gap: 1px; 106 } 107 .tbottom{ 108 height: 30px; 109 width: calc(100% - 15px); 110 position: absolute; 111 bottom: 0; 112 z-index: 1; 113 justify-content: center; 114 align-items: center; 115 display: none; 116 flex-direction: row; 117 color: var(--dark-color1,#000); 118 background-color: var(--dark-background,#FFFFFF); 119 } 120 :host([pagination]) .tbottom{ 121 display: flex; 122 } 123 .tree{ 124 overflow-x:hidden; 125 overflow-y:hidden; 126 display: grid; 127 grid-template-columns: 1fr; 128 row-gap: 1px; 129 column-gap: 1px; 130 position:relative; 131 } 132 .tree:hover{ 133 overflow-x: overlay; 134 } 135 .tree-first-body{ 136 min-width: 100%; 137 box-sizing: border-box; 138 display:flex; 139 align-items:center; 140 white-space: nowrap; 141 font-weight: 500; 142 cursor: pointer; 143 } 144 .tree-first-body[high-light]{ 145 font-weight: 600; 146 } 147 .tree-first-body:hover{ 148 background-color: var(--dark-background6,#DEEDFF); /*antd #fafafa 42b983*/ 149 } 150 .body{ 151 display: grid; 152 grid-template-columns: 1fr; 153 row-gap: 1px; 154 column-gap: 1px; 155 flex:1; 156 position: relative; 157 } 158 :host([grid-line]) .tbody{ 159 border-bottom: 1px solid #f0f0f0; 160 background-color: #f0f0f0; 161 } 162 .th{ 163 grid-column-gap: 5px; 164 display: grid; 165 background-color: var(--dark-background,#FFFFFF); 166 } 167 168 .tree-icon{ 169 font-size: 1.2rem; 170 width: 20px; 171 height: 20px; 172 padding-right: 5px; 173 padding-left: 5px; 174 cursor: pointer; 175 } 176 .tree-icon:hover{ 177 color: #42b983; 178 } 179 .row-checkbox,row-checkbox-all{ 180 181 } 182 :host([no-head]) .thead{ 183 display: none; 184 } 185 .up-svg{ 186 position: absolute; 187 right: 5px; 188 top: 8px; 189 bottom: 8px; 190 width: 15px; 191 height: 15px; 192 } 193 .down-svg{ 194 position: absolute; 195 top: 8px; 196 right: 5px; 197 bottom: 8px; 198 width: 15px; 199 height: 15px; 200 } 201 .mouse-select{ 202 background-color: var(--dark-background6,#DEEDFF); 203 } 204 .mouse-in{ 205 background-color: var(--dark-background6,#DEEDFF); 206 } 207 .export{ 208 height:32px; 209 width: 32px; 210 cursor:pointer; 211 display:none; 212 align-items:center; 213 justify-content:center; 214 border-radius:5px; 215 box-sizing: border-box; 216 background-color: #000000; 217 opacity: 0.3; 218 position:absolute; 219 right:20px; 220 bottom:20px; 221 z-index: 999999; 222 } 223 .resize{ 224 width: 2px; 225 margin-right: 3px; 226 height: 20px; 227 background-color: #e0e0e0; 228 cursor: col-resize; 229 } 230 231 .progress{ 232 position: absolute; 233 height: 1px; 234 top: 0; 235 left: 0; 236 right: 0; 237 z-index: 999999; 238 } 239 :host([hideDownload]) .export{ 240 display: none; 241 } 242 .td::-webkit-scrollbar { 243 width: 0; 244 background-color: transparent; 245 } 246 </style> 247 <lit-progress-bar id="export_progress_bar" class="progress"></lit-progress-bar> 248 <slot id="slot" style="display: none"></slot> 249 <slot name="head"></slot> 250 <div class="export"> 251 <lit-icon size="18" style="color: #ffffff" name="copyhovered" ></lit-icon> 252 </div> 253 <div class="table" style="overflow-x:auto;"> 254 <div class="thead"></div> 255 <div class="tbody"> 256 <div class="tree"></div> 257 <div class="body"></div> 258 </div> 259 <div class="tbottom"> 260 <div id="previousPage" style="cursor: pointer">上一页</div> 261 <div id="currentPage" style="margin-left: 10px;margin-right: 10px">1</div> 262 <input id="targetPage" style="width: 60px;margin-right: 10px" min="1" type="number"/> 263 <div id="jumpPage" style="padding: 2px 10px;border: 1px solid #676767;margin-right: 10px;font-size: 13px;cursor: pointer">GO</div> 264 <div id="nextPage" style="cursor: pointer">下一页</div> 265 </div> 266 </div> 267 `; 268 269export const litTableHtml = ` 270 <style> 271 :host{ 272 display: grid; 273 grid-template-columns: repeat(1,1fr); 274 width: 100%; 275 position: relative; 276 font-weight: 500; 277 flex:1; 278 } 279 .tr{ 280 display: grid; 281 grid-column-gap: 5px; 282 min-width:100%; 283 } 284 .tr:nth-of-type(even){ 285 } 286 .tr{ 287 background-color: var(--dark-background,#FFFFFF); 288 } 289 .tr:hover{ 290 background-color: var(--dark-background6,#DEEDFF); 291 } 292 .tr[selected]{ 293 background-color: var(--dark-background6,#DEEDFF); 294 } 295 .tr[high-light]{ 296 font-weight: 600; 297 } 298 .td{ 299 box-sizing: border-box; 300 padding: 3px; 301 display: flex; 302 justify-content: flex-start; 303 align-items: center; 304 width: 100%; 305 height: auto; 306 line-height: 21px; 307 cursor: pointer; 308 } 309 .td label{ 310 overflow: hidden; 311 text-overflow: ellipsis; 312 white-space: normal; 313 } 314 .td text{ 315 overflow: hidden; 316 text-overflow: ellipsis; 317 white-space: nowrap; 318 } 319 .td-order{ 320 } 321 .td-order:before{ 322 323 } 324 :host([grid-line]) .td{ 325 border-left: 1px solid #f0f0f0; 326 } 327 :host([grid-line]) .td:last-of-type{ 328 border-right: 1px solid #f0f0f0; 329 } 330 .table{ 331 width: 100%; 332 color: var(--dark-color2,#262626); 333 } 334 .thead{ 335 display: grid; 336 position: sticky; 337 top: 0; 338 font-weight: bold; 339 font-size: .9rem; 340 color: var(--dark-color1,#000); 341 background-color: var(--dark-background,#FFFFFF); 342 z-index: 1; 343 } 344 .tbody{ 345 width: 100%; 346 top: 0; 347 left: 0; 348 right:0; 349 bottom:0; 350 display: flex; 351 flex-direction: row 352 row-gap: 1px; 353 column-gap: 1px; 354 } 355 .tree{ 356 overflow-x:hidden; 357 overflow-y:hidden; 358 display: grid; 359 grid-template-columns: 1fr; 360 row-gap: 1px; 361 column-gap: 1px; 362 position:relative; 363 } 364 .tree:hover{ 365 overflow-x: overlay; 366 } 367 .tree-first-body{ 368 min-width: 100%; 369 box-sizing: border-box; 370 display:flex; 371 align-items:center; 372 white-space: nowrap; 373 font-weight: 500; 374 cursor: pointer; 375 } 376 .tree-first-body[high-light]{ 377 font-weight: 600; 378 } 379 .tree-first-body:hover{ 380 background-color: var(--dark-background6,#DEEDFF); /*antd #fafafa 42b983*/ 381 } 382 .body{ 383 display: grid; 384 grid-template-columns: 1fr; 385 row-gap: 1px; 386 column-gap: 1px; 387 flex:1; 388 position: relative; 389 } 390 :host([grid-line]) .tbody{ 391 border-bottom: 1px solid #f0f0f0; 392 background-color: #f0f0f0; 393 } 394 .th{ 395 grid-column-gap: 5px; 396 display: grid; 397 background-color: var(--dark-background,#FFFFFF); 398 } 399 :host([data-query-scene]) .th { 400 background-color: #F6F6F6; 401 color: #7E7E7E; 402 } 403 :host([data-query-scene]) .tr { 404 background-color: #F6F6F6; 405 } 406 .tree-icon{ 407 font-size: 1.2rem; 408 width: 20px; 409 height: 20px; 410 padding-right: 5px; 411 padding-left: 5px; 412 cursor: pointer; 413 } 414 .tree-icon:hover{ 415 color: #42b983; 416 } 417 .row-checkbox,row-checkbox-all{ 418 419 } 420 :host([no-head]) .thead{ 421 display: none; 422 } 423 .up-svg{ 424 position: absolute; 425 right: 5px; 426 top: 8px; 427 bottom: 8px; 428 width: 15px; 429 height: 15px; 430 } 431 .down-svg{ 432 position: absolute; 433 top: 8px; 434 right: 5px; 435 bottom: 8px; 436 width: 15px; 437 height: 15px; 438 } 439 .button-icon{ 440 height: 32px; 441 width: 164px; 442 color: black; 443 font-size: 14px; 444 border: 1px solid black; 445 display: flex; 446 flex-direction: row; 447 align-items: center; 448 justify-content: center; 449 cursor: pointer; 450 background: var(--dark-background3,#FFFFFF); 451 border-radius: 20px; 452 padding: 15px; 453 transition: opacity 0.2s; 454 outline: none; 455 position: relative; 456 overflow: hidden; 457 } 458 .button-icon:active { 459 background: var(--dark-background1,#f5f5f5) 460 } 461 .mouse-select{ 462 background-color: var(--dark-background6,#DEEDFF); 463 } 464 .mouse-in{ 465 background-color: var(--dark-background6,#DEEDFF); 466 } 467 .export{ 468 height:32px; 469 width: 32px; 470 cursor:pointer; 471 display:none; 472 align-items:center; 473 justify-content:center; 474 border-radius:5px; 475 box-sizing: border-box; 476 background-color: #000000; 477 opacity: 0.3; 478 position:absolute; 479 right:20px; 480 bottom:20px; 481 z-index: 999999; 482 } 483 .resize{ 484 width: 2px; 485 margin-right: 3px; 486 height: 20px; 487 background-color: #e0e0e0; 488 cursor: col-resize; 489 } 490 .progress{ 491 position: absolute; 492 height: 1px; 493 top: 0; 494 left: 0; 495 right: 0; 496 z-index: 999999; 497 } 498 :host([hideDownload]) .export{ 499 display: none; 500 } 501 </style> 502 <lit-progress-bar id="export_progress_bar" class="progress"></lit-progress-bar> 503 <slot id="slot" style="display: none"></slot> 504 <slot name="head"></slot> 505 <div class="export"> 506 <lit-icon size="18" style="color: #ffffff" name="copyhovered" ></lit-icon> 507 </div> 508 <div class="table" style="overflow-x:auto;"> 509 <div class="thead"></div> 510 <div class="tbody"> 511 <div class="tree"></div> 512 <div class="body"></div> 513 </div> 514 </div> 515 `; 516 517export function createDownUpSvg(index: number, head: any) { 518 let NS = 'http://www.w3.org/2000/svg'; 519 let upSvg: any = document.createElementNS(NS, 'svg'); 520 let upPath: any = document.createElementNS(NS, 'path'); 521 upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); 522 upSvg.setAttribute('viewBox', '0 0 1024 1024'); 523 upSvg.setAttribute('stroke', 'let(--dark-color1,#212121)'); 524 upSvg.classList.add('up-svg'); 525 upPath.setAttribute( 526 'd', 527 'M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z' 528 ); 529 upSvg.appendChild(upPath); 530 let downSvg: any = document.createElementNS(NS, 'svg'); 531 let downPath: any = document.createElementNS(NS, 'path'); 532 downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); 533 downSvg.setAttribute('viewBox', '0 0 1024 1024'); 534 downSvg.setAttribute('stroke', 'let(--dark-color1,#212121)'); 535 downSvg.classList.add('down-svg'); 536 downPath.setAttribute( 537 'd', 538 'M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z' 539 ); 540 downSvg.appendChild(downPath); 541 if (index == 0) { 542 head.sortType = 0; // 默认以第一列 降序排序 作为默认排序 543 upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); 544 downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); 545 } 546 upSvg.style.display = 'none'; 547 downSvg.style.display = 'none'; 548 head.appendChild(upSvg); 549 head.appendChild(downSvg); 550 return {upSvg, downSvg} 551} 552 553export function exportData(that: any): void { 554 if (that.exportLoading || that.ds.length === 0) { 555 return; 556 } 557 that.exportLoading = true; 558 that.exportProgress!.loading = true; 559 let date = new Date(); 560 JSONToCSV.csvExport({ 561 columns: that.columns as any[], 562 tables: that.ds, 563 fileName: `${date.getTime()}`, 564 columnFormatter: that.itemTextHandleMap, 565 exportFormatter: that.exportTextHandleMap, 566 }).then((res) => { 567 that.exportLoading = false; 568 that.exportProgress!.loading = false; 569 }); 570} 571 572export function formatExportData(dataSource: any[], that: any): any[] { 573 if (dataSource === undefined || dataSource.length === 0) { 574 return []; 575 } 576 if (that.columns === undefined) { 577 return []; 578 } 579 return dataSource.map((item) => { 580 let formatData: any = {}; 581 that.columns!.forEach((column: any) => { 582 let dataIndex = column.getAttribute('data-index'); 583 let columnName = column.getAttribute('title'); 584 if (columnName === '') { 585 columnName = dataIndex; 586 } 587 if (dataIndex && columnName && item[dataIndex] != undefined) { 588 formatData[columnName] = item[dataIndex]; 589 } 590 }); 591 if (item.children !== undefined) { 592 formatData.children = formatExportData(item.children, that); 593 } 594 return formatData; 595 }); 596} 597 598export function recursionExportTableData(columns: any[], dataSource: any[]): string { 599 let concatStr = '\r\n'; 600 dataSource.forEach((item, index) => { 601 concatStr += columns 602 .map((column) => { 603 let dataIndex = column.getAttribute('data-index'); 604 return `"${item[dataIndex] || ''}" `; 605 }) 606 .join(','); 607 if (item.children !== undefined) { 608 concatStr += recursionExportTableData(columns, item.children); 609 } 610 if (index !== dataSource.length - 1) { 611 concatStr += '\r\n'; 612 } 613 }); 614 return concatStr; 615} 616 617export function addCopyEventListener(that: any): void { 618 that.tableElement?.addEventListener('copy', (e: any) => { 619 // @ts-ignore 620 let clipboardData = e.clipboardData || window.clipboardData; 621 if (!clipboardData) return; 622 // @ts-ignore 623 let text = window.getSelection().toString(); 624 if (text) { 625 e.preventDefault(); 626 let length = that.tableColumns?.length || 1; 627 let strings = text.split('\n'); 628 let formatStr = ''; 629 for (let i = 0; i < strings.length; i++) { 630 if (i % length != 0) { 631 formatStr += ' '; 632 } 633 formatStr += strings[i]; 634 if (i !== 0 && i % length === length - 1) { 635 formatStr += '\n'; 636 } 637 } 638 clipboardData.setData('text/plain', formatStr); 639 } 640 }); 641} 642 643export function addSelectAllBox(rowElement: HTMLDivElement, that: any): void { 644 if (that.selectable) { 645 let box = document.createElement('div'); 646 box.style.display = 'flex'; 647 box.style.justifyContent = 'center'; 648 box.style.alignItems = 'center'; 649 box.style.gridArea = '_checkbox_'; 650 box.classList.add('td'); 651 box.style.backgroundColor = '#ffffff66'; 652 let checkbox = document.createElement('lit-checkbox'); 653 checkbox.classList.add('row-checkbox-all'); 654 checkbox.onchange = (e: any) => { 655 that.shadowRoot!.querySelectorAll('.row-checkbox').forEach((a: any) => (a.checked = e.detail.checked)); 656 if (e.detail.checked) { 657 that.shadowRoot!.querySelectorAll('.tr').forEach((a: any) => a.setAttribute('checked', '')); 658 } else { 659 that.shadowRoot!.querySelectorAll('.tr').forEach((a: any) => a.removeAttribute('checked')); 660 } 661 }; 662 box.appendChild(checkbox); 663 rowElement.appendChild(box); 664 } 665} 666 667export function fixed(td: HTMLElement, placement: string, bgColor: string): void { 668 td.style.position = 'sticky'; 669 if (placement === 'left') { 670 td.style.left = '0px'; 671 td.style.boxShadow = '3px 0px 5px #33333333'; 672 } else if (placement === 'right') { 673 td.style.right = '0px'; 674 td.style.boxShadow = '-3px 0px 5px #33333333'; 675 } 676} 677 678export function formatName(key: string, name: any, that: any): any { 679 let content = name; 680 if (that.itemTextHandleMap.has(key)) { 681 content = that.itemTextHandleMap.get(key)?.(name) || ''; 682 } 683 if (content !== undefined && content !== null) { 684 return content.toString().replace(/</g, '<').replace(/>/g, '>'); 685 } 686 return ''; 687}