king
2023-04-20 99c0ccd473e30f029b81feb65975d654528bc3e5
2023-04-20
28个文件已修改
341 ■■■■ 已修改文件
src/menu/components/card/balcony/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/data-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/double-data-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/prop-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/table-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/data-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/carousel/prop-card/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-G6/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-bar/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-dashboard/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-pie/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/chart/antv-scatter/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/simple-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/step-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/form/tab-form/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/index.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/group/normal-group/options.jsx 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/iframe/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/search/main-search/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/edit-table/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/table/normal-table/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/timeline/normal-timeline/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/tree/antd-tree/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/index.jsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/datasource/verifycard/index.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/mob/components/search/single-search/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pc/components/login/normal-login/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tabviews/custom/components/group/normal-group/index.jsx 158 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/menu/components/card/balcony/index.jsx
@@ -333,7 +333,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/card/data-card/index.jsx
@@ -639,7 +639,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/card/double-data-card/index.jsx
@@ -634,7 +634,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/card/prop-card/index.jsx
@@ -552,7 +552,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/card/table-card/index.jsx
@@ -520,7 +520,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/carousel/data-card/index.jsx
@@ -275,7 +275,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/carousel/prop-card/index.jsx
@@ -350,7 +350,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/chart/antv-G6/index.jsx
@@ -1426,7 +1426,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/chart/antv-bar/index.jsx
@@ -1386,7 +1386,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/chart/antv-dashboard/index.jsx
@@ -555,7 +555,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/chart/antv-pie/index.jsx
@@ -729,7 +729,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/chart/antv-scatter/index.jsx
@@ -401,7 +401,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/form/simple-form/index.jsx
@@ -673,7 +673,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/form/step-form/index.jsx
@@ -797,7 +797,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/form/tab-form/index.jsx
@@ -799,7 +799,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/group/normal-group/index.jsx
@@ -1,8 +1,8 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Popover, Button, Modal } from 'antd'
import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, PrinterOutlined, UngroupOutlined } from '@ant-design/icons'
import { Popover, Modal } from 'antd'
import { EditOutlined, ToolOutlined, DeleteOutlined, FontColorsOutlined, UngroupOutlined } from '@ant-design/icons'
import MKEmitter from '@/utils/events.js'
import asyncComponent from '@/utils/asyncComponent'
@@ -187,7 +187,7 @@
        } trigger="hover">
          <ToolOutlined />
        </Popover>
        {group.setting && group.setting.print === 'true' ? <Button className="print-button" onClick={this.print}><PrinterOutlined /></Button> : null}
        {/* {group.setting && group.setting.print === 'true' ? <Button className="print-button" onClick={this.print}><PrinterOutlined /></Button> : null} */}
        <GroupComponents config={group} handleList={this.updateComponent} deleteCard={this.deleteCard} />
      </div>
    )
