@electerm/electerm-react 1.51.1 → 1.51.8

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 (64) hide show
  1. package/client/common/constants.js +1 -2
  2. package/client/common/db.js +10 -9
  3. package/client/components/batch-op/batch-op.jsx +16 -5
  4. package/client/components/bookmark-form/index.jsx +1 -1
  5. package/client/components/bookmark-form/ssh-form.jsx +3 -23
  6. package/client/components/bookmark-form/use-submit.jsx +6 -15
  7. package/client/components/context-menu/context-menu.styl +5 -5
  8. package/client/components/context-menu/history.jsx +2 -11
  9. package/client/components/context-menu/sub-tab-menu.jsx +1 -1
  10. package/client/components/footer/batch-input.jsx +10 -10
  11. package/client/components/footer/footer-entry.jsx +3 -8
  12. package/client/components/footer/tab-select.jsx +2 -2
  13. package/client/components/layout/layout-item.jsx +2 -2
  14. package/client/components/layout/layout.jsx +7 -7
  15. package/client/components/main/main.jsx +9 -5
  16. package/client/components/session/session.jsx +22 -3
  17. package/client/components/session/session.styl +3 -2
  18. package/client/components/session/sessions.jsx +4 -4
  19. package/client/components/setting-panel/list.styl +0 -1
  20. package/client/components/setting-panel/on-tree-drop.js +5 -5
  21. package/client/components/setting-panel/setting-modal.jsx +0 -12
  22. package/client/components/sftp/confirm-modal-store.jsx +0 -7
  23. package/client/components/sftp/file-mode-modal.jsx +2 -2
  24. package/client/components/sftp/sftp-entry.jsx +2 -2
  25. package/client/components/sftp/transfer-conflict-store.jsx +69 -66
  26. package/client/components/sftp/transport-action-store.jsx +32 -50
  27. package/client/components/sftp/transports-action-store.jsx +15 -15
  28. package/client/components/sftp/transports-ui-store.jsx +9 -5
  29. package/client/components/shortcuts/shortcut-control.jsx +3 -3
  30. package/client/components/sidebar/bookmark-select.jsx +1 -1
  31. package/client/components/sidebar/bookmark.jsx +4 -63
  32. package/client/components/sidebar/history-item.jsx +34 -0
  33. package/client/components/sidebar/history.jsx +17 -52
  34. package/client/components/sidebar/index.jsx +4 -34
  35. package/client/components/sidebar/sidebar-panel.jsx +107 -0
  36. package/client/components/sidebar/sidebar.styl +14 -0
  37. package/client/components/sidebar/transfer-list-control.jsx +1 -0
  38. package/client/components/sidebar/transfer.styl +1 -1
  39. package/client/components/sidebar/transport-ui.jsx +179 -37
  40. package/client/components/tabs/index.jsx +12 -12
  41. package/client/components/tabs/tab.jsx +23 -14
  42. package/client/components/terminal/index.jsx +12 -15
  43. package/client/components/terminal/term-search.jsx +4 -4
  44. package/client/components/tree-list/tree-list.jsx +8 -10
  45. package/client/entry/worker.js +5 -3
  46. package/client/store/bookmark-group.js +3 -5
  47. package/client/store/common.js +11 -1
  48. package/client/store/db-upgrade.js +0 -2
  49. package/client/store/event.js +1 -1
  50. package/client/store/index.js +2 -5
  51. package/client/store/init-state.js +9 -8
  52. package/client/store/item.js +0 -19
  53. package/client/store/load-data.js +2 -0
  54. package/client/store/quick-command.js +1 -1
  55. package/client/store/session.js +1 -1
  56. package/client/store/setting.js +2 -51
  57. package/client/store/sidebar.js +7 -8
  58. package/client/store/sync.js +7 -7
  59. package/client/store/tab.js +102 -34
  60. package/client/store/transfer-history.js +3 -9
  61. package/client/store/transfer-list.js +75 -75
  62. package/client/store/watch.js +13 -5
  63. package/package.json +1 -1
  64. package/client/components/setting-panel/tab-history.jsx +0 -43
