From 9cfccf5bd28a860fad48fe74ad7ea49d8af40dec Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期四, 03 十一月 2022 12:52:27 +0800
Subject: [PATCH] 2022-11-03

---
 src/menu/components/timeline/normal-timeline/index.jsx           |    2 
 src/menu/components/card/table-card/index.jsx                    |    2 
 src/mob/components/tabs/antv-tabs/index.jsx                      |    2 
 src/menu/components/card/cardcellcomponent/dragaction/action.jsx |   10 
 src/tabviews/custom/components/group/normal-group/index.scss     |   22 +
 src/menu/components/module/voucher/index.jsx                     |    2 
 src/tabviews/custom/popview/index.jsx                            |   56 ++-
 src/menu/components/chart/antv-scatter/index.jsx                 |    2 
 src/mob/components/official/index.jsx                            |    2 
 src/menu/components/tree/antd-tree/index.jsx                     |    2 
 src/menu/menushell/card.jsx                                      |    4 
 src/menu/components/share/normalheader/index.scss                |    1 
 src/tabviews/custom/components/card/cardcellList/index.jsx       |   57 ++-
 src/mob/colorsketch/index.jsx                                    |    4 
 src/menu/components/carousel/data-card/options.jsx               |   13 +
 src/menu/components/card/cardcellcomponent/index.jsx             |    2 
 src/menu/components/form/tab-form/index.jsx                      |    2 
 src/tabviews/custom/components/group/normal-group/index.jsx      |  171 +++++++-----
 src/mob/components/menubar/normal-menubar/index.jsx              |    2 
 src/pc/menushell/card.jsx                                        |    5 
 src/menu/components/carousel/prop-card/index.jsx                 |    2 
 src/menu/components/group/normal-group/options.jsx               |    7 
 src/menu/components/card/data-card/index.jsx                     |    2 
 src/menu/components/chart/antv-pie/index.jsx                     |    2 
 src/menu/components/group/groupcomponents/card.jsx               |    4 
 src/tabviews/custom/components/carousel/prop-card/index.jsx      |   10 
 src/menu/components/chart/antv-dashboard/index.jsx               |    2 
 src/tabviews/custom/index.jsx                                    |  156 ++++++-----
 src/mob/components/menubar/common-menubar/index.jsx              |    2 
 src/menu/components/card/prop-card/index.jsx                     |    2 
 src/menu/components/table/normal-table/index.jsx                 |    2 
 src/menu/components/tabs/tabcomponents/card.jsx                  |    4 
 src/menu/components/tabs/antv-tabs/index.jsx                     |    2 
 src/menu/components/group/normal-group/index.jsx                 |   12 
 src/menu/components/chart/chart-custom/index.jsx                 |    2 
 src/menu/components/card/cardcellcomponent/dragaction/card.jsx   |   12 
 src/menu/components/form/simple-form/index.jsx                   |    2 
 src/tabviews/custom/components/carousel/data-card/index.jsx      |   10 
 src/menu/components/chart/antv-bar/index.jsx                     |    2 
 src/menu/components/code/sandbox/index.jsx                       |    2 
 src/tabviews/custom/components/share/normalheader/index.scss     |    1 
 src/menu/components/table/edit-table/index.jsx                   |    2 
 src/mob/mobshell/card.jsx                                        |    4 
 src/menu/components/carousel/data-card/index.jsx                 |    2 
 src/mob/components/search/single-search/index.jsx                |    2 
 src/menu/components/card/balcony/index.jsx                       |    2 
 src/components/normalform/modalform/index.jsx                    |    4 
 src/menu/components/form/step-form/index.jsx                     |    2 
 src/tabviews/custom/components/share/tabtransfer/index.jsx       |   86 +++---
 src/menu/stylecontroller/index.jsx                               |   14 +
 src/menu/components/share/normalheader/index.jsx                 |   18 
 src/mob/components/tabs/tabcomponents/card.jsx                   |    4 
 src/menu/components/card/cardsimplecomponent/index.jsx           |   20 +
 src/menu/components/search/main-search/index.jsx                 |    2 
 src/pc/components/login/normal-login/index.jsx                   |    2 
 src/menu/components/editor/braft-editor/index.jsx                |    2 
 56 files changed, 482 insertions(+), 287 deletions(-)

diff --git a/src/components/normalform/modalform/index.jsx b/src/components/normalform/modalform/index.jsx
index ce8b71d..6a2636b 100644
--- a/src/components/normalform/modalform/index.jsx
+++ b/src/components/normalform/modalform/index.jsx
@@ -57,6 +57,10 @@
           required: item.required,
           message: item.label + '涓嶅彲涓虹┖!'
         }]
+
+        if (item.rules) {
+          _rules.push(...item.rules)
+        }
         
         item.rules = _rules
       } else if (item.type === 'number') {
diff --git a/src/menu/components/card/balcony/index.jsx b/src/menu/components/card/balcony/index.jsx
index 31c5004..4c89067 100644
--- a/src/menu/components/card/balcony/index.jsx
+++ b/src/menu/components/card/balcony/index.jsx
@@ -191,7 +191,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
index 31328d0..95f0033 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/action.jsx
@@ -66,6 +66,12 @@
     btnElement = (<Button style={_style}>{card.icon ? <MkIcon type={card.icon}/> : null}{card.label}{warning}</Button>)
   }
 
+  let _style_ = null
+
+  if (card.style && card.style.clear === 'left') {
+    _style_ = {clear: 'left'}
+  }
+
   return (
     <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
       <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
@@ -76,8 +82,8 @@
         {hasProfile ? <ProfileOutlined className="profile" title="setting" onClick={() => profileCard(id)} /> : null}
       </div>
     } trigger="hover">
-      <div ref={node => drag(drop(node))} className={'ant-col card-button-cell ant-col-' + card.width + (card.hidden === 'true' ? ' mk-hidden' : '')} onDoubleClick={(e) => {e.stopPropagation(); doubleClickCard(id)}}>
-        <div style={{opacity: isDragging ? 0 : 1, ...card.wrapStyle}}>
+      <div ref={node => drag(drop(node))} style={_style_} className={'ant-col card-button-cell ant-col-' + card.width + (card.hidden === 'true' ? ' mk-hidden' : '')} onDoubleClick={(e) => {e.stopPropagation(); doubleClickCard(id)}}>
+        <div style={{opacity: isDragging ? 0.3 : 1, ...card.wrapStyle}}>
           {btnElement}
         </div>
       </div>
