@electerm/electerm-react 1.70.6 → 1.72.16
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/cache.js +56 -0
- package/client/common/constants.js +2 -0
- package/client/common/default-setting.js +2 -1
- package/client/common/download.jsx +5 -7
- package/client/common/setting-list.js +27 -0
- package/client/components/ai/ai-cache.jsx +36 -0
- package/client/components/ai/ai-chat-history-item.jsx +1 -1
- package/client/components/ai/ai-chat.jsx +5 -40
- package/client/components/ai/ai-config-props.js +7 -0
- package/client/components/ai/ai-config.jsx +5 -14
- package/client/components/ai/ai.styl +0 -4
- package/client/components/ai/providers.js +2 -2
- package/client/components/batch-op/batch-op-entry.jsx +1 -1
- package/client/components/batch-op/batch-op.jsx +2 -2
- package/client/components/bookmark-form/form-ssh-common.jsx +2 -3
- package/client/components/bookmark-form/form-tabs.jsx +2 -2
- package/client/components/bookmark-form/render-connection-hopping.jsx +2 -2
- package/client/components/bookmark-form/render-delayed-scripts.jsx +4 -4
- package/client/components/bookmark-form/render-ssh-tunnel.jsx +2 -2
- package/client/components/bookmark-form/sftp-enable.jsx +9 -0
- package/client/components/bookmark-form/ssh-form-ui.jsx +1 -0
- package/client/components/bookmark-form/ssh-form.jsx +3 -0
- package/client/components/bookmark-form/use-quick-commands.jsx +2 -2
- package/client/components/bookmark-form/x11.jsx +78 -9
- package/client/components/common/input-auto-focus.jsx +3 -11
- package/client/components/layout/layout.jsx +2 -1
- package/client/components/main/main.jsx +5 -0
- package/client/components/profile/profile-form-elem.jsx +1 -3
- package/client/components/quick-commands/quick-commands-form-elem.jsx +1 -3
- package/client/components/quick-commands/quick-commands-list-form.jsx +2 -2
- package/client/components/session/session.jsx +80 -19
- package/client/components/session/session.styl +10 -3
- package/client/components/session/sessions.jsx +2 -1
- package/client/components/setting-panel/keywords-form.jsx +36 -38
- package/client/components/setting-panel/setting-modal.jsx +2 -2
- package/client/components/setting-panel/setting-terminal.jsx +2 -1
- package/client/components/setting-panel/tab-settings.jsx +26 -0
- package/client/components/sftp/address-bar.jsx +9 -2
- package/client/components/sftp/address-bookmark.jsx +4 -6
- package/client/components/sftp/file-item.jsx +1 -1
- package/client/components/sftp/file-read.js +14 -19
- package/client/components/sftp/keyword-filter.jsx +63 -0
- package/client/components/sftp/list-table-ui.jsx +7 -9
- package/client/components/sftp/sftp-entry.jsx +46 -9
- package/client/components/sftp/sftp.styl +6 -1
- package/client/components/sftp/transfer-conflict-store.jsx +1 -1
- package/client/components/shortcuts/shortcut-control.jsx +20 -0
- package/client/components/shortcuts/shortcut-editor.jsx +2 -2
- package/client/components/shortcuts/shortcuts.jsx +2 -2
- package/client/components/sidebar/info-modal.jsx +2 -2
- package/client/components/sidebar/transfer-list-control.jsx +18 -20
- package/client/components/ssh-config/ssh-config-item.jsx +2 -4
- package/client/components/ssh-config/ssh-config-load-notify.jsx +2 -2
- package/client/components/sys-menu/zoom.jsx +2 -2
- package/client/components/tabs/index.jsx +1 -1
- package/client/components/tabs/tab.jsx +3 -3
- package/client/components/terminal/cmd-item.jsx +32 -0
- package/client/components/terminal/command-tracker-addon.js +3 -1
- package/client/components/terminal/term-search.jsx +5 -6
- package/client/components/terminal/terminal-command-dropdown.jsx +303 -0
- package/client/components/terminal/terminal.jsx +88 -8
- package/client/components/terminal/terminal.styl +58 -0
- package/client/components/terminal-info/terminal-info.jsx +2 -2
- package/client/components/tree-list/tree-list.jsx +1 -1
- package/client/components/web/address-bar.jsx +2 -2
- package/client/store/common.js +27 -2
- package/client/store/init-state.js +3 -3
- package/client/store/item.js +2 -1
- package/client/store/setting.js +3 -2
- package/client/store/store.js +23 -24
- package/client/store/watch.js +7 -1
- package/package.json +1 -1
|
@@ -4,22 +4,14 @@ import {
|
|
|
4
4
|
} from 'antd'
|
|
5
5
|
|
|
6
6
|
export default function InputAutoFocus (props) {
|
|
7
|
-
const { type,
|
|
7
|
+
const { type, ...rest } = props
|
|
8
8
|
const inputRef = useRef(null)
|
|
9
|
-
const isFirstRender = useRef(true)
|
|
10
9
|
|
|
11
10
|
useEffect(() => {
|
|
12
11
|
if (inputRef.current) {
|
|
13
|
-
|
|
14
|
-
if (value && selectall && isFirstRender.current) {
|
|
15
|
-
inputRef.current.focus()
|
|
16
|
-
inputRef.current.setSelectionRange(0, value.length)
|
|
17
|
-
isFirstRender.current = false
|
|
18
|
-
} else {
|
|
19
|
-
inputRef.current.focus()
|
|
20
|
-
}
|
|
12
|
+
inputRef.current.focus()
|
|
21
13
|
}
|
|
22
|
-
}, [props.value
|
|
14
|
+
}, [props.value])
|
|
23
15
|
|
|
24
16
|
let InputComponent
|
|
25
17
|
switch (type) {
|
|
@@ -14,6 +14,7 @@ import Resolutions from '../rdp/resolution-edit'
|
|
|
14
14
|
import TerminalInteractive from '../terminal/terminal-interactive'
|
|
15
15
|
import ConfirmModalStore from '../sftp/confirm-modal-store.jsx'
|
|
16
16
|
import TransferConflictStore from '../sftp/transfer-conflict-store.jsx'
|
|
17
|
+
import TerminalCmdSuggestions from '../terminal/terminal-command-dropdown'
|
|
17
18
|
import TransportsActionStore from '../sftp/transports-action-store.jsx'
|
|
18
19
|
import classnames from 'classnames'
|
|
19
20
|
import ShortcutControl from '../shortcuts/shortcut-control.jsx'
|
|
@@ -221,6 +222,9 @@ export default auto(function Index (props) {
|
|
|
221
222
|
showAIConfig: store.showAIConfig,
|
|
222
223
|
rightPanelTab
|
|
223
224
|
}
|
|
225
|
+
const cmdSuggestionsProps = {
|
|
226
|
+
suggestions: store.terminalCommandSuggestions
|
|
227
|
+
}
|
|
224
228
|
return (
|
|
225
229
|
<ConfigProvider
|
|
226
230
|
theme={uiThemeConfig}
|
|
@@ -281,6 +285,7 @@ export default auto(function Index (props) {
|
|
|
281
285
|
sshConfigs={store.sshConfigs}
|
|
282
286
|
/>
|
|
283
287
|
<ConnectionHoppingWarning {...warningProps} />
|
|
288
|
+
<TerminalCmdSuggestions {...cmdSuggestionsProps} />
|
|
284
289
|
</div>
|
|
285
290
|
</ConfigProvider>
|
|
286
291
|
)
|
|
@@ -113,7 +113,7 @@ export default function renderQm () {
|
|
|
113
113
|
{
|
|
114
114
|
(fields, { add, remove }, { errors }) => {
|
|
115
115
|
return (
|
|
116
|
-
|
|
116
|
+
<>
|
|
117
117
|
{
|
|
118
118
|
fields.map((field, i) => {
|
|
119
119
|
return renderItem(field, i, add, remove)
|
|
@@ -129,7 +129,7 @@ export default function renderQm () {
|
|
|
129
129
|
{e('quickCommand')}
|
|
130
130
|
</Button>
|
|
131
131
|
</FormItem>
|
|
132
|
-
|
|
132
|
+
</>
|
|
133
133
|
)
|
|
134
134
|
}
|
|
135
135
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* terminal/sftp wrapper
|
|
3
3
|
*/
|
|
4
4
|
import { createRef } from 'react'
|
|
5
|
-
import { Component } from '
|
|
5
|
+
import { Component } from 'manate/react/class-components'
|
|
6
6
|
import Term from '../terminal/terminal.jsx'
|
|
7
7
|
import Sftp from '../sftp/sftp-entry'
|
|
8
8
|
import RdpSession from '../rdp/rdp-session'
|
|
@@ -12,7 +12,8 @@ import {
|
|
|
12
12
|
SearchOutlined,
|
|
13
13
|
FullscreenOutlined,
|
|
14
14
|
PaperClipOutlined,
|
|
15
|
-
CloseOutlined
|
|
15
|
+
CloseOutlined,
|
|
16
|
+
ApartmentOutlined
|
|
16
17
|
} from '@ant-design/icons'
|
|
17
18
|
import {
|
|
18
19
|
Tooltip,
|
|
@@ -29,7 +30,8 @@ import {
|
|
|
29
30
|
terminalRdpType,
|
|
30
31
|
terminalVncType,
|
|
31
32
|
terminalWebType,
|
|
32
|
-
terminalTelnetType
|
|
33
|
+
terminalTelnetType,
|
|
34
|
+
splitMap
|
|
33
35
|
} from '../../common/constants'
|
|
34
36
|
import { SplitViewIcon } from '../icons/split-view'
|
|
35
37
|
import { refs } from '../common/ref'
|
|
@@ -50,7 +52,8 @@ export default class SessionWrapper extends Component {
|
|
|
50
52
|
splitSize: [50, 50],
|
|
51
53
|
sessionOptions: null,
|
|
52
54
|
sessionId: generate(),
|
|
53
|
-
delKeyPressed: false
|
|
55
|
+
delKeyPressed: false,
|
|
56
|
+
broadcastInput: false
|
|
54
57
|
}
|
|
55
58
|
props.tab.sshSftpSplitView = !!props.config.sshSftpSplitView
|
|
56
59
|
}
|
|
@@ -71,6 +74,19 @@ export default class SessionWrapper extends Component {
|
|
|
71
74
|
return this.domRef.current
|
|
72
75
|
}
|
|
73
76
|
|
|
77
|
+
isDisabled = () => {
|
|
78
|
+
const { enableSsh, enableSftp } = this.props.tab
|
|
79
|
+
return enableSsh === false || enableSftp === false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
isSshDisabled = () => {
|
|
83
|
+
return this.props.tab.enableSsh === false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
isSftpDisabled = () => {
|
|
87
|
+
return this.props.tab.enableSftp === false
|
|
88
|
+
}
|
|
89
|
+
|
|
74
90
|
handleSshSftpSplitView = () => {
|
|
75
91
|
const nv = !this.props.tab.sshSftpSplitView
|
|
76
92
|
this.editTab({
|
|
@@ -82,10 +98,9 @@ export default class SessionWrapper extends Component {
|
|
|
82
98
|
canSplitView = () => {
|
|
83
99
|
const {
|
|
84
100
|
width,
|
|
85
|
-
height
|
|
86
|
-
tab
|
|
101
|
+
height
|
|
87
102
|
} = this.props
|
|
88
|
-
if (
|
|
103
|
+
if (this.isDisabled()) {
|
|
89
104
|
return false
|
|
90
105
|
}
|
|
91
106
|
return width > this.minWithForSplit ||
|
|
@@ -222,7 +237,7 @@ export default class SessionWrapper extends Component {
|
|
|
222
237
|
const update = {
|
|
223
238
|
pane
|
|
224
239
|
}
|
|
225
|
-
if (pane === paneMap.fileManager
|
|
240
|
+
if (pane === paneMap.fileManager) {
|
|
226
241
|
this.setState({
|
|
227
242
|
enableSftp: true
|
|
228
243
|
})
|
|
@@ -253,7 +268,8 @@ export default class SessionWrapper extends Component {
|
|
|
253
268
|
const {
|
|
254
269
|
sessionOptions,
|
|
255
270
|
sessionId,
|
|
256
|
-
sftpPathFollowSsh
|
|
271
|
+
sftpPathFollowSsh,
|
|
272
|
+
broadcastInput
|
|
257
273
|
} = this.state
|
|
258
274
|
const {
|
|
259
275
|
tab
|
|
@@ -312,7 +328,6 @@ export default class SessionWrapper extends Component {
|
|
|
312
328
|
}
|
|
313
329
|
|
|
314
330
|
const cls = pane === paneMap.terminal ||
|
|
315
|
-
pane === paneMap.ssh ||
|
|
316
331
|
(sshSftpSplitView && this.canSplitView())
|
|
317
332
|
? 'terms-box'
|
|
318
333
|
: 'terms-box hide'
|
|
@@ -326,6 +341,7 @@ export default class SessionWrapper extends Component {
|
|
|
326
341
|
...this.props,
|
|
327
342
|
sftpPathFollowSsh,
|
|
328
343
|
themeConfig,
|
|
344
|
+
broadcastInput,
|
|
329
345
|
pane,
|
|
330
346
|
...pick(
|
|
331
347
|
this,
|
|
@@ -416,14 +432,15 @@ export default class SessionWrapper extends Component {
|
|
|
416
432
|
} = this.state
|
|
417
433
|
const { pane, id, sshSftpSplitView } = this.props.tab
|
|
418
434
|
if (
|
|
419
|
-
this.isNotTerminalType()
|
|
435
|
+
this.isNotTerminalType() ||
|
|
436
|
+
this.isSftpDisabled()
|
|
420
437
|
) {
|
|
421
438
|
return null
|
|
422
439
|
}
|
|
423
440
|
const height = this.props.computeHeight(
|
|
424
441
|
this.props.height
|
|
425
442
|
)
|
|
426
|
-
const cls = pane === paneMap.fileManager ||
|
|
443
|
+
const cls = pane === paneMap.fileManager ||
|
|
427
444
|
(sshSftpSplitView && this.canSplitView())
|
|
428
445
|
? ''
|
|
429
446
|
: 'hide'
|
|
@@ -453,6 +470,12 @@ export default class SessionWrapper extends Component {
|
|
|
453
470
|
window.store.toggleTermFullscreen(true)
|
|
454
471
|
}
|
|
455
472
|
|
|
473
|
+
toggleBroadcastInput = () => {
|
|
474
|
+
this.setState({
|
|
475
|
+
broadcastInput: !this.state.broadcastInput
|
|
476
|
+
})
|
|
477
|
+
}
|
|
478
|
+
|
|
456
479
|
handleOpenSearch = () => {
|
|
457
480
|
refs.get('term-' + this.props.tab.id)?.toggleSearch()
|
|
458
481
|
}
|
|
@@ -462,7 +485,7 @@ export default class SessionWrapper extends Component {
|
|
|
462
485
|
return (
|
|
463
486
|
<Tooltip title={title} placement='bottomLeft'>
|
|
464
487
|
<SearchOutlined
|
|
465
|
-
className='mg1r icon-info
|
|
488
|
+
className='mg1r icon-info iblock pointer spliter'
|
|
466
489
|
onClick={this.handleOpenSearch}
|
|
467
490
|
/>
|
|
468
491
|
</Tooltip>
|
|
@@ -474,7 +497,7 @@ export default class SessionWrapper extends Component {
|
|
|
474
497
|
return (
|
|
475
498
|
<Tooltip title={title} placement='bottomLeft'>
|
|
476
499
|
<FullscreenOutlined
|
|
477
|
-
className='mg1r icon-info
|
|
500
|
+
className='mg1r icon-info iblock pointer spliter term-fullscreen-control1'
|
|
478
501
|
onClick={this.handleFullscreen}
|
|
479
502
|
/>
|
|
480
503
|
</Tooltip>
|
|
@@ -496,6 +519,29 @@ export default class SessionWrapper extends Component {
|
|
|
496
519
|
)
|
|
497
520
|
}
|
|
498
521
|
|
|
522
|
+
renderBroadcastIcon = () => {
|
|
523
|
+
if (
|
|
524
|
+
this.props.layout === splitMap.c1 ||
|
|
525
|
+
this.isSshDisabled()
|
|
526
|
+
) {
|
|
527
|
+
return null
|
|
528
|
+
}
|
|
529
|
+
const { broadcastInput } = this.state
|
|
530
|
+
const title = e('broadcastInput')
|
|
531
|
+
const iconProps = {
|
|
532
|
+
className: classnames('sess-icon pointer broadcast-icon', {
|
|
533
|
+
active: broadcastInput
|
|
534
|
+
}),
|
|
535
|
+
onClick: this.toggleBroadcastInput
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return (
|
|
539
|
+
<Tooltip title={title}>
|
|
540
|
+
<ApartmentOutlined {...iconProps} />
|
|
541
|
+
</Tooltip>
|
|
542
|
+
)
|
|
543
|
+
}
|
|
544
|
+
|
|
499
545
|
renderTermControls = () => {
|
|
500
546
|
const { props } = this
|
|
501
547
|
const { pane } = props.tab
|
|
@@ -515,10 +561,19 @@ export default class SessionWrapper extends Component {
|
|
|
515
561
|
return null
|
|
516
562
|
}
|
|
517
563
|
const title = e('sshSftpSplitView')
|
|
564
|
+
const {
|
|
565
|
+
sshSftpSplitView
|
|
566
|
+
} = this.props.tab
|
|
567
|
+
const cls = classnames(
|
|
568
|
+
'pointer sess-icon split-view-toggle',
|
|
569
|
+
{
|
|
570
|
+
active: sshSftpSplitView
|
|
571
|
+
}
|
|
572
|
+
)
|
|
518
573
|
return (
|
|
519
574
|
<Tooltip title={title} placement='bottomLeft'>
|
|
520
575
|
<span
|
|
521
|
-
className=
|
|
576
|
+
className={cls}
|
|
522
577
|
onClick={this.handleSshSftpSplitView}
|
|
523
578
|
>
|
|
524
579
|
<SplitViewIcon />
|
|
@@ -536,6 +591,9 @@ export default class SessionWrapper extends Component {
|
|
|
536
591
|
const {
|
|
537
592
|
sshSftpSplitView
|
|
538
593
|
} = this.props.tab
|
|
594
|
+
if (this.isDisabled()) {
|
|
595
|
+
return null
|
|
596
|
+
}
|
|
539
597
|
if (sshSftpSplitView && this.canSplitView()) {
|
|
540
598
|
return null
|
|
541
599
|
}
|
|
@@ -591,6 +649,9 @@ export default class SessionWrapper extends Component {
|
|
|
591
649
|
}
|
|
592
650
|
|
|
593
651
|
renderSftpPathFollowControl = () => {
|
|
652
|
+
if (this.isDisabled()) {
|
|
653
|
+
return null
|
|
654
|
+
}
|
|
594
655
|
const {
|
|
595
656
|
sftpPathFollowSsh
|
|
596
657
|
} = this.state
|
|
@@ -604,14 +665,13 @@ export default class SessionWrapper extends Component {
|
|
|
604
665
|
const checkProps = {
|
|
605
666
|
onClick: this.toggleCheckSftpPathFollowSsh,
|
|
606
667
|
className: classnames(
|
|
607
|
-
'sftp-follow-ssh-icon',
|
|
668
|
+
'sftp-follow-ssh-icon sess-icon pointer',
|
|
608
669
|
{
|
|
609
670
|
active: sftpPathFollowSsh
|
|
610
671
|
}
|
|
611
672
|
)
|
|
612
673
|
}
|
|
613
674
|
const isS = pane === paneMap.terminal ||
|
|
614
|
-
pane === paneMap.ssh ||
|
|
615
675
|
sshSftpSplitView
|
|
616
676
|
return (
|
|
617
677
|
<>
|
|
@@ -646,6 +706,7 @@ export default class SessionWrapper extends Component {
|
|
|
646
706
|
{this.renderPaneControl()}
|
|
647
707
|
{this.renderSftpPathFollowControl()}
|
|
648
708
|
{this.renderSplitToggle()}
|
|
709
|
+
{this.renderBroadcastIcon()}
|
|
649
710
|
{this.renderTermControls()}
|
|
650
711
|
</div>
|
|
651
712
|
)
|
|
@@ -670,8 +731,8 @@ export default class SessionWrapper extends Component {
|
|
|
670
731
|
}
|
|
671
732
|
const notSplitVew = !this.canSplitView() || !this.props.tab.sshSftpSplitView
|
|
672
733
|
const { pane } = this.props.tab
|
|
673
|
-
const show1 = notSplitVew &&
|
|
674
|
-
const show2 = notSplitVew &&
|
|
734
|
+
const show1 = notSplitVew && pane === paneMap.terminal
|
|
735
|
+
const show2 = notSplitVew && pane === paneMap.fileManager
|
|
675
736
|
const direction = this.getSplitDirection()
|
|
676
737
|
const layout = direction === 'leftRight' ? 'horizontal' : 'vertical'
|
|
677
738
|
const [size1, size2] = this.state.splitSize
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
position relative
|
|
17
17
|
display inline-block
|
|
18
18
|
|
|
19
|
-
.sftp-follow-ssh-icon
|
|
20
19
|
.type-tab
|
|
21
20
|
display inline-block
|
|
22
21
|
vertical-align middle
|
|
@@ -44,7 +43,6 @@
|
|
|
44
43
|
display none
|
|
45
44
|
.spliter
|
|
46
45
|
color text
|
|
47
|
-
font-size 16px
|
|
48
46
|
&:hover
|
|
49
47
|
color text-light
|
|
50
48
|
|
|
@@ -73,4 +71,13 @@
|
|
|
73
71
|
width auto !important
|
|
74
72
|
height auto !important
|
|
75
73
|
.not-split-view .ant-splitter-bar-dragger
|
|
76
|
-
display none
|
|
74
|
+
display none
|
|
75
|
+
|
|
76
|
+
.sess-icon
|
|
77
|
+
margin-right 10px
|
|
78
|
+
&.active
|
|
79
|
+
color warn
|
|
80
|
+
|
|
81
|
+
.split-view-toggle
|
|
82
|
+
&.active
|
|
83
|
+
color success
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component } from '
|
|
1
|
+
import { Component } from 'manate/react/class-components'
|
|
2
2
|
import Session from './session.jsx'
|
|
3
3
|
|
|
4
4
|
import { pick } from 'lodash-es'
|
|
@@ -62,6 +62,7 @@ export default class Sessions extends Component {
|
|
|
62
62
|
}
|
|
63
63
|
const sessProps = {
|
|
64
64
|
activeTabId,
|
|
65
|
+
layout: this.props.layout,
|
|
65
66
|
tab,
|
|
66
67
|
width,
|
|
67
68
|
height,
|
|
@@ -107,44 +107,42 @@ export default function KeywordForm (props) {
|
|
|
107
107
|
}, [props.keywordFormReset])
|
|
108
108
|
|
|
109
109
|
return (
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
>
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
{
|
|
122
|
-
(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
)
|
|
143
|
-
}
|
|
110
|
+
<Form
|
|
111
|
+
form={formChild}
|
|
112
|
+
onValuesChange={handleTrigger}
|
|
113
|
+
initialValues={formData}
|
|
114
|
+
onFinish={handleFinish}
|
|
115
|
+
>
|
|
116
|
+
<FormItem {...formItemLayout}>
|
|
117
|
+
<FormList
|
|
118
|
+
name='keywords'
|
|
119
|
+
>
|
|
120
|
+
{
|
|
121
|
+
(fields, { add, remove }, { errors }) => {
|
|
122
|
+
return (
|
|
123
|
+
<>
|
|
124
|
+
{
|
|
125
|
+
fields.map((field, i) => {
|
|
126
|
+
return renderItem(field, i, add, remove)
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
<FormItem>
|
|
130
|
+
<Button
|
|
131
|
+
type='dashed'
|
|
132
|
+
onClick={() => add({
|
|
133
|
+
color: 'red'
|
|
134
|
+
})}
|
|
135
|
+
icon={<PlusOutlined />}
|
|
136
|
+
>
|
|
137
|
+
{e('keyword')}
|
|
138
|
+
</Button>
|
|
139
|
+
</FormItem>
|
|
140
|
+
</>
|
|
141
|
+
)
|
|
144
142
|
}
|
|
145
|
-
|
|
146
|
-
</
|
|
147
|
-
</
|
|
148
|
-
</
|
|
143
|
+
}
|
|
144
|
+
</FormList>
|
|
145
|
+
</FormItem>
|
|
146
|
+
</Form>
|
|
149
147
|
)
|
|
150
148
|
}
|
|
@@ -104,7 +104,7 @@ export default auto(function SettingModalWrap (props) {
|
|
|
104
104
|
type: 'card'
|
|
105
105
|
}
|
|
106
106
|
return (
|
|
107
|
-
|
|
107
|
+
<>
|
|
108
108
|
<Tabs
|
|
109
109
|
{...tabsProps}
|
|
110
110
|
/>
|
|
@@ -141,7 +141,7 @@ export default auto(function SettingModalWrap (props) {
|
|
|
141
141
|
store={store}
|
|
142
142
|
settingTab={settingTab}
|
|
143
143
|
/>
|
|
144
|
-
|
|
144
|
+
</>
|
|
145
145
|
)
|
|
146
146
|
}
|
|
147
147
|
|
|
@@ -594,7 +594,8 @@ export default class SettingTerminal extends Component {
|
|
|
594
594
|
'copyWhenSelect',
|
|
595
595
|
'ctrlOrMetaOpenTerminalLink',
|
|
596
596
|
'sftpPathFollowSsh',
|
|
597
|
-
'sshSftpSplitView'
|
|
597
|
+
'sshSftpSplitView',
|
|
598
|
+
'showCmdSuggestions'
|
|
598
599
|
].map(d => this.renderToggle(d))
|
|
599
600
|
}
|
|
600
601
|
<div className='pd1b'>{e('terminalBackSpaceMode')}</div>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { auto } from 'manate/react'
|
|
2
|
+
import { message } from 'antd'
|
|
2
3
|
import SettingCommon from './setting-common'
|
|
3
4
|
import SettingTerminal from './setting-terminal'
|
|
4
5
|
import SettingCol from './col'
|
|
6
|
+
import SettingAi from '../ai/ai-config'
|
|
5
7
|
import SyncSetting from '../setting-sync/setting-sync'
|
|
6
8
|
import Shortcuts from '../shortcuts/shortcuts'
|
|
7
9
|
import List from './list'
|
|
@@ -9,8 +11,10 @@ import {
|
|
|
9
11
|
settingMap,
|
|
10
12
|
settingSyncId,
|
|
11
13
|
settingTerminalId,
|
|
14
|
+
settingAiId,
|
|
12
15
|
settingShortcutsId
|
|
13
16
|
} from '../../common/constants'
|
|
17
|
+
import { aiConfigsArr } from '../ai/ai-config-props'
|
|
14
18
|
import { pick } from 'lodash-es'
|
|
15
19
|
|
|
16
20
|
export default auto(function TabSettings (props) {
|
|
@@ -26,6 +30,26 @@ export default auto(function TabSettings (props) {
|
|
|
26
30
|
store
|
|
27
31
|
} = props
|
|
28
32
|
let elem = null
|
|
33
|
+
|
|
34
|
+
function getInitialValues () {
|
|
35
|
+
const res = pick(props.store.config, aiConfigsArr)
|
|
36
|
+
if (!res.languageAI) {
|
|
37
|
+
res.languageAI = window.store.getLangName()
|
|
38
|
+
}
|
|
39
|
+
return res
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function handleConfigSubmit (values) {
|
|
43
|
+
window.store.updateConfig(values)
|
|
44
|
+
message.success('Saved')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const aiConfProps = {
|
|
48
|
+
initialValues: getInitialValues(),
|
|
49
|
+
onSubmit: handleConfigSubmit,
|
|
50
|
+
showAIConfig: true
|
|
51
|
+
}
|
|
52
|
+
|
|
29
53
|
const sid = settingItem.id
|
|
30
54
|
if (sid === settingSyncId) {
|
|
31
55
|
const syncProps = pick(store, [
|
|
@@ -37,6 +61,8 @@ export default auto(function TabSettings (props) {
|
|
|
37
61
|
'syncServerStatus'
|
|
38
62
|
])
|
|
39
63
|
elem = <SyncSetting {...syncProps} />
|
|
64
|
+
} else if (sid === settingAiId) {
|
|
65
|
+
elem = <SettingAi {...aiConfProps} />
|
|
40
66
|
} else if (sid === settingTerminalId) {
|
|
41
67
|
elem = <SettingTerminal {...listProps} config={store.config} />
|
|
42
68
|
} else if (sid === settingShortcutsId) {
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from '../../common/constants'
|
|
16
16
|
import classnames from 'classnames'
|
|
17
17
|
import AddrBookmark from './address-bookmark'
|
|
18
|
+
import KeywordFilter from './keyword-filter'
|
|
18
19
|
|
|
19
20
|
const e = window.translate
|
|
20
21
|
|
|
@@ -26,8 +27,13 @@ function renderAddonBefore (props, realPath) {
|
|
|
26
27
|
const isShow = props[`${type}ShowHiddenFile`]
|
|
27
28
|
const title = `${isShow ? e('hide') : e('show')} ${e('hfd')}`
|
|
28
29
|
const Icon = isShow ? EyeFilled : EyeInvisibleFilled
|
|
30
|
+
const keywordProps = {
|
|
31
|
+
keyword: props[`${type}Keyword`],
|
|
32
|
+
type,
|
|
33
|
+
updateKeyword: props.updateKeyword
|
|
34
|
+
}
|
|
29
35
|
return (
|
|
30
|
-
|
|
36
|
+
<>
|
|
31
37
|
<Tooltip
|
|
32
38
|
title={title}
|
|
33
39
|
placement='topLeft'
|
|
@@ -49,6 +55,7 @@ function renderAddonBefore (props, realPath) {
|
|
|
49
55
|
className='mg1r'
|
|
50
56
|
/>
|
|
51
57
|
</Tooltip>
|
|
58
|
+
<KeywordFilter {...keywordProps} />
|
|
52
59
|
<AddrBookmark
|
|
53
60
|
store={window.store}
|
|
54
61
|
realPath={realPath}
|
|
@@ -56,7 +63,7 @@ function renderAddonBefore (props, realPath) {
|
|
|
56
63
|
type={type}
|
|
57
64
|
onClickHistory={props.onClickHistory}
|
|
58
65
|
/>
|
|
59
|
-
|
|
66
|
+
</>
|
|
60
67
|
)
|
|
61
68
|
}
|
|
62
69
|
|
|
@@ -62,12 +62,10 @@ export default auto(function AddrBookmark (props) {
|
|
|
62
62
|
</div>
|
|
63
63
|
)
|
|
64
64
|
const title = (
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/>
|
|
70
|
-
</div>
|
|
65
|
+
<PlusSquareOutlined
|
|
66
|
+
className='add-addr-bookmark'
|
|
67
|
+
onClick={handleAddAddr}
|
|
68
|
+
/>
|
|
71
69
|
)
|
|
72
70
|
return (
|
|
73
71
|
<Popover
|
|
@@ -43,25 +43,20 @@ export const getFolderFromFilePath = (filePath, isRemote) => {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export const getLocalFileInfo = async (filePath) => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
isSymbolicLink: stat.isSymbolicLink
|
|
61
|
-
}
|
|
62
|
-
} catch (e) {
|
|
63
|
-
log.debug(e)
|
|
64
|
-
return null
|
|
46
|
+
const statr = await fs.statAsync(filePath)
|
|
47
|
+
const stat = await fs.lstatAsync(filePath)
|
|
48
|
+
return {
|
|
49
|
+
size: stat.size,
|
|
50
|
+
accessTime: stat.atime,
|
|
51
|
+
modifyTime: stat.mtime,
|
|
52
|
+
mode: stat.mode,
|
|
53
|
+
owner: stat.uid,
|
|
54
|
+
group: stat.gid,
|
|
55
|
+
type: 'local',
|
|
56
|
+
...getFolderFromFilePath(filePath, false),
|
|
57
|
+
id: generate(),
|
|
58
|
+
isDirectory: statr.isDirectory,
|
|
59
|
+
isSymbolicLink: stat.isSymbolicLink
|
|
65
60
|
}
|
|
66
61
|
}
|
|
67
62
|
|