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