diff --git a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
index 4e41566..f9657cf 100644
--- a/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
+++ b/src/menu/components/card/cardcellcomponent/dragaction/card.jsx
@@ -57,10 +57,10 @@
     },
   })
 
-  let _style = {opacity: isDragging ? 0 : 1}
+  let _style = {opacity: isDragging ? 0.3 : 1}
   
   if (card.style) {
-    _style = {...card.style, opacity: isDragging ? 0 : 1}
+    _style = {...card.style, opacity: isDragging ? 0.3 : 1}
     _style = resetStyle(_style)
   }
   if (card.eleType === 'picture' && card.maxWidth) {
@@ -191,6 +191,12 @@
     able = false
   }
 
+  let _style_ = null
+
+  if (card.style && card.style.clear === 'left') {
+    _style_ = {clear: 'left'}
+  }
+
   return (
     <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
       <div className="mk-popover-control" onDoubleClick={(e) => e.stopPropagation()}>
@@ -201,7 +207,7 @@
         {['text', 'number', 'slider', 'sequence', 'formula'].includes(card.eleType) ? <MarkColumn field={card.field || ''} columns={fields} type={card.eleType} marks={card.marks} onSubmit={(vals) => updateMarks({...card, marks: vals})} /> : null }
       </div>
     } trigger="hover">
-      <div ref={node => drag(drop(node))} className={'ant-col card-cell ant-col-' + card.width}>
+      <div ref={node => drag(drop(node))} style={_style_} className={'ant-col card-cell ant-col-' + card.width}>
         <div style={_style} onClick={clickComponent} onDoubleClick={() => able && editCard(id)} id={card.uuid}>
           {getContent()}
         </div>
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index bd882b1..bbab97e 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -162,6 +162,8 @@
       options = ['padding', 'margin']
     }
 
+    options.push('clear')
+
     this.setState({
       card: element
     })
