@electerm/electerm-react 3.2.0 → 3.3.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 -3
- package/client/components/batch-op/batch-op-alert.jsx +42 -0
- package/client/components/batch-op/batch-op-editor.jsx +202 -0
- package/client/components/batch-op/batch-op-logs.jsx +53 -0
- package/client/components/batch-op/batch-op-runner.jsx +315 -0
- package/client/components/bookmark-form/ai-bookmark-form.jsx +2 -1
- package/client/components/bookmark-form/bookmark-from-history-modal.jsx +2 -1
- package/client/components/common/auto-check-update.jsx +31 -0
- package/client/components/common/notification.styl +1 -1
- package/client/components/file-transfer/conflict-resolve.jsx +3 -0
- package/client/components/footer/batch-input.jsx +10 -7
- package/client/components/main/error-wrapper.jsx +18 -7
- package/client/components/main/main.jsx +6 -7
- package/client/components/setting-sync/auto-sync.jsx +53 -0
- package/client/components/setting-sync/data-import.jsx +69 -8
- package/client/components/sftp/address-bar.jsx +7 -1
- package/client/components/sidebar/bookmark-select.jsx +3 -2
- package/client/components/sidebar/history-item.jsx +3 -1
- package/client/components/sidebar/index.jsx +0 -9
- package/client/components/tabs/add-btn-menu.jsx +1 -1
- package/client/components/tabs/add-btn.jsx +9 -15
- package/client/components/tabs/quick-connect.jsx +6 -10
- package/client/components/terminal/terminal.jsx +4 -5
- package/client/components/tree-list/tree-list.jsx +115 -10
- package/client/components/tree-list/tree-list.styl +3 -0
- package/client/components/tree-list/tree-search.jsx +9 -1
- package/client/components/widgets/widget-form.jsx +6 -0
- package/client/store/common.js +0 -28
- package/client/store/load-data.js +3 -3
- package/client/store/mcp-handler.js +2 -2
- package/client/store/sync.js +25 -1
- package/client/store/tab.js +1 -1
- package/client/store/watch.js +10 -18
- package/client/views/index.pug +1 -2
- package/package.json +1 -1
- package/client/components/batch-op/batch-op.jsx +0 -694
|
@@ -136,12 +136,10 @@ export default class BatchInput extends Component {
|
|
|
136
136
|
} = this.props
|
|
137
137
|
const opts = {
|
|
138
138
|
options: this.buildOptions(),
|
|
139
|
-
placeholder: e('batchInput'),
|
|
140
139
|
value: cmd,
|
|
141
140
|
onChange: this.handleChange,
|
|
142
141
|
defaultOpen: false,
|
|
143
142
|
open,
|
|
144
|
-
allowClear: true,
|
|
145
143
|
className: 'batch-input-wrap'
|
|
146
144
|
}
|
|
147
145
|
const cls = classNames(
|
|
@@ -155,6 +153,15 @@ export default class BatchInput extends Component {
|
|
|
155
153
|
placeholder: e('batchInput'),
|
|
156
154
|
className: 'batch-input-holder'
|
|
157
155
|
}
|
|
156
|
+
const textAreaProps = {
|
|
157
|
+
onPressEnter: this.handleEnter,
|
|
158
|
+
onClick: this.handleClick,
|
|
159
|
+
onBlur: this.handleBlur,
|
|
160
|
+
size: 'small',
|
|
161
|
+
autoSize: { minRows: 1 },
|
|
162
|
+
placeholder: e('batchInput'),
|
|
163
|
+
allowClear: true
|
|
164
|
+
}
|
|
158
165
|
const tabSelectProps = {
|
|
159
166
|
activeTabId: this.props.activeTabId,
|
|
160
167
|
tabs: this.getTabs(),
|
|
@@ -179,11 +186,7 @@ export default class BatchInput extends Component {
|
|
|
179
186
|
{...opts}
|
|
180
187
|
>
|
|
181
188
|
<Input.TextArea
|
|
182
|
-
|
|
183
|
-
onClick={this.handleClick}
|
|
184
|
-
onBlur={this.handleBlur}
|
|
185
|
-
size='small'
|
|
186
|
-
autoSize={{ minRows: 1 }}
|
|
189
|
+
{...textAreaProps}
|
|
187
190
|
/>
|
|
188
191
|
</AutoComplete>
|
|
189
192
|
<TabSelect {...tabSelectProps} />
|
|
@@ -77,12 +77,9 @@ export default class ErrorBoundary extends React.PureComponent {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
renderTroubleShoot = () => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
} = packInfo
|
|
85
|
-
const bugUrl = `${bugReportLink}/new/choose`
|
|
80
|
+
if (window.et.isWebApp) {
|
|
81
|
+
return this.renderContacts()
|
|
82
|
+
}
|
|
86
83
|
return (
|
|
87
84
|
<div className='pd1y wordbreak'>
|
|
88
85
|
<h2>{e('troubleShoot')}</h2>
|
|
@@ -99,6 +96,20 @@ export default class ErrorBoundary extends React.PureComponent {
|
|
|
99
96
|
)
|
|
100
97
|
})
|
|
101
98
|
}
|
|
99
|
+
{this.renderContacts()}
|
|
100
|
+
</div>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
renderContacts () {
|
|
105
|
+
const {
|
|
106
|
+
bugs: {
|
|
107
|
+
url: bugReportLink
|
|
108
|
+
}
|
|
109
|
+
} = packInfo
|
|
110
|
+
const bugUrl = `${bugReportLink}/new/choose`
|
|
111
|
+
return (
|
|
112
|
+
<>
|
|
102
113
|
<div className='pd1b'>
|
|
103
114
|
<Link to={bugUrl}>{e('bugReport')}</Link>
|
|
104
115
|
</div>
|
|
@@ -112,7 +123,7 @@ export default class ErrorBoundary extends React.PureComponent {
|
|
|
112
123
|
className='mwm-100'
|
|
113
124
|
/>
|
|
114
125
|
</div>
|
|
115
|
-
|
|
126
|
+
</>
|
|
116
127
|
)
|
|
117
128
|
}
|
|
118
129
|
|
|
@@ -6,7 +6,6 @@ import UpdateCheck from './upgrade'
|
|
|
6
6
|
import SettingModal from '../setting-panel/setting-modal'
|
|
7
7
|
import TextEditor from '../text-editor/text-editor'
|
|
8
8
|
import Sidebar from '../sidebar'
|
|
9
|
-
import BatchOp from '../batch-op/batch-op'
|
|
10
9
|
import CssOverwrite from '../bg/css-overwrite'
|
|
11
10
|
import UiTheme from './ui-theme'
|
|
12
11
|
import CustomCss from '../bg/custom-css.jsx'
|
|
@@ -34,6 +33,9 @@ import MoveItemModal from '../tree-list/move-item-modal'
|
|
|
34
33
|
import InputContextMenu from '../common/input-context-menu'
|
|
35
34
|
import WorkspaceSaveModal from '../tabs/workspace-save-modal'
|
|
36
35
|
import BookmarkFromHistoryModal from '../bookmark-form/bookmark-from-history-modal'
|
|
36
|
+
import AutoSync from '../setting-sync/auto-sync'
|
|
37
|
+
import AutoCheckUpdate from '../common/auto-check-update'
|
|
38
|
+
import BatchOpRunner from '../batch-op/batch-op-runner'
|
|
37
39
|
import { pick } from 'lodash-es'
|
|
38
40
|
import deepCopy from 'json-deep-copy'
|
|
39
41
|
import './wrapper.styl'
|
|
@@ -184,11 +186,6 @@ export default auto(function Index (props) {
|
|
|
184
186
|
fileTransferChanged: JSON.stringify(copiedTransfer),
|
|
185
187
|
fileTransfers: copiedTransfer
|
|
186
188
|
}
|
|
187
|
-
const batchOpProps = {
|
|
188
|
-
transferHistory,
|
|
189
|
-
showModal: store.showModal,
|
|
190
|
-
innerWidth: store.innerWidth
|
|
191
|
-
}
|
|
192
189
|
const resProps = {
|
|
193
190
|
resolutions: deepCopy(store.resolutions),
|
|
194
191
|
openResolutionEdit
|
|
@@ -263,7 +260,6 @@ export default auto(function Index (props) {
|
|
|
263
260
|
/>
|
|
264
261
|
<FileInfoModal />
|
|
265
262
|
<SettingModal store={store} />
|
|
266
|
-
<BatchOp {...batchOpProps} />
|
|
267
263
|
<MoveItemModal store={store} />
|
|
268
264
|
<div
|
|
269
265
|
id='outside-context'
|
|
@@ -295,9 +291,12 @@ export default auto(function Index (props) {
|
|
|
295
291
|
<ConnectionHoppingWarning {...warningProps} />
|
|
296
292
|
<TerminalCmdSuggestions {...cmdSuggestionsProps} />
|
|
297
293
|
<TransferQueue />
|
|
294
|
+
<AutoSync config={config} />
|
|
295
|
+
<AutoCheckUpdate config={config} />
|
|
298
296
|
<WorkspaceSaveModal store={store} />
|
|
299
297
|
<BookmarkFromHistoryModal />
|
|
300
298
|
<NotificationContainer />
|
|
299
|
+
<BatchOpRunner />
|
|
301
300
|
</div>
|
|
302
301
|
</ConfigProvider>
|
|
303
302
|
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
|
+
|
|
3
|
+
export default function AutoSync ({ config }) {
|
|
4
|
+
const lastSyncTimeRef = useRef(0)
|
|
5
|
+
const intervalIdRef = useRef(null)
|
|
6
|
+
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (
|
|
9
|
+
!config.syncSetting?.autoSync || config.syncSetting?.autoSyncInterval <= 0
|
|
10
|
+
) {
|
|
11
|
+
clearInterval(intervalIdRef.current)
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
const checkAndSync = async () => {
|
|
15
|
+
const syncSetting = config.syncSetting || {}
|
|
16
|
+
const { autoSync, autoSyncInterval = 0, autoSyncDirection = 'upload' } = syncSetting
|
|
17
|
+
|
|
18
|
+
if (!autoSync) {
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (autoSyncInterval <= 0) {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const now = Date.now()
|
|
27
|
+
const intervalMs = autoSyncInterval * 60 * 1000
|
|
28
|
+
if (now - lastSyncTimeRef.current >= intervalMs) {
|
|
29
|
+
const { store } = window
|
|
30
|
+
if (autoSyncDirection === 'download') {
|
|
31
|
+
await store.downloadSettingAll()
|
|
32
|
+
} else {
|
|
33
|
+
await store.uploadSettingAll()
|
|
34
|
+
}
|
|
35
|
+
lastSyncTimeRef.current = now
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
intervalIdRef.current = setInterval(checkAndSync, 10000)
|
|
40
|
+
|
|
41
|
+
return () => {
|
|
42
|
+
if (intervalIdRef.current) {
|
|
43
|
+
clearInterval(intervalIdRef.current)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}, [
|
|
47
|
+
config.syncSetting?.autoSync,
|
|
48
|
+
config.syncSetting?.autoSyncInterval,
|
|
49
|
+
config.syncSetting?.autoSyncDirection
|
|
50
|
+
])
|
|
51
|
+
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
@@ -5,22 +5,65 @@
|
|
|
5
5
|
import {
|
|
6
6
|
Button,
|
|
7
7
|
Switch,
|
|
8
|
-
|
|
8
|
+
Select,
|
|
9
|
+
Space
|
|
9
10
|
} from 'antd'
|
|
10
11
|
import {
|
|
11
12
|
ImportOutlined,
|
|
12
|
-
ExportOutlined
|
|
13
|
-
InfoCircleOutlined
|
|
13
|
+
ExportOutlined
|
|
14
14
|
} from '@ant-design/icons'
|
|
15
15
|
import Upload from '../common/upload'
|
|
16
|
+
import HelpIcon from '../common/help-icon'
|
|
16
17
|
|
|
17
18
|
const e = window.translate
|
|
18
19
|
|
|
20
|
+
const intervalOptions = [
|
|
21
|
+
{ value: 0, label: e('autoSyncOnChange') },
|
|
22
|
+
{ value: 5, label: '5 ' + e('minutes') },
|
|
23
|
+
{ value: 10, label: '10 ' + e('minutes') },
|
|
24
|
+
{ value: 15, label: '15 ' + e('minutes') },
|
|
25
|
+
{ value: 30, label: '30 ' + e('minutes') },
|
|
26
|
+
{ value: 60, label: '1 ' + e('hours') },
|
|
27
|
+
{ value: 120, label: '2 ' + e('hours') },
|
|
28
|
+
{ value: 360, label: '6 ' + e('hours') },
|
|
29
|
+
{ value: 720, label: '12 ' + e('hours') },
|
|
30
|
+
{ value: 1440, label: '24 ' + e('hours') }
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
const directionOptions = [
|
|
34
|
+
{ value: 'upload', label: e('uploadSettings') },
|
|
35
|
+
{ value: 'download', label: e('downloadSettings') }
|
|
36
|
+
]
|
|
37
|
+
|
|
19
38
|
export default function DataTransport (props) {
|
|
20
39
|
const txt = e('autoSync')
|
|
21
40
|
const {
|
|
22
41
|
store
|
|
23
42
|
} = window
|
|
43
|
+
|
|
44
|
+
const syncSetting = props.config.syncSetting || {}
|
|
45
|
+
const autoSyncEnabled = syncSetting.autoSync || false
|
|
46
|
+
const autoSyncInterval = syncSetting.autoSyncInterval || 0
|
|
47
|
+
const autoSyncDirection = syncSetting.autoSyncDirection || 'upload'
|
|
48
|
+
|
|
49
|
+
function handleAutoSync (checked) {
|
|
50
|
+
store.updateSyncSetting({
|
|
51
|
+
autoSync: checked
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function handleIntervalChange (value) {
|
|
56
|
+
store.updateSyncSetting({
|
|
57
|
+
autoSyncInterval: value
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function handleDirectionChange (value) {
|
|
62
|
+
store.updateSyncSetting({
|
|
63
|
+
autoSyncDirection: value
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
24
67
|
return (
|
|
25
68
|
<div className='pd2 fix'>
|
|
26
69
|
<div className='fleft'>
|
|
@@ -45,15 +88,33 @@ export default function DataTransport (props) {
|
|
|
45
88
|
</div>
|
|
46
89
|
<div className='fright'>
|
|
47
90
|
<Switch
|
|
48
|
-
checked={
|
|
91
|
+
checked={autoSyncEnabled}
|
|
49
92
|
checkedChildren={txt}
|
|
50
|
-
onChange={
|
|
93
|
+
onChange={handleAutoSync}
|
|
51
94
|
unCheckedChildren={txt}
|
|
52
95
|
className='mg3l mg1r'
|
|
53
96
|
/>
|
|
54
|
-
|
|
55
|
-
<
|
|
56
|
-
|
|
97
|
+
{autoSyncEnabled && (
|
|
98
|
+
<Space className='mg1l' size='small'>
|
|
99
|
+
<Select
|
|
100
|
+
value={autoSyncInterval}
|
|
101
|
+
onChange={handleIntervalChange}
|
|
102
|
+
options={intervalOptions}
|
|
103
|
+
style={{ width: 120 }}
|
|
104
|
+
popupMatchSelectWidth={false}
|
|
105
|
+
/>
|
|
106
|
+
<Select
|
|
107
|
+
value={autoSyncDirection}
|
|
108
|
+
onChange={handleDirectionChange}
|
|
109
|
+
options={directionOptions}
|
|
110
|
+
style={{ width: 100 }}
|
|
111
|
+
popupMatchSelectWidth={false}
|
|
112
|
+
/>
|
|
113
|
+
</Space>
|
|
114
|
+
)}
|
|
115
|
+
<HelpIcon
|
|
116
|
+
link='https://github.com/electerm/electerm/wiki/Auto-data-Sync'
|
|
117
|
+
/>
|
|
57
118
|
</div>
|
|
58
119
|
</div>
|
|
59
120
|
)
|
|
@@ -74,9 +74,15 @@ function renderAddonBefore (props, realPath) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
function renderAddonAfter (isLoadingRemote, onGoto, GoIcon, type) {
|
|
77
|
+
const handleClick = (e) => {
|
|
78
|
+
e.stopPropagation()
|
|
79
|
+
if (!isLoadingRemote) {
|
|
80
|
+
onGoto(type)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
77
83
|
return (
|
|
78
84
|
<GoIcon
|
|
79
|
-
onClick={
|
|
85
|
+
onClick={handleClick}
|
|
80
86
|
/>
|
|
81
87
|
)
|
|
82
88
|
}
|
|
@@ -6,7 +6,7 @@ import { auto } from 'manate/react'
|
|
|
6
6
|
import TreeList from '../tree-list/tree-list'
|
|
7
7
|
|
|
8
8
|
export default auto(function BookmarkSelect (props) {
|
|
9
|
-
const { store, from } = props
|
|
9
|
+
const { store, from, autoFocus } = props
|
|
10
10
|
const {
|
|
11
11
|
listStyle,
|
|
12
12
|
openedSideBar,
|
|
@@ -38,7 +38,8 @@ export default auto(function BookmarkSelect (props) {
|
|
|
38
38
|
bookmarkGroups: store.getBookmarkGroupsTotal(),
|
|
39
39
|
expandedKeys,
|
|
40
40
|
leftSidebarWidth,
|
|
41
|
-
bookmarkGroupTree: store.bookmarkGroupTree
|
|
41
|
+
bookmarkGroupTree: store.bookmarkGroupTree,
|
|
42
|
+
autoFocus
|
|
42
43
|
}
|
|
43
44
|
return (
|
|
44
45
|
<TreeList
|
|
@@ -40,7 +40,9 @@ export default function HistoryItem (props) {
|
|
|
40
40
|
e.stopPropagation()
|
|
41
41
|
refsStatic.get('bookmark-from-history-modal')?.show(item.tab)
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
if (!item.tab) {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
44
46
|
const title = createTitleWithTag(item.tab)
|
|
45
47
|
const tt = createTitle(item.tab)
|
|
46
48
|
return (
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
PlusCircleOutlined,
|
|
7
7
|
SettingOutlined,
|
|
8
8
|
UpCircleOutlined,
|
|
9
|
-
BarsOutlined,
|
|
10
9
|
AppstoreOutlined,
|
|
11
10
|
ThunderboltOutlined
|
|
12
11
|
} from '@ant-design/icons'
|
|
@@ -92,7 +91,6 @@ export default function Sidebar (props) {
|
|
|
92
91
|
openAbout,
|
|
93
92
|
openSettingSync,
|
|
94
93
|
openTerminalThemes,
|
|
95
|
-
toggleBatchOp,
|
|
96
94
|
setLeftSidePanelWidth
|
|
97
95
|
} = store
|
|
98
96
|
const {
|
|
@@ -102,7 +100,6 @@ export default function Sidebar (props) {
|
|
|
102
100
|
shouldUpgrade
|
|
103
101
|
} = upgradeInfo
|
|
104
102
|
const showSetting = showModal === modals.setting
|
|
105
|
-
const showBatchOp = showModal === modals.batchOps
|
|
106
103
|
const settingActive = showSetting && settingTab === settingMap.setting && settingItem.id === 'setting-common'
|
|
107
104
|
const syncActive = showSetting && settingTab === settingMap.setting && settingItem.id === 'setting-sync'
|
|
108
105
|
const themeActive = showSetting && settingTab === settingMap.terminalThemes
|
|
@@ -190,12 +187,6 @@ export default function Sidebar (props) {
|
|
|
190
187
|
spin={isSyncingSetting}
|
|
191
188
|
/>
|
|
192
189
|
</SideIcon>
|
|
193
|
-
<SideIcon
|
|
194
|
-
title={e('batchOp')}
|
|
195
|
-
active={showBatchOp}
|
|
196
|
-
>
|
|
197
|
-
<BarsOutlined className='iblock font20 control-icon' onClick={toggleBatchOp} />
|
|
198
|
-
</SideIcon>
|
|
199
190
|
<SideIcon
|
|
200
191
|
title={e('widgets')}
|
|
201
192
|
active={widgetsActive}
|
|
@@ -75,7 +75,7 @@ export default function AddBtnMenu ({
|
|
|
75
75
|
|
|
76
76
|
let listContent
|
|
77
77
|
if (activeTab === 'bookmarks') {
|
|
78
|
-
listContent = <BookmarksList store={window.store} />
|
|
78
|
+
listContent = <BookmarksList store={window.store} autoFocus />
|
|
79
79
|
} else {
|
|
80
80
|
listContent = <History store={window.store} />
|
|
81
81
|
}
|
|
@@ -40,15 +40,18 @@ export default class AddBtn extends Component {
|
|
|
40
40
|
componentWillUnmount () {
|
|
41
41
|
if (this.state.open) {
|
|
42
42
|
document.removeEventListener('click', this.handleDocumentClick)
|
|
43
|
+
document.removeEventListener('keydown', this.handleKeyDown)
|
|
43
44
|
}
|
|
44
45
|
// Clean up portal container
|
|
45
46
|
if (this.portalContainer) {
|
|
46
47
|
document.body.removeChild(this.portalContainer)
|
|
47
48
|
this.portalContainer = null
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
handleKeyDown = (e) => {
|
|
53
|
+
if (e.key === 'Escape') {
|
|
54
|
+
this.setState({ open: false })
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
|
|
@@ -56,8 +59,10 @@ export default class AddBtn extends Component {
|
|
|
56
59
|
// Attach or detach document click listener only when menu open state changes
|
|
57
60
|
if (this.state.open && !prevState.open) {
|
|
58
61
|
document.addEventListener('click', this.handleDocumentClick)
|
|
62
|
+
document.addEventListener('keydown', this.handleKeyDown)
|
|
59
63
|
} else if (!this.state.open && prevState.open) {
|
|
60
64
|
document.removeEventListener('click', this.handleDocumentClick)
|
|
65
|
+
document.removeEventListener('keydown', this.handleKeyDown)
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
|
|
@@ -115,17 +120,6 @@ export default class AddBtn extends Component {
|
|
|
115
120
|
)
|
|
116
121
|
}
|
|
117
122
|
|
|
118
|
-
focusSearchInput = () => {
|
|
119
|
-
// Focus the search input after the menu renders
|
|
120
|
-
this.focusTimeout = setTimeout(() => {
|
|
121
|
-
const searchInput = this.menuRef.current?.querySelector('.add-menu-list .ant-input')
|
|
122
|
-
if (searchInput) {
|
|
123
|
-
searchInput.focus()
|
|
124
|
-
searchInput.select()
|
|
125
|
-
}
|
|
126
|
-
}, 500)
|
|
127
|
-
}
|
|
128
|
-
|
|
129
123
|
handleAddBtnClick = () => {
|
|
130
124
|
if (this.state.open) {
|
|
131
125
|
this.setState({ open: false })
|
|
@@ -172,7 +166,7 @@ export default class AddBtn extends Component {
|
|
|
172
166
|
menuPosition,
|
|
173
167
|
menuTop,
|
|
174
168
|
menuLeft
|
|
175
|
-
}
|
|
169
|
+
})
|
|
176
170
|
|
|
177
171
|
window.openTabBatch = this.props.batch
|
|
178
172
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useRef, useEffect } from 'react'
|
|
2
|
-
import { Button, Space } from 'antd'
|
|
2
|
+
import { Button, Space, Input } from 'antd'
|
|
3
3
|
import { ArrowRightOutlined, ThunderboltOutlined } from '@ant-design/icons'
|
|
4
4
|
import message from '../common/message'
|
|
5
5
|
import InputAutoFocus from '../common/input-auto-focus'
|
|
@@ -29,18 +29,14 @@ export default function QuickConnect ({ batch, inputOnly }) {
|
|
|
29
29
|
const [inputValue, setInputValue] = useState('')
|
|
30
30
|
const inputRef = useRef(null)
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
if (showInput && inputRef.current) {
|
|
34
|
-
inputRef.current.focus()
|
|
35
|
-
}
|
|
36
|
-
}, [showInput])
|
|
37
|
-
|
|
38
|
-
// When inputOnly is true, always show the input
|
|
32
|
+
// When inputOnly is true, always show the input (without auto-focus)
|
|
39
33
|
useEffect(() => {
|
|
40
34
|
if (inputOnly) {
|
|
41
35
|
setShowInput(true)
|
|
36
|
+
} else if (showInput && inputRef.current) {
|
|
37
|
+
inputRef.current.focus()
|
|
42
38
|
}
|
|
43
|
-
}, [inputOnly])
|
|
39
|
+
}, [inputOnly, showInput])
|
|
44
40
|
|
|
45
41
|
const handleToggle = () => {
|
|
46
42
|
setShowInput(!showInput)
|
|
@@ -94,7 +90,7 @@ export default function QuickConnect ({ batch, inputOnly }) {
|
|
|
94
90
|
<Button
|
|
95
91
|
{...iconsProps1}
|
|
96
92
|
/>
|
|
97
|
-
<InputAutoFocus {...inputProps} />
|
|
93
|
+
{inputOnly ? <Input {...inputProps} /> : <InputAutoFocus {...inputProps} />}
|
|
98
94
|
<Button
|
|
99
95
|
{...iconProps}
|
|
100
96
|
/>
|
|
@@ -378,11 +378,10 @@ class Term extends Component {
|
|
|
378
378
|
}
|
|
379
379
|
|
|
380
380
|
runQuickCommand = (cmd, inputOnly = false) => {
|
|
381
|
-
this.term && this.attachAddon
|
|
382
|
-
cmd +
|
|
383
|
-
(
|
|
384
|
-
|
|
385
|
-
this.term.focus()
|
|
381
|
+
if (this.term && this.attachAddon) {
|
|
382
|
+
this.attachAddon._sendData(cmd + (inputOnly ? '' : '\r'))
|
|
383
|
+
this.term.focus()
|
|
384
|
+
}
|
|
386
385
|
}
|
|
387
386
|
|
|
388
387
|
cd = (p) => {
|