• 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 NSAsciiValues = [104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 119, 51, 46, 111, 114, 103, 47, 50, 48, 48, 48, 47, 115, 118, 103];
521  let NS = String.fromCharCode.apply(null, NSAsciiValues);
522  let upSvg: SVGSVGElement = document.createElementNS(NS, 'svg') as SVGSVGElement;
523  let upPath: Element = document.createElementNS(NS, 'path');
524  upSvg.setAttribute('fill', 'let(--dark-color1,#212121)');
525  upSvg.setAttribute('viewBox', '0 0 1024 1024');
526  upSvg.setAttribute('stroke', 'let(--dark-color1,#212121)');
527  upSvg.classList.add('up-svg');
528  upPath.setAttribute(
529    'd',
530    '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'
531  );
532  upSvg.appendChild(upPath);
533  let downSvg: SVGSVGElement = document.createElementNS(NS, 'svg') as SVGSVGElement;
534  let downPath: Element = document.createElementNS(NS, 'path');
535  downSvg.setAttribute('fill', 'let(--dark-color1,#212121)');
536  downSvg.setAttribute('viewBox', '0 0 1024 1024');
537  downSvg.setAttribute('stroke', 'let(--dark-color1,#212121)');
538  downSvg.classList.add('down-svg');
539  downPath.setAttribute(
540    'd',
541    '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'
542  );
543  downSvg.appendChild(downPath);
544  if (index === 0) {
545    //@ts-ignore
546    head.sortType = 0; // 默认以第一列 降序排序 作为默认排序
547    upSvg.setAttribute('fill', 'let(--dark-color1,#212121)');
548    downSvg.setAttribute('fill', 'let(--dark-color1,#212121)');
549  }
550  upSvg.style.display = 'none';
551  downSvg.style.display = 'none'; //@ts-ignore
552  head.appendChild(upSvg); //@ts-ignore
553  head.appendChild(downSvg);
554  return { upSvg, downSvg };
555}
556
557export function exportData(that: unknown): void {
558  //@ts-ignore
559  if (that.exportLoading || that.ds.length === 0) {
560    return;
561  } //@ts-ignore
562  that.exportLoading = true; //@ts-ignore
563  that.exportProgress!.loading = true;
564  let date = new Date();
565  JSONToCSV.csvExport({
566    //@ts-ignore
567    columns: that.columns as unknown[], //@ts-ignore
568    tables: that.ds,
569    fileName: `${date.getTime()}`, //@ts-ignore
570    columnFormatter: that.itemTextHandleMap, //@ts-ignore
571    exportFormatter: that.exportTextHandleMap,
572  }).then((res) => {
573    //@ts-ignore
574    that.exportLoading = false; //@ts-ignore
575    that.exportProgress!.loading = false;
576  });
577}
578
579export function formatExportData(dataSource: unknown[], that: unknown): unknown[] {
580  if (dataSource === undefined || dataSource.length === 0) {
581    return [];
582  } //@ts-ignore
583  if (that.columns === undefined) {
584    return [];
585  }
586  return dataSource.map((item) => {
587    let formatData: unknown = {}; //@ts-ignore
588    that.columns!.forEach((column: unknown) => {
589      //@ts-ignore
590      let dataIndex = column.getAttribute('data-index'); //@ts-ignore
591      let columnName = column.getAttribute('title');
592      if (columnName === '') {
593        columnName = dataIndex;
594      } //@ts-ignore
595      if (dataIndex && columnName && item[dataIndex] !== undefined) {
596        //@ts-ignore
597        formatData[columnName] = item[dataIndex];
598      }
599    }); //@ts-ignore
600    if (item.children !== undefined) {
601      //@ts-ignore
602      formatData.children = formatExportData(item.children, that);
603    }
604    return formatData;
605  });
606}
607
608export function recursionExportTableData(columns: unknown[], dataSource: unknown[]): string {
609  let concatStr = '\r\n';
610  dataSource.forEach((item, index) => {
611    concatStr += columns
612      .map((column) => {
613        //@ts-ignore
614        let dataIndex = column.getAttribute('data-index'); //@ts-ignore
615        return `"${item[dataIndex] || ''}"    `;
616      })
617      .join(','); //@ts-ignore
618    if (item.children !== undefined) {
619      //@ts-ignore
620      concatStr += recursionExportTableData(columns, item.children);
621    }
622    if (index !== dataSource.length - 1) {
623      concatStr += '\r\n';
624    }
625  });
626  return concatStr;
627}
628
629export function addCopyEventListener(that: unknown): void {
630  //@ts-ignore
631  that.tableElement?.addEventListener('copy', (e: unknown) => {
632    // @ts-ignore
633    let clipboardData = e.clipboardData || window.clipboardData;
634    if (!clipboardData) {
635      return;
636    }
637    // @ts-ignore
638    let text = window.getSelection().toString();
639    if (text) {
640      //@ts-ignore
641      e.preventDefault(); //@ts-ignore
642      let length = that.tableColumns?.length || 1;
643      let strings = text.split('\n');
644      let formatStr = '';
645      for (let i = 0; i < strings.length; i++) {
646        if (i % length !== 0) {
647          formatStr += '    ';
648        }
649        formatStr += strings[i];
650        if (i !== 0 && i % length === length - 1) {
651          formatStr += '\n';
652        }
653      }
654      clipboardData.setData('text/plain', formatStr);
655    }
656  });
657}
658
659export function addSelectAllBox(rowElement: HTMLDivElement, that: unknown): void {
660  //@ts-ignore
661  if (that.selectable) {
662    let box = document.createElement('div');
663    box.style.display = 'flex';
664    box.style.justifyContent = 'center';
665    box.style.alignItems = 'center';
666    box.style.gridArea = '_checkbox_';
667    box.classList.add('td');
668    box.style.backgroundColor = '#ffffff66';
669    let checkbox = document.createElement('lit-checkbox');
670    checkbox.classList.add('row-checkbox-all');
671    checkbox.onchange = (e: unknown): void => {
672      //@ts-ignore
673      that.shadowRoot!.querySelectorAll('.row-checkbox').forEach((a: unknown) => (a.checked = e.detail.checked)); //@ts-ignore
674      if (e.detail.checked) {
675        //@ts-ignore
676        that.shadowRoot!.querySelectorAll('.tr').forEach((a: unknown) => a.setAttribute('checked', ''));
677      } else {
678        //@ts-ignore
679        that.shadowRoot!.querySelectorAll('.tr').forEach((a: unknown) => a.removeAttribute('checked'));
680      }
681    };
682    box.appendChild(checkbox);
683    rowElement.appendChild(box);
684  }
685}
686
687export function fixed(td: HTMLElement, placement: string, bgColor: string): void {
688  td.style.position = 'sticky';
689  if (placement === 'left') {
690    td.style.left = '0px';
691    td.style.boxShadow = '3px 0px 5px #33333333';
692  } else if (placement === 'right') {
693    td.style.right = '0px';
694    td.style.boxShadow = '-3px 0px 5px #33333333';
695  }
696}
697
698export function formatName(key: string, name: unknown, that: unknown): unknown {
699  let content = name; //@ts-ignore
700  if (that.itemTextHandleMap.has(key)) {
701    //@ts-ignore
702    content = that.itemTextHandleMap.get(key)?.(name) || '';
703  }
704  if (content !== undefined && content !== null) {
705    return content.toString().replace(/</g, '&lt;').replace(/>/g, '&gt;');
706  }
707  return '';
708}
709