• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, '&lt;').replace(/>/g, '&gt;');
705  }
706  return '';
707}
708