@electerm/electerm-react 3.11.12 → 3.15.0
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/bookmark-schemas.js +2 -1
- package/client/common/constants.js +11 -2
- package/client/common/is-absolute-path.js +1 -1
- package/client/common/normalize-remote-path.js +20 -0
- package/client/common/resolve.js +16 -0
- package/client/components/ai/agent-tools.js +204 -0
- package/client/components/ai/agent.js +12 -10
- package/client/components/ai/ai-chat-history-item.jsx +15 -25
- package/client/components/ai/ai-chat.jsx +24 -9
- package/client/components/bookmark-form/bookmark-schema.js +2 -1
- package/client/components/bookmark-form/config/serial.js +3 -2
- package/client/components/footer/cmd-history.jsx +20 -11
- package/client/components/main/main.jsx +1 -1
- package/client/components/sftp/address-bar.jsx +22 -6
- package/client/components/sftp/file-item.jsx +31 -1
- package/client/components/sftp/file-read.js +11 -2
- package/client/components/sftp/sftp-entry.jsx +38 -3
- package/client/components/shortcuts/shortcut-handler.js +7 -0
- package/client/components/sidebar/history.jsx +16 -8
- package/client/components/sys-menu/icons-map.jsx +10 -2
- package/client/components/terminal/attach-addon-custom.js +1 -1
- package/client/components/terminal/drop-file-modal.jsx +53 -22
- package/client/components/terminal/terminal-apis.js +9 -0
- package/client/components/terminal/terminal.jsx +179 -3
- package/client/components/terminal/xmodem-client.js +244 -0
- package/client/components/terminal-info/base.jsx +41 -38
- package/client/components/terminal-info/data-cols-parser.jsx +2 -1
- package/client/components/terminal-info/disk.jsx +4 -2
- package/client/components/terminal-info/log-path-edit.jsx +3 -2
- package/client/components/terminal-info/network.jsx +3 -1
- package/client/components/terminal-info/resource.jsx +3 -3
- package/client/components/tree-list/tree-list.styl +7 -1
- package/client/store/mcp-handler.js +41 -9
- package/client/store/quick-command.js +3 -2
- package/client/store/watch.js +1 -1
- package/package.json +1 -1
|
@@ -105,17 +105,11 @@ export default auto(function CmdHistory (props) {
|
|
|
105
105
|
))
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
onChange={handleChange}
|
|
114
|
-
placeholder={e('search')}
|
|
115
|
-
className='cmd-history-search-input'
|
|
116
|
-
allowClear
|
|
117
|
-
/>
|
|
118
|
-
</div>
|
|
108
|
+
function renderHeader () {
|
|
109
|
+
if (!historyArray.length) {
|
|
110
|
+
return null
|
|
111
|
+
}
|
|
112
|
+
return (
|
|
119
113
|
<div className='cmd-history-header pd2b'>
|
|
120
114
|
<Switch
|
|
121
115
|
checkedChildren={e('sortByFrequency')}
|
|
@@ -130,6 +124,21 @@ export default auto(function CmdHistory (props) {
|
|
|
130
124
|
onClick={handleClearAll}
|
|
131
125
|
/>
|
|
132
126
|
</div>
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const content = (
|
|
131
|
+
<div className='cmd-history-popover-content pd2'>
|
|
132
|
+
<div className='cmd-history-search pd2b'>
|
|
133
|
+
<InputAutoFocus
|
|
134
|
+
value={keyword}
|
|
135
|
+
onChange={handleChange}
|
|
136
|
+
placeholder={e('search')}
|
|
137
|
+
className='cmd-history-search-input'
|
|
138
|
+
allowClear
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
{renderHeader()}
|
|
133
142
|
<div className='cmd-history-list'>
|
|
134
143
|
{renderList()}
|
|
135
144
|
</div>
|
|
@@ -282,7 +282,7 @@ export default auto(function Index (props) {
|
|
|
282
282
|
<InfoModal {...infoModalProps} />
|
|
283
283
|
<RightSidePanel {...rightPanelProps}>
|
|
284
284
|
<AIChat {...aiChatProps} />
|
|
285
|
-
<TerminalInfo {...terminalInfoProps} />
|
|
285
|
+
<TerminalInfo key={store.activeTabId} {...terminalInfoProps} />
|
|
286
286
|
</RightSidePanel>
|
|
287
287
|
<SshConfigLoadNotify {...sshConfigProps} />
|
|
288
288
|
<LoadSshConfigs
|
|
@@ -6,7 +6,8 @@ import {
|
|
|
6
6
|
ReloadOutlined,
|
|
7
7
|
ArrowRightOutlined,
|
|
8
8
|
LoadingOutlined,
|
|
9
|
-
HomeOutlined
|
|
9
|
+
HomeOutlined,
|
|
10
|
+
PlusOutlined
|
|
10
11
|
} from '@ant-design/icons'
|
|
11
12
|
import {
|
|
12
13
|
Input,
|
|
@@ -74,7 +75,7 @@ function renderAddonBefore (props, realPath) {
|
|
|
74
75
|
)
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
function renderAddonAfter (isLoadingRemote, onGoto, GoIcon, type) {
|
|
78
|
+
function renderAddonAfter (isLoadingRemote, onGoto, GoIcon, type, handleUploadFromBrowser) {
|
|
78
79
|
const handleClick = (e) => {
|
|
79
80
|
e.stopPropagation()
|
|
80
81
|
if (!isLoadingRemote) {
|
|
@@ -82,9 +83,24 @@ function renderAddonAfter (isLoadingRemote, onGoto, GoIcon, type) {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
return (
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
<>
|
|
87
|
+
{
|
|
88
|
+
type === typeMap.local && window.et.isWebApp
|
|
89
|
+
? (
|
|
90
|
+
<PlusOutlined
|
|
91
|
+
className='mg1r'
|
|
92
|
+
onClick={(e) => {
|
|
93
|
+
e.stopPropagation()
|
|
94
|
+
handleUploadFromBrowser()
|
|
95
|
+
}}
|
|
96
|
+
/>
|
|
97
|
+
)
|
|
98
|
+
: null
|
|
99
|
+
}
|
|
100
|
+
<GoIcon
|
|
101
|
+
onClick={handleClick}
|
|
102
|
+
/>
|
|
103
|
+
</>
|
|
88
104
|
)
|
|
89
105
|
}
|
|
90
106
|
|
|
@@ -160,7 +176,7 @@ export default function AddressBar (props) {
|
|
|
160
176
|
onBlur={() => props.onInputBlur(type)}
|
|
161
177
|
disabled={loadingSftp}
|
|
162
178
|
suffix={
|
|
163
|
-
renderAddonAfter(isLoadingRemote, onGoto, GoIcon, type)
|
|
179
|
+
renderAddonAfter(isLoadingRemote, onGoto, GoIcon, type, props.handleUploadFromBrowser)
|
|
164
180
|
}
|
|
165
181
|
/>
|
|
166
182
|
{renderHistory(props, type)}
|
|
@@ -14,6 +14,7 @@ import copy from 'json-deep-copy'
|
|
|
14
14
|
import { pick, some } from 'lodash-es'
|
|
15
15
|
import Input from '../common/input-auto-focus'
|
|
16
16
|
import resolve from '../../common/resolve'
|
|
17
|
+
import normalizeRemotePath from '../../common/normalize-remote-path'
|
|
17
18
|
import { addClass, removeClass } from '../../common/class'
|
|
18
19
|
import {
|
|
19
20
|
mode2permission,
|
|
@@ -604,7 +605,10 @@ export default class FileSection extends React.Component {
|
|
|
604
605
|
const { type, name, isParent } = file
|
|
605
606
|
const n = `${type}Path`
|
|
606
607
|
const path = isParent ? file.path : this.props[n]
|
|
607
|
-
|
|
608
|
+
let np = resolve(path, name)
|
|
609
|
+
if (type === typeMap.remote) {
|
|
610
|
+
np = normalizeRemotePath(np)
|
|
611
|
+
}
|
|
608
612
|
const op = this.props[type + 'Path']
|
|
609
613
|
this.props.modifier({
|
|
610
614
|
[n]: np,
|
|
@@ -882,6 +886,25 @@ export default class FileSection extends React.Component {
|
|
|
882
886
|
window.pre.showItemInFolder(p)
|
|
883
887
|
}
|
|
884
888
|
|
|
889
|
+
downloadFromBrowser = async () => {
|
|
890
|
+
const { path, name, isDirectory } = this.state.file
|
|
891
|
+
const p = resolve(path, name)
|
|
892
|
+
const url = '/api/download?path=' + encodeURIComponent(p)
|
|
893
|
+
const res = await window.fetch(url, {
|
|
894
|
+
headers: {
|
|
895
|
+
token: window.store?.config.tokenElecterm
|
|
896
|
+
}
|
|
897
|
+
})
|
|
898
|
+
const blob = await res.blob()
|
|
899
|
+
const a = document.createElement('a')
|
|
900
|
+
a.href = URL.createObjectURL(blob)
|
|
901
|
+
a.download = isDirectory ? name + '.tar.gz' : name
|
|
902
|
+
document.body.appendChild(a)
|
|
903
|
+
a.click()
|
|
904
|
+
document.body.removeChild(a)
|
|
905
|
+
URL.revokeObjectURL(a.href)
|
|
906
|
+
}
|
|
907
|
+
|
|
885
908
|
newItem = (isDirectory) => {
|
|
886
909
|
const { type } = this.state.file
|
|
887
910
|
const list = copy(this.props[type])
|
|
@@ -1060,6 +1083,13 @@ export default class FileSection extends React.Component {
|
|
|
1060
1083
|
text: e('showInDefaultFileMananger')
|
|
1061
1084
|
})
|
|
1062
1085
|
}
|
|
1086
|
+
if (isLocal && isRealFile && window.et.isWebApp) {
|
|
1087
|
+
res.push({
|
|
1088
|
+
func: 'downloadFromBrowser',
|
|
1089
|
+
icon: 'DownloadOutlined',
|
|
1090
|
+
text: 'Download from browser'
|
|
1091
|
+
})
|
|
1092
|
+
}
|
|
1063
1093
|
if (showEdit) {
|
|
1064
1094
|
res.push({
|
|
1065
1095
|
func: 'editFile',
|
|
@@ -7,6 +7,12 @@ import fs from '../../common/fs'
|
|
|
7
7
|
import { isWin } from '../../common/constants'
|
|
8
8
|
|
|
9
9
|
export const getFileExt = fileName => {
|
|
10
|
+
if (/^\\\\(?:wsl\$|wsl\.localhost)\\/.test(fileName)) {
|
|
11
|
+
return {
|
|
12
|
+
base: fileName,
|
|
13
|
+
ext: ''
|
|
14
|
+
}
|
|
15
|
+
}
|
|
10
16
|
const sep = '.'
|
|
11
17
|
const arr = fileName.split(sep)
|
|
12
18
|
const len = arr.length
|
|
@@ -82,12 +88,15 @@ export const getFolderFromFilePath = (filePath, isRemote) => {
|
|
|
82
88
|
const arr = filePath.split(sep)
|
|
83
89
|
const len = arr.length
|
|
84
90
|
const isWinDisk = isWin && filePath.endsWith(sep)
|
|
85
|
-
const
|
|
91
|
+
const isWslRoot = isWin && /^\\\\(?:wsl\$|wsl\.localhost)\\[^\\]+$/.test(filePath.replace(/\\$/, ''))
|
|
92
|
+
const path = (isWinDisk || isWslRoot)
|
|
86
93
|
? '/'
|
|
87
94
|
: arr.slice(0, len - 1).join(sep)
|
|
88
95
|
const name = isWinDisk
|
|
89
96
|
? filePath.replace(sep, '')
|
|
90
|
-
:
|
|
97
|
+
: isWslRoot
|
|
98
|
+
? filePath
|
|
99
|
+
: arr[len - 1]
|
|
91
100
|
|
|
92
101
|
return {
|
|
93
102
|
path,
|
|
@@ -29,6 +29,7 @@ import fs from '../../common/fs'
|
|
|
29
29
|
import ListTable from './list-table-ui'
|
|
30
30
|
import deepCopy from 'json-deep-copy'
|
|
31
31
|
import isValidPath from '../../common/is-valid-path'
|
|
32
|
+
import normalizeRemotePath from '../../common/normalize-remote-path'
|
|
32
33
|
import { LoadingOutlined, ReloadOutlined } from '@ant-design/icons'
|
|
33
34
|
import * as owner from './owner-list'
|
|
34
35
|
import AddressBar from './address-bar'
|
|
@@ -292,6 +293,7 @@ export default class Sftp extends Component {
|
|
|
292
293
|
if (!path && this.sftp) {
|
|
293
294
|
path = await this.getPwd(this.props.tab.username)
|
|
294
295
|
}
|
|
296
|
+
path = normalizeRemotePath(path)
|
|
295
297
|
} else {
|
|
296
298
|
path = this.getLocalHome()
|
|
297
299
|
}
|
|
@@ -762,7 +764,7 @@ export default class Sftp extends Component {
|
|
|
762
764
|
|
|
763
765
|
if (!remotePath) {
|
|
764
766
|
if (startDirectory) {
|
|
765
|
-
remotePath = startDirectory
|
|
767
|
+
remotePath = normalizeRemotePath(startDirectory)
|
|
766
768
|
} else {
|
|
767
769
|
remotePath = await this.getPwd(username)
|
|
768
770
|
}
|
|
@@ -970,6 +972,31 @@ export default class Sftp extends Component {
|
|
|
970
972
|
})
|
|
971
973
|
}
|
|
972
974
|
|
|
975
|
+
handleUploadFromBrowser = () => {
|
|
976
|
+
const input = document.createElement('input')
|
|
977
|
+
input.type = 'file'
|
|
978
|
+
input.multiple = true
|
|
979
|
+
input.onchange = async () => {
|
|
980
|
+
const files = input.files
|
|
981
|
+
if (!files || !files.length) return
|
|
982
|
+
const { localPath } = this.state
|
|
983
|
+
for (const file of files) {
|
|
984
|
+
const formData = new FormData()
|
|
985
|
+
formData.append('file', file)
|
|
986
|
+
formData.append('path', localPath)
|
|
987
|
+
await window.fetch('/api/upload', {
|
|
988
|
+
method: 'POST',
|
|
989
|
+
body: formData,
|
|
990
|
+
headers: {
|
|
991
|
+
token: window.store?.config.tokenElecterm
|
|
992
|
+
}
|
|
993
|
+
})
|
|
994
|
+
}
|
|
995
|
+
this.localList()
|
|
996
|
+
}
|
|
997
|
+
input.click()
|
|
998
|
+
}
|
|
999
|
+
|
|
973
1000
|
parsePath = async (type, pth) => {
|
|
974
1001
|
const reg = /^%([^%]+)%/
|
|
975
1002
|
if (!reg.test(pth)) {
|
|
@@ -995,7 +1022,10 @@ export default class Sftp extends Component {
|
|
|
995
1022
|
const n = `${type}Path`
|
|
996
1023
|
const nt = n + 'Temp'
|
|
997
1024
|
const oldPath = this.state[type + 'Path']
|
|
998
|
-
|
|
1025
|
+
let np = await this.parsePath(type, this.state[nt])
|
|
1026
|
+
if (type === typeMap.remote) {
|
|
1027
|
+
np = normalizeRemotePath(np)
|
|
1028
|
+
}
|
|
999
1029
|
if (!isValidPath(np)) {
|
|
1000
1030
|
return notification.warning({
|
|
1001
1031
|
message: 'path not valid'
|
|
@@ -1003,6 +1033,7 @@ export default class Sftp extends Component {
|
|
|
1003
1033
|
}
|
|
1004
1034
|
this.setState({
|
|
1005
1035
|
[n]: np,
|
|
1036
|
+
[nt]: np,
|
|
1006
1037
|
[`${type}Keyword`]: ''
|
|
1007
1038
|
}, () => this[`${type}List`](undefined, undefined, oldPath))
|
|
1008
1039
|
}
|
|
@@ -1010,7 +1041,10 @@ export default class Sftp extends Component {
|
|
|
1010
1041
|
goParent = (type) => {
|
|
1011
1042
|
const n = `${type}Path`
|
|
1012
1043
|
const p = this.state[n]
|
|
1013
|
-
|
|
1044
|
+
let np = resolve(p, '..')
|
|
1045
|
+
if (type === typeMap.remote) {
|
|
1046
|
+
np = normalizeRemotePath(np)
|
|
1047
|
+
}
|
|
1014
1048
|
const op = this.state[n]
|
|
1015
1049
|
if (np !== p) {
|
|
1016
1050
|
this.setState({
|
|
@@ -1218,6 +1252,7 @@ export default class Sftp extends Component {
|
|
|
1218
1252
|
const addrProps = {
|
|
1219
1253
|
host,
|
|
1220
1254
|
type,
|
|
1255
|
+
handleUploadFromBrowser: this.handleUploadFromBrowser,
|
|
1221
1256
|
...pick(
|
|
1222
1257
|
this,
|
|
1223
1258
|
[
|
|
@@ -82,6 +82,7 @@ export function handleTerminalSelectionReplace (event, ctx) {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
ctx.term.clearSelection()
|
|
85
|
+
ctx.term.scrollToBottom()
|
|
85
86
|
return true
|
|
86
87
|
}
|
|
87
88
|
|
|
@@ -167,6 +168,7 @@ export function shortcutExtend (Cls) {
|
|
|
167
168
|
const altDelDelKey = delKey === 8 ? 127 : 8
|
|
168
169
|
const char = String.fromCharCode(shiftKey ? delKey : altDelDelKey)
|
|
169
170
|
this.socket.send(char)
|
|
171
|
+
this.term.scrollToBottom()
|
|
170
172
|
return false
|
|
171
173
|
} else if (
|
|
172
174
|
this.term &&
|
|
@@ -193,6 +195,11 @@ export function shortcutExtend (Cls) {
|
|
|
193
195
|
this.trzszClient.cancel()
|
|
194
196
|
return false
|
|
195
197
|
}
|
|
198
|
+
// Cancel xmodem transfer if active
|
|
199
|
+
if (this.xmodemClient && this.xmodemClient.isActive) {
|
|
200
|
+
this.xmodemClient.cancel()
|
|
201
|
+
return false
|
|
202
|
+
}
|
|
196
203
|
}
|
|
197
204
|
|
|
198
205
|
let codeName
|
|
@@ -38,6 +38,21 @@ export default auto(function HistoryPanel (props) {
|
|
|
38
38
|
store.clearHistory()
|
|
39
39
|
}
|
|
40
40
|
const e = window.translate
|
|
41
|
+
function renderHeader () {
|
|
42
|
+
if (!arr.length) {
|
|
43
|
+
return null
|
|
44
|
+
}
|
|
45
|
+
return (
|
|
46
|
+
<div className='history-header pd2x pd2b'>
|
|
47
|
+
<Switch
|
|
48
|
+
{...switchProps}
|
|
49
|
+
/>
|
|
50
|
+
<UnorderedListOutlined
|
|
51
|
+
{...clearIconProps}
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
41
56
|
const switchProps = {
|
|
42
57
|
checkedChildren: e('sortByFrequency'),
|
|
43
58
|
unCheckedChildren: e('sortByFrequency'),
|
|
@@ -54,14 +69,7 @@ export default auto(function HistoryPanel (props) {
|
|
|
54
69
|
<div
|
|
55
70
|
className='sidebar-panel-history'
|
|
56
71
|
>
|
|
57
|
-
|
|
58
|
-
<Switch
|
|
59
|
-
{...switchProps}
|
|
60
|
-
/>
|
|
61
|
-
<UnorderedListOutlined
|
|
62
|
-
{...clearIconProps}
|
|
63
|
-
/>
|
|
64
|
-
</div>
|
|
72
|
+
{renderHeader()}
|
|
65
73
|
<div className='history-body'>
|
|
66
74
|
{
|
|
67
75
|
arr.map((item, i) => {
|
|
@@ -24,7 +24,11 @@ import {
|
|
|
24
24
|
LockOutlined,
|
|
25
25
|
ReloadOutlined,
|
|
26
26
|
FileZipOutlined,
|
|
27
|
-
AppstoreOutlined
|
|
27
|
+
AppstoreOutlined,
|
|
28
|
+
SaveOutlined,
|
|
29
|
+
PlayCircleFilled,
|
|
30
|
+
StopOutlined,
|
|
31
|
+
DownloadOutlined
|
|
28
32
|
} from '@ant-design/icons'
|
|
29
33
|
import IconHolder from './icon-holder'
|
|
30
34
|
|
|
@@ -52,5 +56,9 @@ export default {
|
|
|
52
56
|
LockOutlined,
|
|
53
57
|
ReloadOutlined,
|
|
54
58
|
FileZipOutlined,
|
|
55
|
-
AppstoreOutlined
|
|
59
|
+
AppstoreOutlined,
|
|
60
|
+
SaveOutlined,
|
|
61
|
+
PlayCircleFilled,
|
|
62
|
+
StopOutlined,
|
|
63
|
+
DownloadOutlined
|
|
56
64
|
}
|
|
@@ -96,7 +96,7 @@ export default class AttachAddonCustom {
|
|
|
96
96
|
if (typeof ev.data === 'string') {
|
|
97
97
|
try {
|
|
98
98
|
const msg = JSON.parse(ev.data)
|
|
99
|
-
if (msg.action === 'zmodem-event' || msg.action === 'trzsz-event') {
|
|
99
|
+
if (msg.action === 'zmodem-event' || msg.action === 'trzsz-event' || msg.action === 'xmodem-event') {
|
|
100
100
|
return
|
|
101
101
|
}
|
|
102
102
|
} catch (e) {}
|
|
@@ -4,11 +4,62 @@ import Modal from '../common/modal'
|
|
|
4
4
|
const e = window.translate
|
|
5
5
|
|
|
6
6
|
export class DropFileModal extends Component {
|
|
7
|
+
renderSerialFooter () {
|
|
8
|
+
const { onSelect } = this.props
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<button
|
|
12
|
+
type='button'
|
|
13
|
+
className='custom-modal-ok-btn'
|
|
14
|
+
onClick={() => onSelect('xmodem')}
|
|
15
|
+
>
|
|
16
|
+
XMODEM
|
|
17
|
+
</button>
|
|
18
|
+
<button
|
|
19
|
+
type='button'
|
|
20
|
+
className='custom-modal-cancel-btn'
|
|
21
|
+
onClick={() => onSelect('inputOnly')}
|
|
22
|
+
>
|
|
23
|
+
{e('inputOnly')}
|
|
24
|
+
</button>
|
|
25
|
+
</>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
renderSshFooter () {
|
|
30
|
+
const { onSelect } = this.props
|
|
31
|
+
return (
|
|
32
|
+
<>
|
|
33
|
+
<button
|
|
34
|
+
type='button'
|
|
35
|
+
className='custom-modal-ok-btn'
|
|
36
|
+
onClick={() => onSelect('trz')}
|
|
37
|
+
>
|
|
38
|
+
trz
|
|
39
|
+
</button>
|
|
40
|
+
<button
|
|
41
|
+
type='button'
|
|
42
|
+
className='custom-modal-cancel-btn'
|
|
43
|
+
onClick={() => onSelect('rz')}
|
|
44
|
+
>
|
|
45
|
+
rz
|
|
46
|
+
</button>
|
|
47
|
+
<button
|
|
48
|
+
type='button'
|
|
49
|
+
className='custom-modal-cancel-btn'
|
|
50
|
+
onClick={() => onSelect('inputOnly')}
|
|
51
|
+
>
|
|
52
|
+
{e('inputOnly')}
|
|
53
|
+
</button>
|
|
54
|
+
</>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
7
58
|
render () {
|
|
8
59
|
const {
|
|
9
60
|
visible,
|
|
10
61
|
files,
|
|
11
|
-
|
|
62
|
+
isSerial,
|
|
12
63
|
onCancel
|
|
13
64
|
} = this.props
|
|
14
65
|
|
|
@@ -23,27 +74,7 @@ export class DropFileModal extends Component {
|
|
|
23
74
|
onCancel={onCancel}
|
|
24
75
|
footer={
|
|
25
76
|
<div className='custom-modal-footer-buttons'>
|
|
26
|
-
|
|
27
|
-
type='button'
|
|
28
|
-
className='custom-modal-ok-btn'
|
|
29
|
-
onClick={() => onSelect('trz')}
|
|
30
|
-
>
|
|
31
|
-
trz
|
|
32
|
-
</button>
|
|
33
|
-
<button
|
|
34
|
-
type='button'
|
|
35
|
-
className='custom-modal-cancel-btn'
|
|
36
|
-
onClick={() => onSelect('rz')}
|
|
37
|
-
>
|
|
38
|
-
rz
|
|
39
|
-
</button>
|
|
40
|
-
<button
|
|
41
|
-
type='button'
|
|
42
|
-
className='custom-modal-cancel-btn'
|
|
43
|
-
onClick={() => onSelect('inputOnly')}
|
|
44
|
-
>
|
|
45
|
-
{e('inputOnly')}
|
|
46
|
-
</button>
|
|
77
|
+
{isSerial ? this.renderSerialFooter() : this.renderSshFooter()}
|
|
47
78
|
</div>
|
|
48
79
|
}
|
|
49
80
|
width={400}
|
|
@@ -49,3 +49,12 @@ export function setTerminalLogPath (pid, logPath) {
|
|
|
49
49
|
action: 'set-terminal-log-path'
|
|
50
50
|
})
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
export function startTerminalLogFile (pid, logFilePath, addTimeStampToTermLog) {
|
|
54
|
+
return fetch({
|
|
55
|
+
pid,
|
|
56
|
+
logFilePath,
|
|
57
|
+
addTimeStampToTermLog,
|
|
58
|
+
action: 'start-terminal-log-file'
|
|
59
|
+
})
|
|
60
|
+
}
|