src/menu/components/group/normal-group/options.jsx
@@ -42,63 +42,61 @@
      precision: 0,
      required: true
    },
    {
      type: 'radio',
      field: 'print',
      label: '打印按钮',
      initval: setting.print || 'false',
      required: false,
      options: [
        {value: 'true', label: '显示'},
        {value: 'false', label: '隐藏'},
      ],
      controlFields: [
        {field: 'pageSize', values: ['true']},
        {field: 'pageLayout', values: ['true']},
        {field: 'syncModule', values: ['true']},
        {field: 'checkAll', values: ['true']},
        {field: 'hide', values: ['true']},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      field: 'pageSize',
      label: '打印尺寸',
      initval: setting.pageSize || 'A4',
      required: true,
      options: [
        {value: 'A3', label: 'A3'},
        {value: 'A4', label: 'A4'},
        {value: 'A5', label: 'A5'},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'radio',
      field: 'pageLayout',
      label: '打印布局',
      initval: setting.pageLayout || 'vertical',
      required: true,
      options: [
        {value: 'vertical', label: '纵向'},
        {value: 'horizontal', label: '横向'},
      ],
      forbid: appType === 'mob'
    },
    {
      type: 'checkbox',
      field: 'hide',
      label: '隐藏元素',
      initval: setting.hide || [],
      tooltip: '执行打印时需要隐藏的页面元素。',
      required: false,
      options: [
        {value: 'search', label: '搜索'},
        {value: 'button', label: '按钮'},
      ],
      forbid: appType === 'mob'
    },
    // {
    //   type: 'radio',
    //   field: 'print',
    //   label: '打印按钮',
    //   initval: setting.print || 'false',
    //   required: false,
    //   options: [
    //     {value: 'true', label: '显示'},
    //     {value: 'false', label: '隐藏'},
    //   ],
    //   controlFields: [
    //     {field: 'pageSize', values: ['true']},
    //     {field: 'pageLayout', values: ['true']},
    //     {field: 'hide', values: ['true']},
    //   ],
    //   forbid: appType === 'mob'
    // },
    // {
    //   type: 'radio',
    //   field: 'pageSize',
    //   label: '打印尺寸',
    //   initval: setting.pageSize || 'A4',
    //   required: true,
    //   options: [
    //     {value: 'A3', label: 'A3'},
    //     {value: 'A4', label: 'A4'},
    //     {value: 'A5', label: 'A5'},
    //   ],
    //   forbid: appType === 'mob'
    // },
    // {
    //   type: 'radio',
    //   field: 'pageLayout',
    //   label: '打印布局',
    //   initval: setting.pageLayout || 'vertical',
    //   required: true,
    //   options: [
    //     {value: 'vertical', label: '纵向'},
    //     {value: 'horizontal', label: '横向'},
    //   ],
    //   forbid: appType === 'mob'
    // },
    // {
    //   type: 'checkbox',
    //   field: 'hide',
    //   label: '隐藏元素',
    //   initval: setting.hide || [],
    //   tooltip: '执行打印时需要隐藏的页面元素。',
    //   required: false,
    //   options: [
    //     {value: 'search', label: '搜索'},
    //     {value: 'button', label: '按钮'},
    //   ],
    //   forbid: appType === 'mob'
    // },
    {
      type: 'radio',
      field: 'permission',
src/menu/components/iframe/index.jsx
@@ -175,7 +175,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/search/main-search/index.jsx
@@ -416,7 +416,7 @@
        <div className="component-name">
          <div className="center" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/table/edit-table/index.jsx
@@ -425,7 +425,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/table/normal-table/index.jsx
@@ -484,7 +484,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/timeline/normal-timeline/index.jsx
@@ -224,7 +224,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/components/tree/antd-tree/index.jsx
@@ -259,7 +259,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/menu/datasource/index.jsx
@@ -206,6 +206,12 @@
        res.subColumns.reverse()
      }
      if (this.verifyRef.state.debugId) {
        res.setting.debugId = this.verifyRef.state.debugId
      } else {
        delete res.setting.debugId
      }
      this.setState({loading: false, visible: false})
      this.props.updateConfig({...config, ...res})
    }, () => {
src/menu/datasource/verifycard/index.jsx
@@ -212,7 +212,8 @@
      median: _setting,
      searches: search,
      defaultSearch: _search,
      searchKey: ''
      searchKey: '',
      debugId: _setting.debugId || ''
    })
    this.getsysScript()