@@ -0,0 +1,34 @@
1
+ import createTitle, { createTitleWithTag } from '../../common/create-title'
2
+ import { DeleteOutlined } from '@ant-design/icons'
3
+
4
+ export default function HistoryItem (props) {
5
+ const { store } = window
6
+ const {
7
+ item,
8
+ index
9
+ } = props
10
+ function handleClick () {
11
+ store.onSelectHistory(item.tab)
12
+ }
13
+ function handleDelete (e) {
14
+ e.stopPropagation()
15
+ store.history.splice(index, 1)
16
+ }
17
+ const title = createTitleWithTag(item.tab)
18
+ const tt = createTitle(item.tab)
19
+ return (
20
+ <div
21
+ className='item-list-unit'
22
+ title={tt}
23
+ onClick={handleClick}
24
+ >
25
+ <div className='elli pd1y pd2x'>
26
+ {title}
27
+ </div>
28
+ <DeleteOutlined
29
+ className='list-item-edit'
30
+ onClick={handleDelete}
31
+ />
32
+ </div>
33
+ )
34
+ }
@@ -2,65 +2,30 @@
2
2
  * history select
3
3
  */
4
4
 
5
- import { memo } from 'react'
6
- import ItemList from '../setting-panel/list'
7
- import { pick } from 'lodash-es'
8
- import { EditOutlined, PushpinOutlined } from '@ant-design/icons'
9
- import { Tooltip } from 'antd'
5
+ import { auto } from 'manate/react'
6
+ import HistoryItem from './history-item'
10
7
 