diff --git a/src/menu/components/card/cardsimplecomponent/index.jsx b/src/menu/components/card/cardsimplecomponent/index.jsx
index 67e71fb..e46f414 100644
--- a/src/menu/components/card/cardsimplecomponent/index.jsx
+++ b/src/menu/components/card/cardsimplecomponent/index.jsx
@@ -16,6 +16,7 @@
 const NodesWrap = asyncComponent(() => import('./node-wrap'))
 const CardCellComponent = asyncComponent(() => import('../cardcellcomponent'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
+const PasteController = asyncIconComponent(() => import('@/components/paste'))
 
 class CardBoxComponent extends Component {
   static propTpyes = {
@@ -186,6 +187,24 @@
     this.props.updateElement(_card)
   }
 
+  paste = (element, resolve) => {
+    const { card } = this.state
+
+    let _uuid = Utils.getuuid()
+    
+    if (element.copyType === 'action') {
+      element.eleType = 'button'
+    }
+
+    element.uuid = _uuid
+    element.focus = true
+
+    resolve({status: true})
+
+    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+    MKEmitter.emit('cardAddElement', card.uuid, element)
+  }
+
   render() {
     const { cards } = this.props
     const { card } = this.state
@@ -216,6 +235,7 @@
                   <EditOutlined style={{color: '#1890ff'}} title="缂栬緫"/>
                 </NormalForm> : <NodesWrap card={card} updateMenus={this.updateNodes}/>}
                 {cards.type !== 'timeline' ? <CopyComponent type="cardcell" card={card}/> : null}
+                <PasteController options={['action', 'customCardElement']} updateConfig={this.paste} />
                 <FontColorsOutlined className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle}/>
                 {control ? <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
                   <div className="mk-popover-control">
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index 574a653..3eb6454 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -293,7 +293,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'height', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'height', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/card/prop-card/index.jsx b/src/menu/components/card/prop-card/index.jsx
index 4d31ae4..5e91a50 100644
--- a/src/menu/components/card/prop-card/index.jsx
+++ b/src/menu/components/card/prop-card/index.jsx
@@ -304,7 +304,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/card/table-card/index.jsx b/src/menu/components/card/table-card/index.jsx
index f42e90f..5596f30 100644
--- a/src/menu/components/card/table-card/index.jsx
+++ b/src/menu/components/card/table-card/index.jsx
@@ -254,7 +254,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/carousel/data-card/index.jsx b/src/menu/components/carousel/data-card/index.jsx
index aeb94fb..8f96d79 100644
--- a/src/menu/components/carousel/data-card/index.jsx
+++ b/src/menu/components/carousel/data-card/index.jsx
@@ -195,7 +195,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/carousel/data-card/options.jsx b/src/menu/components/carousel/data-card/options.jsx
index 6193479..7af48df 100644
--- a/src/menu/components/carousel/data-card/options.jsx
+++ b/src/menu/components/carousel/data-card/options.jsx
@@ -64,6 +64,7 @@
       controlFields: [
         {field: 'modalWidth', values: ['modal']},
         {field: 'modalContent', values: ['modal']},
+        {field: 'code', values: ['modal']},
       ]
     },
     {
@@ -95,6 +96,18 @@
       forbid: appType === 'mob'
     },
     {
+      type: 'text',
+      field: 'code',
+      label: '娑堟伅缂栫爜',
+      initval: wrap.code || '',
+      tooltip: '鐢ㄤ簬璁板綍娑堟伅鏄惁宸茶鐨勬爣璇嗭紝濡傛灉涓嶅悓椤甸潰涓瓨鍦ㄧ浉鍚屾秷鎭紝鍙寚瀹氬浐瀹氬�笺��',
+      required: false,
+      rules: [{
+        pattern: /^[0-9a-zA-Z_]*$/ig,
+        message: '鍙厑璁稿寘鍚暟瀛椼�佸瓧姣嶄互鍙奯銆�'
+      }]
+    },
+    {
       type: 'radio',
       field: 'autoplay',
       label: '鑷姩鍒囨崲',
diff --git a/src/menu/components/carousel/prop-card/index.jsx b/src/menu/components/carousel/prop-card/index.jsx
index 92d8dd5..042ea61 100644
--- a/src/menu/components/carousel/prop-card/index.jsx
+++ b/src/menu/components/carousel/prop-card/index.jsx
@@ -215,7 +215,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/chart/antv-bar/index.jsx b/src/menu/components/chart/antv-bar/index.jsx
index 319cd3f..055405a 100644
--- a/src/menu/components/chart/antv-bar/index.jsx
+++ b/src/menu/components/chart/antv-bar/index.jsx
@@ -1331,7 +1331,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/chart/antv-dashboard/index.jsx b/src/menu/components/chart/antv-dashboard/index.jsx
index 22f6b8e..47c6d44 100644
--- a/src/menu/components/chart/antv-dashboard/index.jsx
+++ b/src/menu/components/chart/antv-dashboard/index.jsx
@@ -508,7 +508,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/chart/antv-pie/index.jsx b/src/menu/components/chart/antv-pie/index.jsx
index 9009ffd..bec58c4 100644
--- a/src/menu/components/chart/antv-pie/index.jsx
+++ b/src/menu/components/chart/antv-pie/index.jsx
@@ -665,7 +665,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/chart/antv-scatter/index.jsx b/src/menu/components/chart/antv-scatter/index.jsx
index 2180026..0620a68 100644
--- a/src/menu/components/chart/antv-scatter/index.jsx
+++ b/src/menu/components/chart/antv-scatter/index.jsx
@@ -350,7 +350,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/chart/chart-custom/index.jsx b/src/menu/components/chart/chart-custom/index.jsx
index d5ea198..347ddcc 100644
--- a/src/menu/components/chart/chart-custom/index.jsx
+++ b/src/menu/components/chart/chart-custom/index.jsx
@@ -231,7 +231,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/code/sandbox/index.jsx b/src/menu/components/code/sandbox/index.jsx
index 635e948..53856d4 100644
--- a/src/menu/components/code/sandbox/index.jsx
+++ b/src/menu/components/code/sandbox/index.jsx
@@ -125,7 +125,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/editor/braft-editor/index.jsx b/src/menu/components/editor/braft-editor/index.jsx
index a8d23f8..b032aec 100644
--- a/src/menu/components/editor/braft-editor/index.jsx
+++ b/src/menu/components/editor/braft-editor/index.jsx
@@ -128,7 +128,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/form/simple-form/index.jsx b/src/menu/components/form/simple-form/index.jsx
index f53de00..120d9f4 100644
--- a/src/menu/components/form/simple-form/index.jsx
+++ b/src/menu/components/form/simple-form/index.jsx
@@ -194,7 +194,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/form/step-form/index.jsx b/src/menu/components/form/step-form/index.jsx
index fb5a412..b6fa922 100644
--- a/src/menu/components/form/step-form/index.jsx
+++ b/src/menu/components/form/step-form/index.jsx
@@ -201,7 +201,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/form/tab-form/index.jsx b/src/menu/components/form/tab-form/index.jsx
index 1b1089b..137d437 100644
--- a/src/menu/components/form/tab-form/index.jsx
+++ b/src/menu/components/form/tab-form/index.jsx
@@ -213,7 +213,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/group/groupcomponents/card.jsx b/src/menu/components/group/groupcomponents/card.jsx
index 992c717..f1c77da 100644
--- a/src/menu/components/group/groupcomponents/card.jsx
+++ b/src/menu/components/group/groupcomponents/card.jsx
@@ -58,6 +58,10 @@
     style = { opacity: 0.3}
   }
 
+  if (card.style && card.style.clear === 'left') {
+    style.clear = 'left'
+  }
+
   const getCardComponent = () => {
     if (card.type === 'bar' || card.type === 'line') {
       return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard} />)
diff --git a/src/menu/components/group/normal-group/index.jsx b/src/menu/components/group/normal-group/index.jsx
index 3d5ec2f..0544f9d 100644
--- a/src/menu/components/group/normal-group/index.jsx
+++ b/src/menu/components/group/normal-group/index.jsx
@@ -13,6 +13,7 @@
 
 const NormalForm = asyncIconComponent(() => import('@/components/normalform'))
 const CopyComponent = asyncIconComponent(() => import('@/menu/components/share/copycomponent'))
+const NormalHeader = asyncComponent(() => import('@/menu/components/share/normalheader'))
 const PasteComponent = asyncIconComponent(() => import('../paste'))
 const GroupComponents = asyncComponent(() => import('../groupcomponents'))
 
@@ -69,7 +70,7 @@
   changeStyle = () => {
     const { group } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], group.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], group.style, this.getStyle)
   }
 
   getStyle = (style) => {
@@ -119,7 +120,13 @@
   }
 
   updateWrap = (res) => {
-    this.updateComponent({...this.state.group, setting: res})
+    let group = {...this.state.group, setting: res}
+
+    if (res.title && !group.headerStyle) {
+      group.headerStyle = { fontSize: '16px', borderBottomWidth: '1px', borderBottomColor: '#e8e8e8' }
+    }
+
+    this.updateComponent(group)
   }
 
   render() {
@@ -133,6 +140,7 @@
 
     return (
       <div className={'menu-group-edit-box ' + (paddingTop ? 'padding ' : '') + (group.setting.layout || '')} style={_style} id={group.uuid}>
+        <NormalHeader hideSearch="true" config={group} updateComponent={this.updateComponent}/>
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             <NormalForm title="鍒嗙粍璁剧疆" width={700} update={this.updateWrap} getForms={this.getWrapForms}>
diff --git a/src/menu/components/group/normal-group/options.jsx b/src/menu/components/group/normal-group/options.jsx
index 9c6f2e6..168bc3b 100644
--- a/src/menu/components/group/normal-group/options.jsx
+++ b/src/menu/components/group/normal-group/options.jsx
@@ -18,6 +18,13 @@
   const settingForm = [
     {
       type: 'text',
+      field: 'title',
+      label: '鏍囬',
+      initval: setting.title || '',
+      required: false
+    },
+    {
+      type: 'text',
       field: 'name',
       label: '缁勪欢鍚嶇О',
       initval: setting.name || '',
diff --git a/src/menu/components/module/voucher/index.jsx b/src/menu/components/module/voucher/index.jsx
index 329d64d..5f13cd1 100644
--- a/src/menu/components/module/voucher/index.jsx
+++ b/src/menu/components/module/voucher/index.jsx
@@ -85,7 +85,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/search/main-search/index.jsx b/src/menu/components/search/main-search/index.jsx
index 6a98307..764066a 100644
--- a/src/menu/components/search/main-search/index.jsx
+++ b/src/menu/components/search/main-search/index.jsx
@@ -102,7 +102,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   /**
diff --git a/src/menu/components/share/normalheader/index.jsx b/src/menu/components/share/normalheader/index.jsx
index 2f552fd..acc4e22 100644
--- a/src/menu/components/share/normalheader/index.jsx
+++ b/src/menu/components/share/normalheader/index.jsx
@@ -48,24 +48,24 @@
   changeStyle = () => {
     const { config } = this.props
 
-    let options = ['font', 'border', 'background']
-    if (config.type === 'menubar') {
-      options.push('padding')
-    }
+    let options = ['font', 'border', 'background', 'padding']
 
     MKEmitter.emit('changeStyle', options, config.headerStyle, this.getStyle)
   }
 
   render() {
     const { config, hideSearch } = this.props
-    // const { appType } = this.state
 
-    let title = config.plot ? config.plot.title : config.wrap.title
+    let title = ''
     let show = true
 
-    // if (!title && appType === 'mob' && config.type === 'card' && config.subtype === 'datacard' && config.action && config.action.length) {
-    //   title = ' '
-    // }
+    if (config.plot) {
+      title = config.plot.title
+    } else if (config.type === 'group') {
+      title = config.setting.title || ''
+    } else if (config.wrap) {
+      title = config.wrap.title || ''
+    }
 
     if (!title && (!config.search || config.search.length === 0 || hideSearch === 'true')) {
       show = false
diff --git a/src/menu/components/share/normalheader/index.scss b/src/menu/components/share/normalheader/index.scss
index b069a79..0d9f65f 100644
--- a/src/menu/components/share/normalheader/index.scss
+++ b/src/menu/components/share/normalheader/index.scss
@@ -6,6 +6,7 @@
   overflow: hidden;
   letter-spacing: 0px;
   line-height: 45px;
+  box-sizing: content-box;
 
   .title {
     text-decoration: inherit;
diff --git a/src/menu/components/table/edit-table/index.jsx b/src/menu/components/table/edit-table/index.jsx
index 30e4327..ecd404c 100644
--- a/src/menu/components/table/edit-table/index.jsx
+++ b/src/menu/components/table/edit-table/index.jsx
@@ -228,7 +228,7 @@
     style.fontSize = card.wrap.fontSize || 14
     style.fontWeight = card.wrap.fontWeight || 'normal'
 
-    MKEmitter.emit('changeStyle', ['font1', 'background', 'border', 'padding', 'margin', 'shadow'], style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['font1', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/table/normal-table/index.jsx b/src/menu/components/table/normal-table/index.jsx
index 767e8e9..cd6df52 100644
--- a/src/menu/components/table/normal-table/index.jsx
+++ b/src/menu/components/table/normal-table/index.jsx
@@ -280,7 +280,7 @@
     style.fontSize = card.wrap.fontSize || 14
     style.fontWeight = card.wrap.fontWeight || 'normal'
 
-    MKEmitter.emit('changeStyle', ['font1', 'background', 'border', 'padding', 'margin', 'shadow'], style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['font1', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/tabs/antv-tabs/index.jsx b/src/menu/components/tabs/antv-tabs/index.jsx
index c37b593..523c8b2 100644
--- a/src/menu/components/tabs/antv-tabs/index.jsx
+++ b/src/menu/components/tabs/antv-tabs/index.jsx
@@ -82,7 +82,7 @@
   changeStyle = () => {
     const { tabs } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], tabs.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], tabs.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/tabs/tabcomponents/card.jsx b/src/menu/components/tabs/tabcomponents/card.jsx
index 6a12eb0..5827eb9 100644
--- a/src/menu/components/tabs/tabcomponents/card.jsx
+++ b/src/menu/components/tabs/tabcomponents/card.jsx
@@ -61,6 +61,10 @@
     style = { opacity: 0.3}
   }
 
+  if (card.style && card.style.clear === 'left') {
+    style.clear = 'left'
+  }
+
   const getCardComponent = () => {
     if (card.type === 'bar' || card.type === 'line') {
       return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard} />)
diff --git a/src/menu/components/timeline/normal-timeline/index.jsx b/src/menu/components/timeline/normal-timeline/index.jsx
index 7dda5d2..165e8a9 100644
--- a/src/menu/components/timeline/normal-timeline/index.jsx
+++ b/src/menu/components/timeline/normal-timeline/index.jsx
@@ -166,7 +166,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/components/tree/antd-tree/index.jsx b/src/menu/components/tree/antd-tree/index.jsx
index 04211aa..3dd7abd 100644
--- a/src/menu/components/tree/antd-tree/index.jsx
+++ b/src/menu/components/tree/antd-tree/index.jsx
@@ -129,7 +129,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['height', 'background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/menu/menushell/card.jsx b/src/menu/menushell/card.jsx
index 6fd55a3..802a6c9 100644
--- a/src/menu/menushell/card.jsx
+++ b/src/menu/menushell/card.jsx
@@ -62,6 +62,10 @@
     style = { opacity: 0.3}
   }
 
+  if (card.style && card.style.clear === 'left') {
+    style.clear = 'left'
+  }
+
   const getCardComponent = () => {
     if (card.type === 'card' && card.subtype === 'datacard') {
       return (<DataCard card={card} updateConfig={updateConfig} deletecomponent={delCard}/>)
diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx
index 02ffba0..736abb5 100644
--- a/src/menu/stylecontroller/index.jsx
+++ b/src/menu/stylecontroller/index.jsx
@@ -897,6 +897,20 @@
                   </Form.Item>
                 </Col>
               </Panel> : null}
+              {options.includes('clear') ? <Panel header="娴姩" key="clear">
+                <Col span={24}>
+                  <Form.Item
+                    colon={false}
+                    label={<SwapOutlined title="娴姩"/>}
+                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
+                  >
+                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.clear || 'none'} onChange={(e) => this.changeNormalStyle(e.target.value, 'clear')}>
+                      <Radio value="none">宸︽诞鍔�</Radio>
+                      <Radio value="left">涓嶆诞鍔�</Radio>
+                    </Radio.Group>
+                  </Form.Item>
+                </Col>
+              </Panel> : null}
             </Collapse> : null}
           </Form>
           <div style={{textAlign: 'right'}}>
diff --git a/src/mob/colorsketch/index.jsx b/src/mob/colorsketch/index.jsx
index 21f544e..68d2965 100644
--- a/src/mob/colorsketch/index.jsx
+++ b/src/mob/colorsketch/index.jsx
@@ -47,7 +47,9 @@
       }
       
       _colors.forEach(item => {
-        colors.push(item.linkurl)
+        if (!colors.includes(item.linkurl)) {
+          colors.push(item.linkurl)
+        }
       })
     }
 
diff --git a/src/mob/components/menubar/common-menubar/index.jsx b/src/mob/components/menubar/common-menubar/index.jsx
index 37c24c3..fd5fd14 100644
--- a/src/mob/components/menubar/common-menubar/index.jsx
+++ b/src/mob/components/menubar/common-menubar/index.jsx
@@ -98,7 +98,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/mob/components/menubar/normal-menubar/index.jsx b/src/mob/components/menubar/normal-menubar/index.jsx
index a3ca2dc..df95f23 100644
--- a/src/mob/components/menubar/normal-menubar/index.jsx
+++ b/src/mob/components/menubar/normal-menubar/index.jsx
@@ -162,7 +162,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/mob/components/official/index.jsx b/src/mob/components/official/index.jsx
index 7a1c6d0..f5bcb14 100644
--- a/src/mob/components/official/index.jsx
+++ b/src/mob/components/official/index.jsx
@@ -75,7 +75,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   /**
diff --git a/src/mob/components/search/single-search/index.jsx b/src/mob/components/search/single-search/index.jsx
index b733a7c..43debf2 100644
--- a/src/mob/components/search/single-search/index.jsx
+++ b/src/mob/components/search/single-search/index.jsx
@@ -77,7 +77,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], card.style, this.getStyle)
   }
 
   /**
diff --git a/src/mob/components/tabs/antv-tabs/index.jsx b/src/mob/components/tabs/antv-tabs/index.jsx
index 9b75303..45181e1 100644
--- a/src/mob/components/tabs/antv-tabs/index.jsx
+++ b/src/mob/components/tabs/antv-tabs/index.jsx
@@ -88,7 +88,7 @@
   changeStyle = () => {
     const { tabs } = this.state
 
-    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow'], tabs.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['background', 'border', 'padding', 'margin', 'shadow', 'clear'], tabs.style, this.getStyle)
   }
 
   changeTabStyle = () => {
diff --git a/src/mob/components/tabs/tabcomponents/card.jsx b/src/mob/components/tabs/tabcomponents/card.jsx
index 2bc2cb0..700de18 100644
--- a/src/mob/components/tabs/tabcomponents/card.jsx
+++ b/src/mob/components/tabs/tabcomponents/card.jsx
@@ -60,6 +60,10 @@
     style = { opacity: 0.3}
   }
 
+  if (card.style && card.style.clear === 'left') {
+    style.clear = 'left'
+  }
+
   const getCardComponent = () => {
     if (card.type === 'bar' || card.type === 'line') {
       return (<AntvBar card={card} updateConfig={updateConfig} deletecomponent={delCard} />)
diff --git a/src/mob/mobshell/card.jsx b/src/mob/mobshell/card.jsx
index 50198c5..ab630e2 100644
--- a/src/mob/mobshell/card.jsx
+++ b/src/mob/mobshell/card.jsx
@@ -65,6 +65,10 @@
     style = { opacity: 0.3}
   }
 
+  if (card.style && card.style.clear === 'left') {
+    style.clear = 'left'
+  }
+
   let col = 'ant-col-' + (card.width || 24)
   if (card.type === 'login') {
     let height = ''
diff --git a/src/pc/components/login/normal-login/index.jsx b/src/pc/components/login/normal-login/index.jsx
index a35605f..286b250 100644
--- a/src/pc/components/login/normal-login/index.jsx
+++ b/src/pc/components/login/normal-login/index.jsx
@@ -114,7 +114,7 @@
   changeStyle = () => {
     const { card } = this.state
 
-    MKEmitter.emit('changeStyle', ['width', 'background', 'border', 'padding', 'margin'], card.style, this.getStyle)
+    MKEmitter.emit('changeStyle', ['width', 'background', 'border', 'padding', 'margin', 'clear'], card.style, this.getStyle)
   }
 
   getStyle = (style) => {
diff --git a/src/pc/menushell/card.jsx b/src/pc/menushell/card.jsx
index 0292f9e..c9b0756 100644
--- a/src/pc/menushell/card.jsx
+++ b/src/pc/menushell/card.jsx
@@ -63,6 +63,11 @@
   if (isDragging) {
     style = { opacity: 0.3}
   }
+
+  if (card.style && card.style.clear === 'left') {
+    style.clear = 'left'
+  }
+  
   let col = ' ant-col ant-col-' + (card.width || 24)
   if (card.type === 'login') {
     let height = ''
diff --git a/src/tabviews/custom/components/card/cardcellList/index.jsx b/src/tabviews/custom/components/card/cardcellList/index.jsx
index 0fa2b24..a0eb57b 100644
--- a/src/tabviews/custom/components/card/cardcellList/index.jsx
+++ b/src/tabviews/custom/components/card/cardcellList/index.jsx
@@ -229,6 +229,12 @@
     let contents = []
 
     elements.forEach(card => {
+      let _style_ = null
+
+      if (card.style && card.style.clear === 'left') {
+        _style_ = {clear: 'left'}
+      }
+
       if (card.eleType === 'sequence') {
         let _style = {}
         if (card.marks) {
@@ -241,7 +247,7 @@
           _style = mark.style
         }
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={card.style}>
               <div className="ant-mk-text line1" style={{height: card.innerHeight || 'auto'}}><span className="sequence-wrap" style={_style}>{data.$Index || ''}</span></div>
             </div>
@@ -379,7 +385,7 @@
         }
   
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={_style} onClick={(e) => {this.openNewView(e, card)}}>
               <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div>
             </div>
@@ -446,7 +452,7 @@
         }
   
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={_style}>
               <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div>
             </div>
@@ -484,7 +490,7 @@
         }
   
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={card.style}>
               {val ? <Tooltip title={val}>
                 <MkIcon className="ant-mk-icon" style={{height: height}} type={icon}/>
@@ -514,7 +520,7 @@
         }
   
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={card.style}>
               <MkProgress value={val} config={card} color={color}/>
             </div>
@@ -565,7 +571,7 @@
         let urls = url ? url.split(',').filter(Boolean) : ['']
 
         urls.forEach((u, i) => {
-          contents.push(<Col key={card.uuid + i} span={card.width}>
+          contents.push(<Col key={card.uuid + i} style={_style_} span={card.width}>
             <div style={_style} onClick={(e) => {this.openNewView(e, card)}}>
               <MkPicture style={_imagestyle} scale={scale} url={u} urls={urls}/>
             </div>
@@ -573,8 +579,10 @@
         })
       } else if (card.eleType === 'splitline') {
         let _borderWidth = card.borderWidth === undefined ? 1 : card.borderWidth
+        _style_ = _style_ || {}
+        _style_.minHeight = _borderWidth
         contents.push(
-          <Col key={card.uuid} span={card.width} style={{minHeight: _borderWidth}}>
+          <Col key={card.uuid} span={card.width} style={_style_}>
             <div style={card.style}>
               <div className="ant-mk-splitline" style={{borderColor: card.color, borderWidth: _borderWidth}}></div>
             </div>
@@ -594,7 +602,7 @@
         }
   
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={card.style}>
               <div style={{height: card.innerHeight || 25}}>
                 {val ? <BarCode card={card} value={val}/> : null}
@@ -627,7 +635,7 @@
   
         urls.forEach((u, i) => {
           contents.push(
-            <Col key={card.uuid + i} span={card.width}>
+            <Col key={card.uuid + i} style={_style_} span={card.width}>
               <div className="video-wrap" style={card.style}>
                 <Video card={card} poster={poster} value={u}/>
               </div>
@@ -648,7 +656,7 @@
         }
   
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={card.style}>
               <div style={{minHeight: card.qrWidth || 50}}>
                 {val ? <QrCode card={card} value={val}/> : null}
@@ -667,7 +675,7 @@
         }
   
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={card.style}>
               <div className="ant-mk-text line1" style={{height: card.innerHeight || 'auto'}}>{val}</div>
             </div>
@@ -752,7 +760,7 @@
         }
   
         contents.push(
-          <Col key={card.uuid} span={card.width}>
+          <Col key={card.uuid} style={_style_} span={card.width}>
             <div style={_style}>
               <div className={'ant-mk-text line' + (card.height || '')} style={{height: card.innerHeight || 'auto'}}>{val}</div>
             </div>
@@ -781,10 +789,15 @@
         } else if (data.$$empty) {
           _data = []
         }
+
+        _style_ = _style_ || {}
+        if (card.wrapStyle) {
+          _style_ = {..._style_, ...card.wrapStyle}
+        }
   
         if (['exec', 'prompt', 'pop', 'form'].includes(card.OpenType)) {
           contents.push(
-            <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
               <NormalButton
                 btn={card}
                 BID={data.$$BID}
@@ -798,7 +811,7 @@
           )
         } else if (card.OpenType === 'excelIn') {
           contents.push(
-            <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
               <ExcelInButton
                 btn={card}
                 BID={data.$$BID}
@@ -811,7 +824,7 @@
           )
         } else if (card.OpenType === 'excelOut') {
           contents.push(
-            <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
               <ExcelOutButton
                 btn={card}
                 BID={data.$$BID}
@@ -824,7 +837,7 @@
           )
         } else if (card.OpenType === 'popview') {
           contents.push(
-            <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
               <PopupButton
                 btn={card}
                 BID={data.$$BID}
@@ -837,7 +850,7 @@
           )
         } else if (card.OpenType === 'tab') {
           contents.push(
-            <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
               <TabButton
                 btn={card}
                 BID={data.$$BID}
@@ -849,7 +862,7 @@
           )
         } else if (card.OpenType === 'innerpage') {
           contents.push(
-            <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+            <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
               <NewPageButton
                 btn={card}
                 BData={data.$$BData || ''}
@@ -861,7 +874,7 @@
         } else if (card.OpenType === 'funcbutton') {
           if (card.funcType === 'changeuser' || card.funcType === 'closetab') {
             contents.push(
-              <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+              <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
                 <ChangeUserButton
                   btn={card}
                   BID={data.$$BID}
@@ -874,7 +887,7 @@
             )
           } else if (card.funcType === 'print') {
             contents.push(
-              <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+              <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
                 <PrintButton
                   btn={card}
                   BID={data.$$BID}
@@ -887,7 +900,7 @@
             )
           } else if (card.funcType === 'megvii') {
             contents.push(
-              <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+              <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
                 <FuncMegvii
                   btn={card}
                   BID={data.$$BID}
@@ -899,7 +912,7 @@
             )
           } else if (card.funcType === 'filezip') {
             contents.push(
-              <Col key={card.uuid} className="mk-cell-btn" style={card.wrapStyle} span={card.width}>
+              <Col key={card.uuid} className="mk-cell-btn" style={_style_} span={card.width}>
                 <FuncZip
                   btn={card}
                   BID={data.$$BID}
diff --git a/src/tabviews/custom/components/carousel/data-card/index.jsx b/src/tabviews/custom/components/carousel/data-card/index.jsx
index 27b0c7e..977fea5 100644
--- a/src/tabviews/custom/components/carousel/data-card/index.jsx
+++ b/src/tabviews/custom/components/carousel/data-card/index.jsx
@@ -173,12 +173,13 @@
     
     if (config.wrap.display !== 'modal' || !data || data.length === 0) return
 
-    let tip = localStorage.getItem('modal' + config.uuid)
+    let code = config.wrap.code || ('modal' + config.uuid)
+    let tip = localStorage.getItem(code)
 
     if (!data[0].$$uuid || tip === data[0].$$uuid + data.length) return
 
     if (config.wrap.modalContent === 'update') {
-      localStorage.setItem('modal' + config.uuid, data[0].$$uuid + data.length)
+      localStorage.setItem(code, data[0].$$uuid + data.length)
 
       Api.getAppVersion(true)
     }
@@ -305,10 +306,11 @@
   onTipChange = (e) => {
     const { config, data } = this.state
 
+    let code = config.wrap.code || ('modal' + config.uuid)
     if (e.target.checked) {
-      localStorage.setItem('modal' + config.uuid, data[0].$$uuid + data.length)
+      localStorage.setItem(code, data[0].$$uuid + data.length)
     } else {
-      localStorage.removeItem('modal' + config.uuid)
+      localStorage.removeItem(code)
     }
   }
 
diff --git a/src/tabviews/custom/components/carousel/prop-card/index.jsx b/src/tabviews/custom/components/carousel/prop-card/index.jsx
index d7ecadf..212ca06 100644
--- a/src/tabviews/custom/components/carousel/prop-card/index.jsx
+++ b/src/tabviews/custom/components/carousel/prop-card/index.jsx
@@ -176,12 +176,13 @@
   openModal = () => {
     const { config, data } = this.state
     
-    let tip = localStorage.getItem('modal' + config.uuid)
+    let code = config.wrap.code || ('modal' + config.uuid)
+    let tip = localStorage.getItem(code)
 
     if ((data.$$uuid && tip === data.$$uuid) || (!data.$$uuid && tip)) return
 
     if (config.wrap.modalContent === 'update') {
-      localStorage.setItem('modal' + config.uuid, data.$$uuid || 'true')
+      localStorage.setItem(code, data.$$uuid || 'true')
 
       Api.getAppVersion(true)
     }
@@ -328,10 +329,11 @@
   onTipChange = (e) => {
     const { config, data } = this.state
 
+    let code = config.wrap.code || ('modal' + config.uuid)
     if (e.target.checked) {
-      localStorage.setItem('modal' + config.uuid, data.$$uuid || 'true')
+      localStorage.setItem(code, data.$$uuid || 'true')
     } else {
-      localStorage.removeItem('modal' + config.uuid)
+      localStorage.removeItem(code)
     }
   }
 
diff --git a/src/tabviews/custom/components/group/normal-group/index.jsx b/src/tabviews/custom/components/group/normal-group/index.jsx
index 7b4346e..ac0cc08 100644
--- a/src/tabviews/custom/components/group/normal-group/index.jsx
+++ b/src/tabviews/custom/components/group/normal-group/index.jsx
@@ -139,123 +139,129 @@
     const { mainSearch, data } = this.state
 
     return config.components.map(item => {
-      if (item.type === 'bar' || item.type === 'line') {
+      let style = null
+
+      if (item.style && item.style.clear === 'left') {
+        style = {clear: 'left'}
+      }
+
+      if (item.type === 'card' && item.subtype === 'datacard') {
         return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvBarAndLine data={data} config={item} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'pie') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvPie data={data} config={item} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'dashboard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvDashboard config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'form' && item.subtype === 'simpleform') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <SimpleForm config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'form' && item.subtype === 'stepform') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <NormalForm config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'form' && item.subtype === 'tabform') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <TabForm config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'scatter') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvScatter config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'carousel' && item.subtype === 'datacard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <CarouselDataCard config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'carousel' && item.subtype === 'propcard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <CarouselPropCard config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'card' && item.subtype === 'datacard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <DataCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'propcard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <PropCard config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'card' && item.subtype === 'tablecard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <TableCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'normaltable') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalTable config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'bar' || item.type === 'line') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvBarAndLine data={data} config={item} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'pie') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvPie data={data} config={item} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'dashboard') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvDashboard config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'form' && item.subtype === 'simpleform') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <SimpleForm config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'form' && item.subtype === 'stepform') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <NormalForm config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'form' && item.subtype === 'tabform') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <TabForm config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'scatter') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvScatter config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'carousel' && item.subtype === 'datacard') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <CarouselDataCard config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'carousel' && item.subtype === 'propcard') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <CarouselPropCard config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'card' && item.subtype === 'tablecard') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <TableCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'editable') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <EditTable config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'tree') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalTree config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'editor') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <BraftEditor config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'code') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <SandBox config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'balcony') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <Balcony config={item} data={data}/>
           </Col>
         )
       } else if (item.type === 'timeline') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TimeLine config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'chart') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CustomChart config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
@@ -265,12 +271,32 @@
     })
   }
 
+  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
 
     if (printing) return
     this.setState({printing: true})
+
+    let qrcodes = document.getElementsByClassName('qrcode-box')
+
+    for (let i = 0; i < qrcodes.length; i++) {
+      let canvas = qrcodes[i].getElementsByTagName('canvas')[0]
+
+      if (canvas) {
+        let img = this.canvasToImage(canvas)
+  
+        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'
@@ -345,6 +371,9 @@
     
     return (
       <div className={'normal-group-wrap ' + (config.setting.layout || '')} id={config.uuid} style={config.style}>
+        {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}
         <Row className="component-wrap">{this.getComponents()}</Row>
       </div>
diff --git a/src/tabviews/custom/components/group/normal-group/index.scss b/src/tabviews/custom/components/group/normal-group/index.scss
index 419bf1b..a179389 100644
--- a/src/tabviews/custom/components/group/normal-group/index.scss
+++ b/src/tabviews/custom/components/group/normal-group/index.scss
@@ -7,6 +7,28 @@
     border: 0;
     background: transparent;
   }
+
+  .group-header {
+    position: relative;
+    height: 45px;
+    padding-right: 8px;
+    border-bottom: 1px solid #e8e8e8;
+    overflow: hidden;
+    letter-spacing: 0px;
+    line-height: 45px;
+    box-sizing: content-box;
+  
+    .title {
+      text-decoration: inherit;
+      font-weight: inherit;
+      font-style: inherit;
+      float: left;
+      line-height: inherit;
+      margin-left: 10px;
+      position: relative;
+      z-index: 1;
+    }
+  }
 }
 
 .normal-group-wrap::after {
diff --git a/src/tabviews/custom/components/share/normalheader/index.scss b/src/tabviews/custom/components/share/normalheader/index.scss
index e961d6e..8816fb1 100644
--- a/src/tabviews/custom/components/share/normalheader/index.scss
+++ b/src/tabviews/custom/components/share/normalheader/index.scss
@@ -6,6 +6,7 @@
   overflow: hidden;
   letter-spacing: 0px;
   line-height: 45px;
+  box-sizing: content-box;
 
   .title {
     text-decoration: inherit;
diff --git a/src/tabviews/custom/components/share/tabtransfer/index.jsx b/src/tabviews/custom/components/share/tabtransfer/index.jsx
index 9d7b3ff..2df9942 100644
--- a/src/tabviews/custom/components/share/tabtransfer/index.jsx
+++ b/src/tabviews/custom/components/share/tabtransfer/index.jsx
@@ -168,27 +168,51 @@
     if (!config || !config.components || config.components.length === 0) return (<Empty description={false} />)
 
     return config.components.map(item => {
-      if (item.type === 'bar' || item.type === 'line') {
+      let style = null
+
+      if (item.style && item.style.clear === 'left') {
+        style = {clear: 'left'}
+      }
+
+      if (item.type === 'card' && item.subtype === 'datacard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
+            <DataCard config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'card' && item.subtype === 'propcard') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <PropCard config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'table' && item.subtype === 'normaltable') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <NormalTable config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'bar' || item.type === 'line') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvBarAndLine data={data} config={item} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'pie') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvPie data={data} config={item} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'dashboard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvDashboard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'scatter') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvScatter config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
@@ -199,121 +223,103 @@
           BID = BData.$BID || ''
         }
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <MainSearch config={item} BID={BID} refreshdata={this.resetSearch} />
           </Col>
         )
       } else if (item.type === 'tabs') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvTabs config={item} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'card' && item.subtype === 'datacard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <DataCard config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'card' && item.subtype === 'propcard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <PropCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'datacard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CarouselDataCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'propcard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CarouselPropCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'tablecard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TableCard config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'table' && item.subtype === 'normaltable') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <NormalTable config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'basetable') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <MkBaseTable config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'editable') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <EditTable config={item} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'group' && item.subtype === 'normalgroup') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalGroup config={item} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'simpleform') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <SimpleForm config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'stepform') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <StepForm config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'tabform') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TabForm config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'tree') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalTree config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'editor') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <BraftEditor config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'code') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <SandBox config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'balcony') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <Balcony config={item} data={data}/>
           </Col>
         )
       } else if (item.type === 'timeline') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TimeLine config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'chart') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CustomChart config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
diff --git a/src/tabviews/custom/index.jsx b/src/tabviews/custom/index.jsx
index dc04460..71d0a07 100644
--- a/src/tabviews/custom/index.jsx
+++ b/src/tabviews/custom/index.jsx
@@ -1090,147 +1090,153 @@
     if (!config || !config.components) return
 
     return config.components.map(item => {
-      if (item.type === 'bar' || item.type === 'line') {
+      let style = null
+
+      if (item.style && item.style.clear === 'left') {
+        style = {clear: 'left'}
+      }
+
+      if (item.type === 'card' && item.subtype === 'datacard') {
         return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvBarAndLine config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'pie') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvPie config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'scatter') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvScatter config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'dashboard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvDashboard config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'form' && item.subtype === 'simpleform') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <SimpleForm config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'form' && item.subtype === 'stepform') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <StepForm config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'form' && item.subtype === 'tabform') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <TabForm config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'search') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <MainSearch config={item} BID={BID} refreshdata={this.resetSearch} />
-          </Col>
-        )
-      } else if (item.type === 'tabs') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <AntvTabs config={item} mainSearch={mainSearch} />
-          </Col>
-        )
-      } else if (item.type === 'card' && item.subtype === 'datacard') {
-        return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <DataCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'propcard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <PropCard config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'table' && item.subtype === 'normaltable') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <NormalTable config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'bar' || item.type === 'line') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvBarAndLine config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'pie') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvPie config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'scatter') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvScatter config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'dashboard') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvDashboard config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'form' && item.subtype === 'simpleform') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <SimpleForm config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'form' && item.subtype === 'stepform') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <StepForm config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'form' && item.subtype === 'tabform') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <TabForm config={item} data={data} mainSearch={mainSearch}/>
+          </Col>
+        )
+      } else if (item.type === 'search') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <MainSearch config={item} BID={BID} refreshdata={this.resetSearch} />
+          </Col>
+        )
+      } else if (item.type === 'tabs') {
+        return (
+          <Col span={item.width} style={style} key={item.uuid}>
+            <AntvTabs config={item} mainSearch={mainSearch} />
           </Col>
         )
       } else if (item.type === 'balcony') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <Balcony config={item} data={data}/>
           </Col>
         )
       } else if (item.type === 'timeline') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TimeLine config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'datacard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CarouselDataCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'propcard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CarouselPropCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'tablecard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TableCard config={item} data={data} mainSearch={mainSearch}/>
-          </Col>
-        )
-      } else if (item.type === 'table' && item.subtype === 'normaltable') {
-        return (
-          <Col span={item.width} key={item.uuid}>
-            <NormalTable config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'editable') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <EditTable config={item} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'group' && item.subtype === 'normalgroup') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalGroup config={item} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'editor') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <BraftEditor config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'tree') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalTree config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'code') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <SandBox config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'chart') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CustomChart config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'module' && item.subtype === 'voucher') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <Voucher config={item}/>
           </Col>
         )
diff --git a/src/tabviews/custom/popview/index.jsx b/src/tabviews/custom/popview/index.jsx
index 2bec782..79bbc12 100644
--- a/src/tabviews/custom/popview/index.jsx
+++ b/src/tabviews/custom/popview/index.jsx
@@ -831,153 +831,159 @@
     if (!config) return
 
     return config.components.map(item => {
+      let style = null
+
+      if (item.style && item.style.clear === 'left') {
+        style = {clear: 'left'}
+      }
+
       if (item.type === 'card' && item.subtype === 'datacard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <DataCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'propcard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <PropCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'basetable') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <BaseTable config={item}/>
           </Col>
         )
       } else if (item.type === 'bar' || item.type === 'line') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvBarAndLine config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'pie') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvPie config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'scatter') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvScatter config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'dashboard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvDashboard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'simpleform') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <SimpleForm config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'stepform') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <StepForm config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'form' && item.subtype === 'tabform') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TabForm config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'search') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <MainSearch config={item} BID={BID} refreshdata={this.resetSearch} />
           </Col>
         )
       } else if (item.type === 'tabs') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <AntvTabs config={item} mainSearch={mainSearch} />
           </Col>
         )
       } else if (item.type === 'balcony') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <Balcony config={item} data={data}/>
           </Col>
         )
       } else if (item.type === 'timeline') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TimeLine config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'datacard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CarouselDataCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'carousel' && item.subtype === 'propcard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CarouselPropCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'card' && item.subtype === 'tablecard') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <TableCard config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'normaltable') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalTable config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'table' && item.subtype === 'editable') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <EditTable config={item} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'group' && item.subtype === 'normalgroup') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalGroup config={item} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'editor') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <BraftEditor config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'tree') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <NormalTree config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'code') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <SandBox config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'chart') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <CustomChart config={item} data={data} mainSearch={mainSearch}/>
           </Col>
         )
       } else if (item.type === 'module' && item.subtype === 'voucher') {
         return (
-          <Col span={item.width} key={item.uuid}>
+          <Col span={item.width} style={style} key={item.uuid}>
             <Voucher config={item}/>
           </Col>
         )

--
Gitblit v1.8.0