@electerm/electerm-react 1.40.20 → 1.50.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/client/common/constants.js +57 -7
  2. package/client/common/new-terminal.js +2 -2
  3. package/client/components/auth/login.jsx +34 -57
  4. package/client/components/batch-op/batch-op.jsx +12 -11
  5. package/client/components/bookmark-form/index.jsx +2 -2
  6. package/client/components/bookmark-form/ssh-form.jsx +4 -1
  7. package/client/components/bookmark-form/tree-delete.jsx +5 -5
  8. package/client/components/context-menu/boomarks.jsx +8 -12
  9. package/client/components/context-menu/context-menu.jsx +10 -10
  10. package/client/components/context-menu/history.jsx +21 -24
  11. package/client/components/context-menu/menu-btn.jsx +11 -11
  12. package/client/components/context-menu/tabs.jsx +15 -19
  13. package/client/components/context-menu/zoom.jsx +25 -29
  14. package/client/components/footer/footer-entry.jsx +56 -56
  15. package/client/components/icons/split-icons.jsx +77 -0
  16. package/client/components/layout/layout-alg.js +260 -0
  17. package/client/components/layout/layout-item.jsx +26 -0
  18. package/client/components/layout/layout.jsx +167 -0
  19. package/client/components/layout/layout.styl +5 -0
  20. package/client/components/layout/layouts.jsx +71 -0
  21. package/client/components/layout/session-size-alg.js +31 -0
  22. package/client/components/main/main.jsx +183 -109
  23. package/client/components/main/wrapper.styl +2 -4
  24. package/client/components/profile/profile-list.jsx +1 -3
  25. package/client/components/profile/profile-transport-mod.jsx +1 -1
  26. package/client/components/profile/profile-transport.jsx +6 -9
  27. package/client/components/quick-commands/quick-command-transport.jsx +6 -9
  28. package/client/components/quick-commands/quick-commands-box.jsx +144 -153
  29. package/client/components/quick-commands/quick-commands-select.jsx +10 -3
  30. package/client/components/rdp/rdp-session.jsx +3 -23
  31. package/client/components/rdp/resolution-edit.jsx +40 -42
  32. package/client/components/session/session.jsx +62 -317
  33. package/client/components/session/session.styl +1 -5
  34. package/client/components/session/sessions.jsx +99 -105
  35. package/client/components/setting-panel/bookmark-tree-list.jsx +1 -1
  36. package/client/components/setting-panel/setting-common.jsx +6 -4
  37. package/client/components/setting-panel/setting-modal.jsx +31 -31
  38. package/client/components/setting-panel/start-session-select.jsx +4 -4
  39. package/client/components/setting-panel/tab-settings.jsx +27 -5
  40. package/client/components/setting-sync/data-import.jsx +36 -39
  41. package/client/components/setting-sync/setting-sync-form.jsx +9 -9
  42. package/client/components/setting-sync/setting-sync.jsx +50 -52
  43. package/client/components/sftp/address-bookmark.jsx +57 -58
  44. package/client/components/sftp/confirm-modal-store.jsx +34 -40
  45. package/client/components/sftp/file-item.jsx +14 -3
  46. package/client/components/sftp/file-mode-modal.jsx +3 -0
  47. package/client/components/sftp/list-table-ui.jsx +4 -4
  48. package/client/components/sftp/sftp-entry.jsx +2 -2
  49. package/client/components/sftp/transfer-conflict-store.jsx +13 -17
  50. package/client/components/sftp/transport-action-store.jsx +38 -31
  51. package/client/components/sftp/transports-action-store.jsx +3 -3
  52. package/client/components/sftp/transports-ui-store.jsx +18 -23
  53. package/client/components/shortcuts/shortcut-handler.js +1 -0
  54. package/client/components/shortcuts/shortcuts.jsx +9 -12
  55. package/client/components/side-panel-r/right-side-panel.styl +40 -0
  56. package/client/components/side-panel-r/side-panel-r.jsx +102 -0
  57. package/client/components/sidebar/bookmark-select.jsx +40 -40
  58. package/client/components/sidebar/bookmark.jsx +63 -65
  59. package/client/components/sidebar/history.jsx +53 -50
  60. package/client/components/sidebar/index.jsx +195 -184
  61. package/client/components/sidebar/info-modal.jsx +202 -202
  62. package/client/components/sidebar/sidebar.styl +8 -2
  63. package/client/components/sidebar/transfer-history-modal.jsx +95 -100
  64. package/client/components/sidebar/transfer-list-control.jsx +2 -2
  65. package/client/components/sidebar/transfer-list.jsx +45 -42
  66. package/client/components/sidebar/transfer-modal.jsx +49 -52
  67. package/client/components/sidebar/transport-ui.jsx +1 -1
  68. package/client/components/tabs/index.jsx +261 -49
  69. package/client/components/tabs/tab.jsx +60 -65
  70. package/client/components/tabs/tabs.styl +6 -1
  71. package/client/components/tabs/window-control.jsx +46 -48
  72. package/client/components/terminal/index.jsx +101 -104
  73. package/client/components/terminal/term-search.jsx +26 -24
  74. package/client/components/terminal-info/run-cmd.jsx +0 -25
  75. package/client/components/terminal-info/terminal-info.jsx +60 -0
  76. package/client/components/terminal-info/terminal-info.styl +1 -1
  77. package/client/components/tree-list/bookmark-transport.jsx +8 -9
  78. package/client/components/tree-list/tree-list.jsx +36 -26
  79. package/client/components/vnc/vnc-session.jsx +1 -6
  80. package/client/store/common.js +1 -1
  81. package/client/store/event.js +2 -2
  82. package/client/store/index.js +21 -32
  83. package/client/store/init-state.js +15 -3
  84. package/client/store/load-data.js +1 -1
  85. package/client/store/quick-command.js +4 -4
  86. package/client/store/session.js +1 -1
  87. package/client/store/setting.js +9 -5
  88. package/client/store/system-menu.js +1 -10
  89. package/client/store/tab.js +66 -1
  90. package/client/store/transfer-list.js +5 -6
  91. package/client/store/watch.js +11 -6
  92. package/package.json +1 -1
  93. package/client/components/common/react-subx.jsx +0 -1
  94. package/client/components/common/resize-wrap.jsx +0 -222
  95. package/client/components/common/resize-wrap.styl +0 -9
  96. package/client/components/terminal-info/content.jsx +0 -152
