@electerm/electerm-react 1.51.3 → 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.
- package/client/common/constants.js +1 -2
- package/client/common/db.js +10 -9
- package/client/components/batch-op/batch-op.jsx +16 -5
- package/client/components/bookmark-form/index.jsx +1 -1
- package/client/components/bookmark-form/ssh-form.jsx +3 -23
- package/client/components/bookmark-form/use-submit.jsx +6 -15
- package/client/components/context-menu/context-menu.styl +5 -5
- package/client/components/context-menu/history.jsx +2 -11
- package/client/components/context-menu/sub-tab-menu.jsx +1 -1
- package/client/components/footer/footer-entry.jsx +1 -6
- package/client/components/layout/layout-item.jsx +2 -2
- package/client/components/main/main.jsx +9 -5
- package/client/components/session/session.jsx +15 -1
- package/client/components/session/session.styl +3 -2
- package/client/components/setting-panel/list.styl +0 -1
- package/client/components/setting-panel/on-tree-drop.js +5 -5
- package/client/components/setting-panel/setting-modal.jsx +0 -12
- package/client/components/sftp/confirm-modal-store.jsx +0 -7
- package/client/components/sftp/file-mode-modal.jsx +2 -2
- package/client/components/sftp/sftp-entry.jsx +2 -2
- package/client/components/sftp/transfer-conflict-store.jsx +69 -66
- package/client/components/sftp/transport-action-store.jsx +32 -50
- package/client/components/sftp/transports-action-store.jsx +15 -15
- package/client/components/sftp/transports-ui-store.jsx +9 -5
- package/client/components/sidebar/bookmark-select.jsx +1 -1
- package/client/components/sidebar/bookmark.jsx +4 -63
- package/client/components/sidebar/history-item.jsx +34 -0
- package/client/components/sidebar/history.jsx +17 -52
- package/client/components/sidebar/index.jsx +4 -34
- package/client/components/sidebar/sidebar-panel.jsx +107 -0
- package/client/components/sidebar/sidebar.styl +14 -0
- package/client/components/sidebar/transfer-list-control.jsx +1 -0
- package/client/components/sidebar/transfer.styl +1 -1
- package/client/components/sidebar/transport-ui.jsx +179 -37
- package/client/components/tabs/index.jsx +4 -4
- package/client/components/tabs/tab.jsx +19 -10
- package/client/components/tree-list/tree-list.jsx +8 -10
- package/client/entry/worker.js +5 -3
- package/client/store/bookmark-group.js +3 -5
- package/client/store/common.js +11 -1
- package/client/store/db-upgrade.js +0 -2
- package/client/store/index.js +0 -3
- package/client/store/init-state.js +4 -3
- package/client/store/item.js +0 -19
- package/client/store/load-data.js +2 -0
- package/client/store/setting.js +2 -51
- package/client/store/sidebar.js +7 -8
- package/client/store/sync.js +7 -7
- package/client/store/tab.js +72 -4
- package/client/store/transfer-history.js +3 -9
- package/client/store/transfer-list.js +75 -75
- package/client/store/watch.js +9 -1
- package/package.json +1 -1
- package/client/components/setting-panel/tab-history.jsx +0 -43
|
@@ -2,65 +2,30 @@
|
|
|
2
2
|
* history select
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
export default memo(function HistoryPanel (props) {
|
|
8
|
+
export default auto(function HistoryPanel (props) {
|
|
14
9
|
const { store } = window
|
|
15
10
|
const {
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
<
|
|
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
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* transporter UI component
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
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
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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 {
|
|
7
|
+
import { debounce } from 'lodash-es'
|
|
8
8
|
import TabTitle from './tab-title'
|
|
9
9
|
import {
|
|
10
10
|
CodeFilled,
|
|
@@ -227,13 +227,13 @@ export default class Tabs extends React.Component {
|
|
|
227
227
|
|
|
228
228
|
adjustScroll = () => {
|
|
229
229
|
const { tabs, currentBatchTabId, batch } = this.props
|
|
230
|
-
const index = findIndex(
|
|
230
|
+
const index = tabs.findIndex(t => t.id === currentBatchTabId)
|
|
231
231
|
const tabsDomWith = Array.from(
|
|
232
232
|
document.querySelectorAll(`.v${batch + 1} .tab`)
|
|
233
|
-
).slice(0, index +
|
|
233
|
+
).slice(0, index + 1).reduce((prev, c) => {
|
|
234
234
|
return prev + c.clientWidth
|
|
235
235
|
}, 0)
|
|
236
|
-
const w = (index + 1) * tabMargin +
|
|
236
|
+
const w = (index + 1) * tabMargin + tabsDomWith
|
|
237
237
|
const tabsInnerWidth = this.getInnerWidth()
|
|
238
238
|
const scrollLeft = w > tabsInnerWidth
|
|
239
239
|
? w - tabsInnerWidth
|
|
@@ -10,13 +10,14 @@ import {
|
|
|
10
10
|
} from '@ant-design/icons'
|
|
11
11
|
import { Tooltip, message } from 'antd'
|
|
12
12
|
import classnames from 'classnames'
|
|
13
|
-
import {
|
|
13
|
+
import { pick } from 'lodash-es'
|
|
14
14
|
import Input from '../common/input-auto-focus'
|
|
15
15
|
import createName from '../../common/create-title'
|
|
16
16
|
import { addClass, removeClass } from '../../common/class'
|
|
17
17
|
import {
|
|
18
18
|
terminalSshConfigType
|
|
19
19
|
} from '../../common/constants'
|
|
20
|
+
import { action } from 'manate'
|
|
20
21
|
import { shortcutDescExtend } from '../shortcuts/shortcut-handler.js'
|
|
21
22
|
|
|
22
23
|
const e = window.translate
|
|
@@ -117,7 +118,13 @@ class Tab extends Component {
|
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
const fromTab = JSON.parse(e.dataTransfer.getData('fromFile'))
|
|
120
|
-
|
|
121
|
+
let onDropTab = target
|
|
122
|
+
while (onDropTab) {
|
|
123
|
+
if (onDropTab.classList && onDropTab.classList.contains('tab')) {
|
|
124
|
+
break
|
|
125
|
+
}
|
|
126
|
+
onDropTab = onDropTab.parentElement
|
|
127
|
+
}
|
|
121
128
|
if (!onDropTab || !fromTab) {
|
|
122
129
|
return
|
|
123
130
|
}
|
|
@@ -129,8 +136,8 @@ class Tab extends Component {
|
|
|
129
136
|
|
|
130
137
|
const { id } = fromTab
|
|
131
138
|
const storeTabs = window.store.tabs
|
|
132
|
-
const indexFrom = findIndex(
|
|
133
|
-
let indexDrop = findIndex(
|
|
139
|
+
const indexFrom = storeTabs.findIndex(t => t.id === id)
|
|
140
|
+
let indexDrop = storeTabs.findIndex(t => t.id === dropId)
|
|
134
141
|
|
|
135
142
|
if (indexFrom >= 0 && indexDrop >= 0) {
|
|
136
143
|
const targetTab = storeTabs[indexDrop]
|
|
@@ -146,12 +153,14 @@ class Tab extends Component {
|
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
// Reorder tabs and update batch
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
action(function () {
|
|
157
|
+
const [tab] = storeTabs.splice(indexFrom, 1)
|
|
158
|
+
tab.batch = targetTab.batch // Update the batch to match target tab's batch
|
|
159
|
+
if (indexFrom < indexDrop) {
|
|
160
|
+
indexDrop = indexDrop - 1
|
|
161
|
+
}
|
|
162
|
+
storeTabs.splice(indexDrop, 0, tab)
|
|
163
|
+
})()
|
|
155
164
|
window.store.focus()
|
|
156
165
|
}
|
|
157
166
|
}
|