11
- const e = window.translate
12
-
13
- export default memo(function HistoryPanel (props) {
8
+ export default auto(function HistoryPanel (props) {
14
9
  const { store } = window
15
10
  const {
16
- openedSideBar,
17
- pinned,
18
- history,
19
- activeItemId
20
- } = props
21
- if (openedSideBar !== 'history') {
22
- return null
23
- }
24
- const prps = {
25
- className: 'font16 mg1x mg2l pointer iblock control-icon'
26
- }
27
- const prps1 = {
28
- className: prps.className + (pinned ? ' pinned' : '')
29
- }
30
- function handleClickItem (item) {
31
- store.onSelectHistory(item.id)
32
- }
11
+ history
12
+ } = store
33
13
  return (
34
14
  <div
35
- className='sidebar-panel history-panel animate-fast'
36
- {...pick(props, ['onMouseEnter', 'onMouseLeave'])}
15
+ className='sidebar-panel-history'
37
16
  >
38
- <div className='pd1y pd2t pd2x'>
39
- <div className='fix'>
40
- <div className='fleft'>{e('history')}</div>
41
- <div className='fleft'>
42
- <Tooltip title={`${e('edit')} ${e('history')}`}>
43
- <EditOutlined
44
- className='font16 mg1x mg2l pointer iblock control-icon icon-do-edit'
45
- onClick={store.handleEditHistory}
46
- />
47
- </Tooltip>
48
- <Tooltip title={e('pin')}>
49
- <PushpinOutlined
50
- {...prps1}
51
- onClick={store.handlePin}
52
- />
53
- </Tooltip>
54
- </div>
55
- </div>
56
- </div>
57
17
  <div className='pd2x'>
58
- <ItemList
59
- type='history'
60
- list={history || []}
61
- onClickItem={handleClickItem}
62
- activeItemId={activeItemId}
63
- />
18
+ {
19
+ history.map((item, i) => {
20
+ return (
21
+ <HistoryItem
22
+ key={item.id}
23
+ index={i}
24
+ item={item}
25
+ />
26
+ )
27
+ })
28
+ }
64
29
  </div>
65
30
  </div>
66
31
  )
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  BookOutlined,
3
- ClockCircleOutlined,
4
3
  CloudSyncOutlined,
5
4
  InfoCircleOutlined,
6
5
  PictureOutlined,
@@ -11,8 +10,7 @@ import {
11
10
  } from '@ant-design/icons'
12
11
  import { useRef, memo } from 'react'
13
12
  import { Tooltip } from 'antd'
14
- import BookMarksWrap from './bookmark'
15
- import HistoryWrap from './history'
13
+ import SideBarPanel from './sidebar-panel'
16
14
  import TransferList from './transfer-list'
17
15
  import MenuBtn from '../context-menu/menu-btn'
18
16
  import {
@@ -43,7 +41,7 @@ export default memo(function Sidebar (props) {
43
41
  transferTab,
44
42
  showModal,
45
43
  showInfoModal,
46
- activeItemId
44
+ sidebarPanelTab
47
45
  } = props
48
46
 
49
47
  const { store } = window
@@ -66,14 +64,6 @@ export default memo(function Sidebar (props) {
66
64
  store.setOpenedSideBar('bookmarks')
67
65
  }
68
66
 
69
- const handleMouseEnterHistory = () => {
70
- if (pinned) {
71
- return false
72
- }
73
- clearTimeout(handler.current)
74
- store.setOpenedSideBar('history')
75
- }
76
-
77
67
  const handleShowUpgrade = () => {
78
68
  store.storeAssign({
79
69
  _upgradeInfo: JSON.stringify({
@@ -90,7 +80,6 @@ export default memo(function Sidebar (props) {
90
80
  openSettingSync,
91
81
  openTerminalThemes,
92
82
  onClickBookmark,
93
- onClickHistory,
94
83
  toggleBatchOp,
95
84
  setLeftSidePanelWidth
96
85
  } = store
@@ -105,7 +94,6 @@ export default memo(function Sidebar (props) {
105
94
  const settingActive = showSetting && settingTab === settingMap.setting && settingItem.id === 'setting-common'
106
95
  const syncActive = showSetting && settingTab === settingMap.setting && settingItem.id === 'setting-sync'
107
96
  const themeActive = showSetting && settingTab === settingMap.terminalThemes
108
- const historyActive = showSetting && settingTab === settingMap.history
109
97
  const bookmarksActive = showSetting && settingTab === settingMap.bookmarks
110
98
  const sideProps = openedSideBar
111
99
  ? {
@@ -154,17 +142,6 @@ export default memo(function Sidebar (props) {
154
142
  className='font20 iblock control-icon'
155
143
  />
156
144
  </SideIcon>
157
- <SideIcon
158
- title={e(settingMap.history)}
159
- active={historyActive}
160
- >
161
- <ClockCircleOutlined
162
- onMouseEnter={handleMouseEnterHistory}
163
- onMouseLeave={handleMouseLeave}
164
- onClick={onClickHistory}
165
- className='font20 iblock control-icon'
166
- />
167
- </SideIcon>
168
145
  <TransferList {...transferProps} />
169
146
  <SideIcon
170
147
  title={e(settingMap.terminalThemes)}
@@ -231,19 +208,12 @@ export default memo(function Sidebar (props) {
231
208
  setLeftSidePanelWidth={setLeftSidePanelWidth}
232
209
  leftSidebarWidth={leftSidebarWidth}
233
210
  >
234
- <BookMarksWrap
211
+ <SideBarPanel
235
212
  pinned={pinned}
213
+ sidebarPanelTab={sidebarPanelTab}
236
214
  onMouseEnter={handleMouseEnterBookmark}
237
215
  onMouseLeave={handleMouseLeave}
238
216
  />
239
- <HistoryWrap
240
- history={props.history}
241
- openedSideBar={openedSideBar}
242
- onMouseEnter={handleMouseEnterHistory}
243
- onMouseLeave={handleMouseLeave}
244
- activeItemId={activeItemId}
245
- pinned={pinned}
246
- />
247
217
  </SidePanel>
248
218
  </div>
249
219
  )
@@ -0,0 +1,107 @@
1
+ /**
2
+ * bookmark select
3
+ */
4
+
5
+ import { memo } from 'react'
6
+ import BookmarkWrap from './bookmark'
7
+ import History from './history'
8
+ import { pick } from 'lodash-es'
9
+ import { Tabs, Tooltip } from 'antd'
10
+ import { ArrowsAltOutlined, EditOutlined, PlusCircleOutlined, ShrinkOutlined, PushpinOutlined } from '@ant-design/icons'
11
+
12
+ const e = window.translate
13
+
14
+ export default memo(function SidebarPanel (props) {
15
+ const { sidebarPanelTab, pinned } = props
16
+ const { store } = window
17
+ const prps = {
18
+ className: 'font16 mg1x mg2l pointer iblock control-icon'
19
+ }
20
+ const prps1 = {
21
+ className: prps.className + (pinned ? ' pinned' : '')
22
+ }
23
+ const tabsProps = {
24
+ activeKey: sidebarPanelTab,
25
+ onChange: store.handleSidebarPanelTab,
26
+ items: [
27
+ {
28
+ key: 'bookmarks',
29
+ label: e('bookmarks'),
30
+ children: null
31
+ },
32
+ {
33
+ key: 'history',
34
+ label: e('history'),
35
+ children: null
36
+ }
37
+ ]
38
+ }
39
+ const pop1 = {
40
+ ...prps,
41
+ onClick: store.onNewSsh
42
+ }
43
+ const pop2 = {
44
+ ...prps,
45
+ onClick: store.expandBookmarks
46
+ }
47
+ const pop3 = {
48
+ ...prps,
49
+ onClick: store.collapseBookmarks
50
+ }
51
+
52
+ function renderExpandIcons () {
53
+ if (sidebarPanelTab !== 'bookmarks') {
54
+ return null
55
+ }
56
+ return [
57
+ <Tooltip title={e('expandAll')} key='expand'>
58
+ <ArrowsAltOutlined
59
+ {...pop2}
60
+ />
61
+ </Tooltip>,
62
+ <Tooltip title={e('collapseAll')} key='collapse'>
63
+ <ShrinkOutlined
64
+ {...pop3}
65
+ />
66
+ </Tooltip>
67
+ ]
68
+ }
69
+ return (
70
+ <div
71
+ className='sidebar-panel bookmarks-panel animate-fast'
72
+ {...pick(props, ['onMouseEnter', 'onMouseLeave'])}
73
+ >
74
+ <div className='sidebar-pin-top'>
75
+ <div className='pd1y pd2t pd2x sidebar-panel-control'>
76
+ <Tooltip title={e('newBookmark')}>
77
+ <PlusCircleOutlined
78
+ {...pop1}
79
+ />
80
+ </Tooltip>
81
+ <Tooltip title={`${e('edit')} ${e('bookmarks')}`}>
82
+ <EditOutlined
83
+ {...pop1}
84
+ />
85
+ </Tooltip>
86
+ {
87
+ renderExpandIcons()
88
+ }
89
+ <Tooltip title={e('pin')}>
90
+ <PushpinOutlined
91
+ {...prps1}
92
+ onClick={store.handlePin}
93
+ />
94
+ </Tooltip>
95
+ </div>
96
+ <div className='pd1y pd2x'>
97
+ <Tabs {...tabsProps} />
98
+ </div>
99
+ </div>
100
+ {
101
+ sidebarPanelTab === 'bookmarks'
102
+ ? <BookmarkWrap {...props} />
103
+ : <History store={store} />
104
+ }
105
+ </div>
106
+ )
107
+ })
@@ -26,6 +26,20 @@
26
26
  box-shadow 0px 0px 3px 3px alpha(main, .1)
27
27
  .item-list
28
28
  padding-right 0
29
+ .sidebar-pin-top
30
+ position absolute
31
+ left 0
32
+ right 0
33
+ top 36px
34
+ height 112px
35
+ .sidebar-panel-bookmarks
36
+ .sidebar-panel-history
37
+ position absolute
38
+ left 0
39
+ right 0
40
+ top 148px
41
+ bottom 0
42
+ overflow-y scroll
29
43
  .not-system-ui.is-mac
30
44
  .sidebar-bar
31
45
  margin-top 20px
@@ -117,6 +117,7 @@ export default class TransferModalUI extends Component {
117
117
  return (
118
118
  <Transport
119
119
  transfer={t}
120
+ index={i}
120
121
  key={id + ':tr:' + i}
121
122
  />
122
123
  )
@@ -4,4 +4,4 @@
4
4
  .ant-badge-multiple-words
5
5
  padding 0 3px
6
6
  .transfer-list-card
7
- max-width calc(100% - 38px)
7
+ width calc(100% - 48px)
@@ -1,18 +1,23 @@
1
1
  /**
2
2
  * transporter UI component
3
3
  */
4
- import React from 'react'
4
+ import { useRef } from 'react'
5
5
  import Tag from '../sftp/transfer-tag'
6
+ import { Flex } from 'antd'
6
7
  import {
7
8
  CloseCircleOutlined,
8
9
  PlayCircleOutlined,
9
- PauseCircleOutlined
10
+ PauseCircleOutlined,
11
+ VerticalAlignTopOutlined
10
12
  } from '@ant-design/icons'
13
+ import { action } from 'manate'
14
+ import { addClass, removeClass } from '../../common/class'
11
15
  import './transfer.styl'
12
16
 
13
17
  const e = window.translate
14
18
 
15
19
  export default function Transporter (props) {
20
+ const dom = useRef()
16
21
  const {
17
22
  fromPath,
18
23
  toPath,
@@ -29,12 +34,109 @@ export default function Transporter (props) {
29
34
  inited,
30
35
  id
31
36
  } = props.transfer
37
+ const { index } = props
38
+ const onDragCls = 'ondrag-tr'
39
+ const onDragOverCls = 'dragover-tr'
40
+ function moveToTop () {
41
+ action(function () {
42
+ const arr = window.store.fileTransfers
43
+ if (index > 0) {
44
+ const [item] = arr.splice(index, 1)
45
+ arr.unshift(item)
46
+ }
47
+ })()
48
+ }
32
49
  function cancel () {
33
50
  window.store.cancelTransfer(id)
34
51
  }
35
52
  function handlePauseOrResume () {
36
53
  window.store.toggleTransfer(id)
37
54
  }
55
+
56
+ function clearCls () {
57
+ document.querySelectorAll('.' + onDragOverCls).forEach((d) => {
58
+ removeClass(d, onDragOverCls)
59
+ })
60
+ }
61
+
62
+ function onDrag () {
63
+ addClass(dom.current, onDragCls)
64
+ }
65
+
66
+ function onDragEnter () {
67
+ clearCls()
68
+ addClass(dom.current, onDragOverCls)
69
+ }
70
+
71
+ function onDragExit () {
72
+ // debug('ondragexit')
73
+ // let {target} = e
74
+ // removeClass(target, 'sftp-dragover')
75
+ }
76
+
77
+ function onDragLeave (e) {
78
+ // debug('ondragleave')
79
+ const { target } = e
80
+ removeClass(target, onDragOverCls)
81
+ }
82
+
83
+ function onDragOver (e) {
84
+ // debug('ondragover')
85
+ // debug(e.target)
86
+ // removeClass(dom.current, 'sftp-dragover')
87
+ e.preventDefault()
88
+ }
89
+
90
+ function onDragStart (e) {
91
+ // debug('ondragstart')
92
+ // debug(e.target)
93
+ e.dataTransfer.setData('id', JSON.stringify(dom.current.getAttribute('data-id')))
94
+ // e.effectAllowed = 'copyMove'
95
+ }
96
+
97
+ function onDrop (e) {
98
+ e.preventDefault()
99
+ const { target } = e
100
+ if (!target) {
101
+ return
102
+ }
103
+ let onDropTab = target
104
+ while (onDropTab) {
105
+ if (onDropTab.classList && onDropTab.classList.contains('sftp-transport')) {
106
+ break
107
+ }
108
+ onDropTab = onDropTab.parentElement
109
+ }
110
+ const fromId = JSON.parse(e.dataTransfer.getData('id'))
111
+ if (!onDropTab || !fromId) {
112
+ return
113
+ }
114
+
115
+ const dropId = onDropTab.getAttribute('data-id')
116
+ if (!dropId || dropId === fromId) {
117
+ return
118
+ }
119
+
120
+ const arr = window.store.fileTransfers
121
+ const indexFrom = arr.findIndex(t => t.id === fromId)
122
+ let indexDrop = arr.findIndex(t => t.id === dropId)
123
+ if (indexFrom >= 0 && indexDrop >= 0) {
124
+ // Reorder tabs and update batch
125
+ action(function () {
126
+ const [tr] = arr.splice(indexFrom, 1)
127
+ if (indexFrom < indexDrop) {
128
+ indexDrop = indexDrop - 1
129
+ }
130
+ arr.splice(indexDrop, 0, tr)
131
+ })()
132
+ }
133
+ }
134
+
135
+ function onDragEnd (e) {
136
+ removeClass(dom.current, onDragCls)
137
+ clearCls()
138
+ e && e.dataTransfer && e.dataTransfer.clearData()
139
+ }
38
140
  const isTransfer = typeTo !== typeFrom
39
141
  const Icon = !pausing ? PauseCircleOutlined : PlayCircleOutlined
40
142
  const pauseTitle = pausing ? e('resume') : e('pause')
@@ -49,6 +151,14 @@ export default function Transporter (props) {
49
151
  title={e('cancel')}
50
152
  />
51
153
  )
154
+ const toTopIcon = index === 0
155
+ ? null
156
+ : (
157
+ <VerticalAlignTopOutlined
158
+ className='transfer-control-icon pointer hover-black font14'
159
+ onClick={moveToTop}
160
+ />
161
+ )
52
162
  const controlIcon = isTransfer
53
163
  ? (
54
164
  <Icon
@@ -58,41 +168,73 @@ export default function Transporter (props) {
58
168
  />
59
169
  )
60
170
  : null
171
+ const flexProps = {
172
+ className: cls,
173
+ gap: 3,
174
+ title,
175
+ ref: dom,
176
+ id: `transfer-unit-${id}`,
177
+ draggable: true,
178
+ 'data-id': id,
179
+ onDrag,
180
+ onDragEnter,
181
+ onDragExit,
182
+ onDragLeave,
183
+ onDragOver,
184
+ onDragStart,
185
+ onDrop,
186
+ onDragEnd
187
+ }
61
188
  return (
62
- <div className={cls} title={title} id={`transfer-unit-${id}`}>
63
- <Tag
64
- transfer={{
65
- typeTo,
66
- typeFrom,
67
- error,
68
- inited
69
- }}
70
- />
71
- <span
72
- className='flex-child sftp-file sftp-local-file elli'
73
- title={fromPath}
74
- >{fromPathReal || fromPath}
75
- </span>
76
- <span className='flex-child sftp-transfer-arrow'>
77
-
78
- </span>
79
- <span
80
- className='flex-child sftp-file sftp-remote-file elli'
81
- >{toPathReal || toPath}
82
- </span>
83
- <span
84
- className='flex-child sftp-file-percent'
85
- >
86
- {percent || 0}%
87
- {speed ? `(${speed})` : null}
88
- </span>
89
- <span
90
- className='flex-child sftp-file-percent'
91
- >
92
- {passedTime || '-'}|{leftTime || '-'}
93
- </span>
94
- {controlIcon}
95
- {cancelIcon}
96
- </div>
189
+ <Flex
190
+ {...flexProps}
191
+ >
192
+ <Flex>
193
+ <Tag
194
+ transfer={{
195
+ typeTo,
196
+ typeFrom,
197
+ error,
198
+ inited
199
+ }}
200
+ />
201
+ </Flex>
202
+ <Flex>
203
+ <span
204
+ className='sftp-file sftp-local-file elli'
205
+ title={fromPath}
206
+ >{fromPathReal || fromPath}
207
+ </span>
208
+ </Flex>
209
+ <Flex>
210
+ <span className='sftp-transfer-arrow'>
211
+
212
+ </span>
213
+ </Flex>
214
+ <Flex>
215
+ <span
216
+ className='sftp-file sftp-remote-file elli'
217
+ >{toPathReal || toPath}
218
+ </span>
219
+ </Flex>
220
+ <Flex>
221
+ <span
222
+ className='sftp-file-percent'
223
+ >
224
+ {percent || 0}%
225
+ {speed ? `(${speed})` : null}
226
+ </span>
227
+ </Flex>
228
+ <Flex>
229
+ <span
230
+ className='sftp-file-percent'
231
+ >
232
+ {passedTime || '-'}|{leftTime || '-'}
233
+ </span>
234
+ </Flex>
235
+ <Flex>{controlIcon}</Flex>
236
+ <Flex>{cancelIcon}</Flex>
237
+ <Flex>{toTopIcon}</Flex>
238
+ </Flex>
97
239
  )
98
240
  }
@@ -4,7 +4,7 @@
4
4
 
5
5
  import React from 'react'
6
6
  import runIdle from '../../common/run-idle'
7
- import { findIndex, debounce } from 'lodash-es'
7
+ import { debounce } from 'lodash-es'
8
8
  import TabTitle from './tab-title'
9
9
  import {
10
10
  CodeFilled,
@@ -60,8 +60,7 @@ export default class Tabs extends React.Component {
60
60
  }
61
61
 
62
62
  componentDidMount () {
63
- const { batch } = this.props
64
- this.dom = document.querySelector(`.v${batch + 1} .tabs-inner`)
63
+ this.domRef = React.createRef()
65
64
  const {
66
65
  tabsRef
67
66
  } = this
@@ -228,39 +227,39 @@ export default class Tabs extends React.Component {
228
227
 
229
228
  adjustScroll = () => {
230
229
  const { tabs, currentBatchTabId, batch } = this.props
231
- const index = findIndex(tabs, t => t.id === currentBatchTabId)
230
+ const index = tabs.findIndex(t => t.id === currentBatchTabId)
232
231
  const tabsDomWith = Array.from(
233
232
  document.querySelectorAll(`.v${batch + 1} .tab`)
234
- ).slice(0, index + 2).reduce((prev, c) => {
233
+ ).slice(0, index + 1).reduce((prev, c) => {
235
234
  return prev + c.clientWidth
236
235
  }, 0)
237
- const w = (index + 1) * tabMargin + 5 + tabsDomWith
236
+ const w = (index + 1) * tabMargin + tabsDomWith
238
237
  const tabsInnerWidth = this.getInnerWidth()
239
238
  const scrollLeft = w > tabsInnerWidth
240
239
  ? w - tabsInnerWidth
241
240
  : 0
242
- this.dom.scrollLeft = scrollLeft
241
+ this.domRef.current.scrollTo({ left: scrollLeft, behavior: 'smooth' })
243
242
  this.setState({
244
243
  overflow: this.isOverflow()
245
244
  })
246
245
  }
247
246
 
248
247
  handleScrollLeft = () => {
249
- let { scrollLeft } = this.dom
248
+ let { scrollLeft } = this.domRef.current
250
249
  scrollLeft = scrollLeft - tabMargin - tabWidth
251
250
  if (scrollLeft < 0) {
252
251
  scrollLeft = 0
253
252
  }
254
- this.dom.scrollLeft = scrollLeft
253
+ this.domRef.current.scrollTo({ left: scrollLeft, behavior: 'smooth' })
255
254
  }
256
255
 
257
256
  handleScrollRight = () => {
258
- let { scrollLeft } = this.dom
257
+ let { scrollLeft } = this.domRef.current
259
258
  scrollLeft = scrollLeft + tabMargin + tabWidth
260
259
  if (scrollLeft < 0) {
261
260
  scrollLeft = 0
262
261
  }
263
- this.dom.scrollLeft = scrollLeft
262
+ this.domRef.current.scrollTo({ left: scrollLeft, behavior: 'smooth' })
264
263
  }
265
264
 
266
265
  handleWheelEvent = debounce((e) => {
@@ -275,7 +274,7 @@ export default class Tabs extends React.Component {
275
274
 
276
275
  handleClickMenu = ({ key }) => {
277
276
  const id = key.split('##')[1]
278
- window.store['currentTabId' + this.props.batch] = id
277
+ window.store['activeTabId' + this.props.batch] = id
279
278
  }
280
279
 
281
280
  handleChangeLayout = ({ key }) => {
@@ -415,6 +414,7 @@ export default class Tabs extends React.Component {
415
414
  return (
416
415
  <div
417
416
  className='tabs-inner'
417
+ ref={this.domRef}
418
418
  style={style}
419
419
  >
420
420
  <div