@@ -1,4 +1,3 @@
1
- import { Component } from '../common/react-subx'
2
1
  import InputNumberConfirm from '../common/input-confirm'
3
2
 
4
3
  import {
@@ -6,35 +5,32 @@ import {
6
5
  PlusCircleOutlined
7
6
  } from '@ant-design/icons'
8
7
 
9
- export default class ZoomMenu extends Component {
10
- handleChange = (v) => {
11
- const { store } = this.props
8
+ export default function ZoomMenu (props) {
9
+ const { store } = window
10
+ const handleChange = (v) => {
12
11
  store.zoom(v / 100)
13
12
  }
14
13
 
15
- render () {
16
- const { store } = this.props
17
- return (
18
- <InputNumberConfirm
19
- value={parseInt(store.config.zoom * 100, 10)}
20
- onChange={this.handleChange}
21
- step={1}
22
- min={25}
23
- max={500}
24
- addonAfter='%'
25
- addonBefore={
26
- <div>
27
- <PlusCircleOutlined
28
- onClick={() => store.zoom(0.25, true)}
29
- className='mg1r pointer font16'
30
- />
31
- <MinusCircleOutlined
32
- onClick={() => store.zoom(-0.25, true)}
33
- className='pointer font16'
34
- />
35
- </div>
36
- }
37
- />
38
- )
39
- }
14
+ return (
15
+ <InputNumberConfirm
16
+ value={parseInt(props.config.zoom * 100, 10)}
17
+ onChange={handleChange}
18
+ step={1}
19
+ min={25}
20
+ max={500}
21
+ addonAfter='%'
22
+ addonBefore={
23
+ <div>
24
+ <PlusCircleOutlined
25
+ onClick={() => store.zoom(0.25, true)}
26
+ className='mg1r pointer font16'
27
+ />
28
+ <MinusCircleOutlined
29
+ onClick={() => store.zoom(-0.25, true)}
30
+ className='pointer font16'
31
+ />
32
+ </div>
33
+ }
34
+ />
35
+ )
40
36
  }
@@ -1,4 +1,4 @@
1
- import { Component } from '../common/react-subx'
1
+ import { auto } from 'manate/react'
2
2
  import {
3
3
  Select
4
4
  } from 'antd'
@@ -16,36 +16,35 @@ const {
16
16
 
17
17
  const e = window.translate
18
18
 
19
- export default class FooterEntry extends Component {
20
- handleInfoPanel = () => {
21
- const { activeTerminalId } = this.props.store
19
+ export default auto(function FooterEntry (props) {
20
+ function handleInfoPanel () {
21
+ const { store } = window
22
+ store.rightPanelVisible = !store.rightPanelVisible
22
23
  postMessage({
23
24
  action: terminalActions.showInfoPanel,
24
- activeSplitId: activeTerminalId
25
+ currentTabId: store.currentTabId
25
26
  })
26
27
  }
27
28
 
28
- batchInput = (cmd, toAll) => {
29
- const { activeTerminalId } = this.props.store
29
+ function batchInput (cmd, toAll) {
30
30
  postMessage({
31
31
  action: terminalActions.batchInput,
32
- activeSplitId: activeTerminalId,
32
+ currentTabId: props.store.currentTabId,
33
33
  toAll,
34
34
  cmd
35
35
  })
36
36
  }
37
37
 
38
- handleSwitchEncoding = encode => {
39
- const { activeTerminalId } = this.props.store
38
+ function handleSwitchEncoding (encode) {
40
39
  postMessage({
41
40
  encode,
42
41
  action: terminalActions.changeEncode,
43
- activeSplitId: activeTerminalId
42
+ currentTabId: props.store.currentTabId
44
43
  })
45
44
  }
46
45
 
47
- isLoading = () => {
48
- const { currentTab } = this.props.store
46
+ function isLoading () {
47
+ const { currentTab } = props.store
49
48
  if (!currentTab) {
50
49
  return true
51
50
  }
@@ -55,18 +54,18 @@ export default class FooterEntry extends Component {
55
54
  return status !== statusMap.success
56
55
  }
57
56
 
58
- renderBatchInputs () {
57
+ function renderBatchInputs () {
59
58
  return (
60
59
  <div className='terminal-footer-unit terminal-footer-center'>
61
60
  <BatchInput
62
- input={this.batchInput}
63
- batchInputs={this.props.store.batchInputs}
61
+ input={batchInput}
62
+ batchInputs={props.store.batchInputs}
64
63
  />
65
64
  </div>
66
65
  )
67
66
  }
68
67
 
69
- renderQuickCommands () {
68
+ function renderQuickCommands () {
70
69
  return (
71
70
  <div className='terminal-footer-unit terminal-footer-qm'>
72
71
  <Qm />
@@ -74,14 +73,14 @@ export default class FooterEntry extends Component {
74
73
  )
75
74
  }
76
75
 
77
- renderEncodingInfo () {
76
+ function renderEncodingInfo () {
78
77
  const selectProps = {
79
78
  style: {
80
79
  minWidth: 30
81
80
  },
82
81
  placeholder: e('encode'),
83
- defaultValue: this.props.currentTab?.encode,
84
- onSelect: this.handleSwitchEncoding,
82
+ defaultValue: props.currentTab?.encode,
83
+ onSelect: handleSwitchEncoding,
85
84
  size: 'small',
86
85
  popupMatchSelectWidth: false
87
86
  }
@@ -106,54 +105,55 @@ export default class FooterEntry extends Component {
106
105
  )
107
106
  }
108
107
 
109
- renderInfoIcon () {
110
- const loading = this.isLoading()
108
+ function renderInfoIcon () {
109
+ const loading = isLoading()
111
110
  if (loading) {
112
111
  return null
113
112
  }
114
113
  return (
115
114
  <div className='terminal-footer-unit terminal-footer-info'>
116
115
  <InfoCircleOutlined
117
- onClick={this.handleInfoPanel}
116
+ onClick={handleInfoPanel}
118
117
  className='pointer font18 terminal-info-icon'
119
118
  />
120
119
  </div>
121
120
  )
122
121
  }
123
122
 
124
- render () {
125
- const { tabs, leftSidebarWidth, openedSideBar } = this.props.store
126
- const pane = this.props.store.currentTab?.pane
127
- const type = this.props.store.currentTab?.type
128
- if (
129
- type === 'rdp' ||
130
- type === 'web' ||
131
- type === 'vnc' ||
132
- pane === paneMap.fileManager ||
133
- !tabs.length
134
- ) {
135
- return null
136
- }
137
- const w = 43 + leftSidebarWidth
138
- const sideProps = openedSideBar
139
- ? {
140
- className: 'main-footer',
141
- style: {
142
- left: `${w}px`
143
- }
144
- }
145
- : {
146
- className: 'main-footer'
147
- }
123
+ const { tabs, leftSidebarWidth, openedSideBar, currentTab } = props.store
124
+ const pane = currentTab?.pane
125
+ const type = currentTab?.type
126
+ if (
127
+ type === 'rdp' ||
128
+ type === 'web' ||
129
+ type === 'vnc' ||
130
+ pane === paneMap.fileManager ||
131
+ pane === paneMap.sftp ||
132
+ !tabs.length
133
+ ) {
148
134
  return (
149
- <div {...sideProps}>
150
- <div className='terminal-footer-flex'>
151
- {this.renderQuickCommands()}
152
- {this.renderBatchInputs()}
153
- {this.renderEncodingInfo()}
154
- {this.renderInfoIcon()}
155
- </div>
156
- </div>
135
+ <div className='main-footer' />
157
136
  )
158
137
  }
159
- }
138
+ const w = 43 + leftSidebarWidth
139
+ const sideProps = openedSideBar
140
+ ? {
141
+ className: 'main-footer',
142
+ style: {
143
+ left: `${w}px`
144
+ }
145
+ }
146
+ : {
147
+ className: 'main-footer'
148
+ }
149
+ return (
150
+ <div {...sideProps}>
151
+ <div className='terminal-footer-flex'>
152
+ {renderQuickCommands()}
153
+ {renderBatchInputs()}
154
+ {renderEncodingInfo()}
155
+ {renderInfoIcon()}
156
+ </div>
157
+ </div>
158
+ )
159
+ })
@@ -0,0 +1,77 @@
1
+ import Icon from '@ant-design/icons'
2
+
3
+ const singleSvg = () => (
4
+ <svg width='1em' height='1em' viewBox='0 0 24 24'>
5
+ <rect x='2' y='2' width='20' height='20' fill='none' stroke='currentColor' strokeWidth='2' />
6
+ </svg>
7
+ )
8
+
9
+ // Two Columns (c2)
10
+ const twoColumnsSvg = () => (
11
+ <svg width='1em' height='1em' viewBox='0 0 24 24'>
12
+ <rect x='2' y='2' width='20' height='20' fill='none' stroke='currentColor' strokeWidth='2' />
13
+ <line x1='12' y1='2' x2='12' y2='22' stroke='currentColor' strokeWidth='2' />
14
+ </svg>
15
+ )
16
+
17
+ // Three Columns (c3)
18
+ const threeColumnsSvg = () => (
19
+ <svg width='1em' height='1em' viewBox='0 0 24 24'>
20
+ <rect x='2' y='2' width='20' height='20' fill='none' stroke='currentColor' strokeWidth='2' />
21
+ <line x1='8' y1='2' x2='8' y2='22' stroke='currentColor' strokeWidth='2' />
22
+ <line x1='16' y1='2' x2='16' y2='22' stroke='currentColor' strokeWidth='2' />
23
+ </svg>
24
+ )
25
+
26
+ // Two Rows (r2)
27
+ const twoRowsSvg = () => (
28
+ <svg width='1em' height='1em' viewBox='0 0 24 24'>
29
+ <rect x='2' y='2' width='20' height='20' fill='none' stroke='currentColor' strokeWidth='2' />
30
+ <line x1='2' y1='12' x2='22' y2='12' stroke='currentColor' strokeWidth='2' />
31
+ </svg>
32
+ )
33
+
34
+ // Three Rows (r3)
35
+ const threeRowsSvg = () => (
36
+ <svg width='1em' height='1em' viewBox='0 0 24 24'>
37
+ <rect x='2' y='2' width='20' height='20' fill='none' stroke='currentColor' strokeWidth='2' />
38
+ <line x1='2' y1='8' x2='22' y2='8' stroke='currentColor' strokeWidth='2' />
39
+ <line x1='2' y1='16' x2='22' y2='16' stroke='currentColor' strokeWidth='2' />
40
+ </svg>
41
+ )
42
+
43
+ // Grid 2x2 (2x2)
44
+ const grid2x2Svg = () => (
45
+ <svg width='1em' height='1em' viewBox='0 0 24 24'>
46
+ <rect x='2' y='2' width='20' height='20' fill='none' stroke='currentColor' strokeWidth='2' />
47
+ <line x1='12' y1='2' x2='12' y2='22' stroke='currentColor' strokeWidth='2' />
48
+ <line x1='2' y1='12' x2='22' y2='12' stroke='currentColor' strokeWidth='2' />
49
+ </svg>
50
+ )
51
+
52
+ // Two Rows Right (1x2r)
53
+ const twoRowsRightSvg = () => (
54
+ <svg width='1em' height='1em' viewBox='0 0 24 24'>
55
+ <rect x='2' y='2' width='20' height='20' fill='none' stroke='currentColor' strokeWidth='2' />
56
+ <line x1='12' y1='2' x2='12' y2='22' stroke='currentColor' strokeWidth='2' />
57
+ <line x1='12' y1='12' x2='22' y2='12' stroke='currentColor' strokeWidth='2' />
58
+ </svg>
59
+ )
60
+
61
+ // Two Columns Bottom (1x1c)
62
+ const twoColumnsBottomSvg = () => (
63
+ <svg width='1em' height='1em' viewBox='0 0 24 24'>
64
+ <rect x='2' y='2' width='20' height='20' fill='none' stroke='currentColor' strokeWidth='2' />
65
+ <line x1='2' y1='12' x2='22' y2='12' stroke='currentColor' strokeWidth='2' />
66
+ <line x1='12' y1='12' x2='12' y2='22' stroke='currentColor' strokeWidth='2' />
67
+ </svg>
68
+ )
69
+
70
+ export const SingleIcon = props => (<Icon component={singleSvg} {...props} />)
71
+ export const TwoColumnsIcon = props => (<Icon component={twoColumnsSvg} {...props} />)
72
+ export const ThreeColumnsIcon = props => (<Icon component={threeColumnsSvg} {...props} />)
73
+ export const TwoRowsIcon = props => (<Icon component={twoRowsSvg} {...props} />)
74
+ export const ThreeRowsIcon = props => (<Icon component={threeRowsSvg} {...props} />)
75
+ export const Grid2x2Icon = props => (<Icon component={grid2x2Svg} {...props} />)
76
+ export const TwoRowsRightIcon = props => (<Icon component={twoRowsRightSvg} {...props} />)
77
+ export const TwoColumnsBottomIcon = props => (<Icon component={twoColumnsBottomSvg} {...props} />)
@@ -0,0 +1,260 @@
1
+ import {
2
+ splitMap
3
+ } from '../../common/constants'
4
+
5
+ const layoutSingle = (w, h) => ({
6
+ wrapStyles: [
7
+ {
8
+ left: 0,
9
+ top: 0,
10
+ bottom: 0,
11
+ right: 0
12
+ }
13
+ ],
14
+ handleStyles: []
15
+ })
16
+
17
+ const layoutTwoColumns = (w, h) => ({
18
+ wrapStyles: [
19
+ {
20
+ left: 0,
21
+ top: 0,
22
+ bottom: 0,
23
+ right: (w / 2 - 2) + 'px'
24
+ },
25
+ {
26
+ left: (w / 2 + 2) + 'px',
27
+ top: 0,
28
+ bottom: 0,
29
+ right: 0
30
+ }
31
+ ],
32
+ handleStyles: [
33
+ {
34
+ left: (w / 2 - 2) + 'px',
35
+ top: 0,
36
+ bottom: 0
37
+ }
38
+ ]
39
+ })
40
+
41
+ const layoutThreeColumns = (w, h) => ({
42
+ wrapStyles: [
43
+ {
44
+ left: 0,
45
+ top: 0,
46
+ bottom: 0,
47
+ right: (2 * w / 3 - 2) + 'px'
48
+ },
49
+ {
50
+ left: (w / 3 + 2) + 'px',
51
+ top: 0,
52
+ bottom: 0,
53
+ right: (w / 3 - 2) + 'px'
54
+ },
55
+ {
56
+ left: (2 * w / 3 + 2) + 'px',
57
+ top: 0,
58
+ bottom: 0,
59
+ right: 0
60
+ }
61
+ ],
62
+ handleStyles: [
63
+ {
64
+ left: (w / 3 - 2) + 'px',
65
+ top: 0,
66
+ bottom: 0
67
+ },
68
+ {
69
+ left: (2 * w / 3 - 2) + 'px',
70
+ top: 0,
71
+ bottom: 0
72
+ }
73
+ ]
74
+ })
75
+
76
+ const layoutTwoRows = (w, h) => ({
77
+ wrapStyles: [
78
+ {
79
+ left: 0,
80
+ top: 0,
81
+ right: 0,
82
+ bottom: (h / 2 - 2) + 'px'
83
+ },
84
+ {
85
+ left: 0,
86
+ top: (h / 2 + 2) + 'px',
87
+ right: 0,
88
+ bottom: 0
89
+ }
90
+ ],
91
+ handleStyles: [
92
+ {
93
+ top: (h / 2 - 2) + 'px',
94
+ left: 0,
95
+ right: 0
96
+ }
97
+ ]
98
+ })
99
+
100
+ const layoutThreeRows = (w, h) => ({
101
+ wrapStyles: [
102
+ {
103
+ left: 0,
104
+ top: 0,
105
+ right: 0,
106
+ bottom: (2 * h / 3 - 2) + 'px'
107
+ },
108
+ {
109
+ left: 0,
110
+ top: (h / 3 + 2) + 'px',
111
+ right: 0,
112
+ bottom: (h / 3 - 2) + 'px'
113
+ },
114
+ {
115
+ left: 0,
116
+ top: (2 * h / 3 + 2) + 'px',
117
+ right: 0,
118
+ bottom: 0
119
+ }
120
+ ],
121
+ handleStyles: [
122
+ {
123
+ top: (h / 3 - 2) + 'px',
124
+ left: 0,
125
+ right: 0
126
+ },
127
+ {
128
+ top: (2 * h / 3 - 2) + 'px',
129
+ left: 0,
130
+ right: 0
131
+ }
132
+ ]
133
+ })
134
+
135
+ const layoutGrid2x2 = (w, h) => ({
136
+ wrapStyles: [
137
+ {
138
+ left: 0,
139
+ top: 0,
140
+ right: (w / 2 - 2) + 'px',
141
+ bottom: (h / 2 - 2) + 'px'
142
+ },
143
+ {
144
+ left: (w / 2 + 2) + 'px',
145
+ top: 0,
146
+ right: 0,
147
+ bottom: (h / 2 - 2) + 'px'
148
+ },
149
+ {
150
+ left: 0,
151
+ top: (h / 2 + 2) + 'px',
152
+ right: (w / 2 - 2) + 'px',
153
+ bottom: 0
154
+ },
155
+ {
156
+ left: (w / 2 + 2) + 'px',
157
+ top: (h / 2 + 2) + 'px',
158
+ right: 0,
159
+ bottom: 0
160
+ }
161
+ ],
162
+ handleStyles: [
163
+ {
164
+ left: (w / 2 - 2) + 'px',
165
+ top: 0,
166
+ bottom: 0
167
+ },
168
+ {
169
+ top: (h / 2 - 2) + 'px',
170
+ left: 0,
171
+ right: 0
172
+ }
173
+ ]
174
+ })
175
+
176
+ const layoutTwoRowsRight = (w, h) => ({
177
+ wrapStyles: [
178
+ {
179
+ left: 0,
180
+ top: 0,
181
+ bottom: 0,
182
+ right: (w / 2 - 2) + 'px'
183
+ },
184
+ {
185
+ left: (w / 2 + 2) + 'px',
186
+ top: 0,
187
+ right: 0,
188
+ bottom: (h / 2 - 2) + 'px'
189
+ },
190
+ {
191
+ left: (w / 2 + 2) + 'px',
192
+ top: (h / 2 + 2) + 'px',
193
+ right: 0,
194
+ bottom: 0
195
+ }
196
+ ],
197
+ handleStyles: [
198
+ {
199
+ left: (w / 2 - 2) + 'px',
200
+ top: 0,
201
+ bottom: 0
202
+ },
203
+ {
204
+ top: (h / 2 - 2) + 'px',
205
+ left: (w / 2 + 2) + 'px',
206
+ right: 0
207
+ }
208
+ ]
209
+ })
210
+
211
+ const layoutTwoColumnsBottom = (w, h) => ({
212
+ wrapStyles: [
213
+ {
214
+ left: 0,
215
+ top: 0,
216
+ right: 0,
217
+ bottom: (h / 2 - 2) + 'px'
218
+ },
219
+ {
220
+ left: 0,
221
+ top: (h / 2 + 2) + 'px',
222
+ right: (w / 2 - 2) + 'px',
223
+ bottom: 0
224
+ },
225
+ {
226
+ left: (w / 2 + 2) + 'px',
227
+ top: (h / 2 + 2) + 'px',
228
+ right: 0,
229
+ bottom: 0
230
+ }
231
+ ],
232
+ handleStyles: [
233
+ {
234
+ top: (h / 2 - 2) + 'px',
235
+ left: 0,
236
+ right: 0
237
+ },
238
+ {
239
+ left: (w / 2 - 2) + 'px',
240
+ top: (h / 2 + 2) + 'px',
241
+ bottom: 0
242
+ }
243
+ ]
244
+ })
245
+
246
+ const layoutFunctions = {
247
+ [splitMap.c1]: layoutSingle,
248
+ [splitMap.c2]: layoutTwoColumns,
249
+ [splitMap.c3]: layoutThreeColumns,
250
+ [splitMap.r2]: layoutTwoRows,
251
+ [splitMap.r3]: layoutThreeRows,
252
+ [splitMap.c2x2]: layoutGrid2x2,
253
+ [splitMap.c1r2]: layoutTwoRowsRight,
254
+ [splitMap.r1c2]: layoutTwoColumnsBottom
255
+ }
256
+
257
+ export default function layoutAlg (layout, w, h) {
258
+ const layoutFunction = layoutFunctions[layout] || layoutSingle
259
+ return layoutFunction(w, h)
260
+ }
@@ -0,0 +1,26 @@
1
+ export default function LayoutItem (props) {
2
+ const {
3
+ children,
4
+ i,
5
+ ...itemProps
6
+ } = props
7
+ function handleClick (e) {
8
+ let currentElement = e.target
9
+ while (currentElement) {
10
+ if (currentElement.classList && currentElement.classList.contains('tabs-dd-icon')) {
11
+ return false
12
+ }
13
+ currentElement = currentElement.parentElement
14
+ }
15
+
16
+ window.StorageEvent.currentLayoutBatch = i
17
+ }
18
+ return (
19
+ <div
20
+ {...itemProps}
21
+ onClick={handleClick}
22
+ >
23
+ {children}
24
+ </div>
25
+ )
26
+ }