@@ -722,8 +723,9 @@
          if (sumParam) {
            Api.genericInterface(sumParam).then(res => {
              if (res.status) {
                this.setState({debugId: _debugId})
                resolve()
                this.setState({debugId: _debugId}, () => {
                  resolve()
                })
              } else {
                reject()
                Modal.error({
@@ -732,8 +734,9 @@
              }
            })
          } else {
            this.setState({debugId: _debugId})
            resolve()
            this.setState({debugId: _debugId}, () => {
              resolve()
            })
          }
        } else {
          reject()
src/mob/components/search/single-search/index.jsx
@@ -144,7 +144,7 @@
        <div className="component-name">
          <div className="center" onDoubleClick={() => {
            let oInput = document.createElement('input')
            oInput.value = card.uuid
            oInput.value = 'anchor' + card.uuid
            document.body.appendChild(oInput)
            oInput.select()
            document.execCommand('Copy')
src/pc/components/login/normal-login/index.jsx
@@ -197,7 +197,7 @@
          <div className="center">
            <div className="title" onDoubleClick={() => {
              let oInput = document.createElement('input')
              oInput.value = card.uuid
              oInput.value = 'anchor' + card.uuid
              document.body.appendChild(oInput)
              oInput.select()
              document.execCommand('Copy')
src/tabviews/custom/components/group/normal-group/index.jsx
@@ -1,7 +1,7 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Col, notification, Button, Row } from 'antd'
import { Col, notification, Row } from 'antd'
import Api from '@/api'
import asyncComponent from '@/utils/asyncComponent'
@@ -44,7 +44,7 @@
  state = {
    mainSearch: [],
    printing: false,
    // printing: false,
    data: null
  }
@@ -296,101 +296,101 @@
    })
  }
  canvasToImage(canvas) {
    let image = new Image()
    image.src = canvas.toDataURL('image/jpg')
    image.style = 'width:100%;height:100%;position:absolute;z-index:1;left:0px;top:0px;'
    return image
  }
  // canvasToImage(canvas) {
  //   let image = new Image()
  //   image.src = canvas.toDataURL('image/jpg')
  //   image.style = 'width:100%;height:100%;position:absolute;z-index:1;left:0px;top:0px;'
  //   return image
  // }
  print = () => {
    const { config } = this.props
    const { printing } = this.state
  // print = () => {
  //   const { config } = this.props
  //   const { printing } = this.state
    if (printing) return
    this.setState({printing: true})
  //   if (printing) return
  //   this.setState({printing: true})
    let qrcodes = document.getElementsByClassName('qrcode-box')
  //   let qrcodes = document.getElementsByClassName('qrcode-box')
    for (let i = 0; i < qrcodes.length; i++) {
      let canvas = qrcodes[i].getElementsByTagName('canvas')[0]
  //   for (let i = 0; i < qrcodes.length; i++) {
  //     let canvas = qrcodes[i].getElementsByTagName('canvas')[0]
      if (canvas) {
        let img = this.canvasToImage(canvas)
  //     if (canvas) {
  //       let img = this.canvasToImage(canvas)
  
        canvas.remove()
        qrcodes[i].append(img)
      }
    }
  //       canvas.remove()
  //       qrcodes[i].append(img)
  //     }
  //   }
    let pageSize = ['A4', 'A3', 'A5'].includes(config.setting.pageSize) ? config.setting.pageSize : 'A4'
    let pageLayout = config.setting.pageLayout !== 'horizontal' ? 'vertical' : 'horizontal'
    let hides = config.setting.hide || []
  //   let pageSize = ['A4', 'A3', 'A5'].includes(config.setting.pageSize) ? config.setting.pageSize : 'A4'
  //   let pageLayout = config.setting.pageLayout !== 'horizontal' ? 'vertical' : 'horizontal'
  //   let hides = config.setting.hide || []
    let pageParam = {
      A4: {
        vertical: 980,
        horizontal: 1200,
      },
      A3: {
        vertical: 1200,
        horizontal: 1600,
      },
      A5: {
        vertical: 700,
        horizontal: 1000,
      }
    }
  //   let pageParam = {
  //     A4: {
  //       vertical: 980,
  //       horizontal: 1200,
  //     },
  //     A3: {
  //       vertical: 1200,
  //       horizontal: 1600,
  //     },
  //     A5: {
  //       vertical: 700,
  //       horizontal: 1000,
  //     }
  //   }
    let width = pageParam[pageSize][pageLayout]
  //   let width = pageParam[pageSize][pageLayout]
    try {
      let jubuData =  document.getElementById(config.uuid).innerHTML
  //   try {
  //     let jubuData =  document.getElementById(config.uuid).innerHTML
      let iframe = document.createElement('IFRAME')
      let linkList = document.getElementsByTagName('link')     // 获取父窗口link标签对象列表
      let styleList = document.getElementsByTagName('style')   // 获取父窗口style标签对象列表
  //     let iframe = document.createElement('IFRAME')
  //     let linkList = document.getElementsByTagName('link')     // 获取父窗口link标签对象列表
  //     let styleList = document.getElementsByTagName('style')   // 获取父窗口style标签对象列表
      document.body.appendChild(iframe)
      let doc = iframe.contentWindow.document
  //     document.body.appendChild(iframe)
  //     let doc = iframe.contentWindow.document
      
      doc.open()
      doc.write(`<!DOCTYPE html><html lang="en"><head>`)
      for (let i = 0;i < linkList.length;i++) {
        if (linkList[i].type === 'text/css') {
          doc.write(`<LINK rel="stylesheet" type="text/css" href="${linkList[i].href}">`)
        }
      }
      doc.write(`<style>body{width: ${width}px!important;} *{border-style: solid;border-width: 0;} .print-button{display: none!important;} ${hides.includes('search') ? '.top-search{display: none!important;}' : ''} ${hides.includes('button') ? '.ant-btn{opacity: 0!important;}' : ''}</style>`)
      for (let i = 0;i < styleList.length;i++) {
        doc.write('<style>' + styleList[i].innerHTML + '</style>')
      }
      doc.write(`</head><body>`)
      doc.write(jubuData)
      doc.write(`</body></html>`)
      doc.close()
  //     doc.open()
  //     doc.write(`<!DOCTYPE html><html lang="en"><head>`)
  //     for (let i = 0;i < linkList.length;i++) {
  //       if (linkList[i].type === 'text/css') {
  //         doc.write(`<LINK rel="stylesheet" type="text/css" href="${linkList[i].href}">`)
  //       }
  //     }
  //     doc.write(`<style>body{width: ${width}px!important;} *{border-style: solid;border-width: 0;} .print-button{display: none!important;} ${hides.includes('search') ? '.top-search{display: none!important;}' : ''} ${hides.includes('button') ? '.ant-btn{opacity: 0!important;}' : ''}</style>`)
  //     for (let i = 0;i < styleList.length;i++) {
  //       doc.write('<style>' + styleList[i].innerHTML + '</style>')
  //     }
  //     doc.write(`</head><body>`)
  //     doc.write(jubuData)
  //     doc.write(`</body></html>`)
  //     doc.close()
      setTimeout(() => {
        iframe.contentWindow.focus()
        iframe.contentWindow.print()
  //     setTimeout(() => {
  //       iframe.contentWindow.focus()
  //       iframe.contentWindow.print()
        document.body.removeChild(iframe)
  //       document.body.removeChild(iframe)
        this.setState({printing: false})
      }, 500)
    } catch (e) {
      this.setState({printing: false})
      notification.warning({
        top: 92,
        message: '打印异常!',
        duration: 5
      })
    }
  }
  //       this.setState({printing: false})
  //     }, 500)
  //   } catch (e) {
  //     this.setState({printing: false})
  //     notification.warning({
  //       top: 92,
  //       message: '打印异常!',
  //       duration: 5
  //     })
  //   }
  // }
  render() {
    const { config } = this.props
    const { printing } = this.state
    // const { printing } = this.state
    if (!config.components || config.components.length === 0) return (<div style={config.style}></div>)
    
@@ -399,7 +399,7 @@
        {config.setting && config.setting.title ? <div className="group-header" style={config.headerStyle}>
          <span className="title">{config.setting.title}</span>
        </div> : null}
        {config.setting && config.setting.print === 'true' ? <Button className="print-button" icon="printer" loading={printing} onClick={this.print}></Button> : null}
        {/* {config.setting && config.setting.print === 'true' ? <Button className="print-button" icon="printer" loading={printing} onClick={this.print}></Button> : null} */}
        <Row className="component-wrap">{this.getComponents()}</Row>
      </div>
    )