@electerm/electerm-react 1.51.3 → 1.51.18
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 +15 -1
- package/client/common/db.js +10 -9
- package/client/common/default-setting.js +0 -1
- package/client/common/is-color-dark.js +15 -11
- package/client/common/new-terminal.js +2 -5
- package/client/common/reverse-color.js +12 -0
- package/client/common/ws.js +4 -1
- package/client/components/batch-op/batch-op.jsx +16 -5
- package/client/components/bookmark-form/index.jsx +1 -1
- package/client/components/bookmark-form/render-connection-hopping.jsx +25 -2
- package/client/components/bookmark-form/ssh-form.jsx +4 -25
- package/client/components/bookmark-form/tree-delete.jsx +5 -10
- package/client/components/bookmark-form/use-submit.jsx +6 -15
- package/client/components/bookmark-form/use-ui.jsx +1 -2
- package/client/components/common/connection-hopping-warning-text.jsx +36 -0
- package/client/components/common/drag-handle.jsx +60 -0
- package/client/components/common/drag-handle.styl +12 -0
- 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/layout/layout.jsx +3 -2
- package/client/components/main/connection-hopping-warnning.jsx +45 -0
- package/client/components/main/error-wrapper.jsx +120 -5
- package/client/components/main/main.jsx +32 -8
- package/client/components/main/upgrade.jsx +4 -9
- package/client/components/main/wrapper.styl +2 -1
- package/client/components/profile/profile-form-ssh.jsx +1 -1
- package/client/components/rdp/resolution-edit.jsx +3 -5
- package/client/components/session/session.jsx +22 -3
- 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-common.jsx +28 -7
- package/client/components/setting-panel/setting-modal.jsx +0 -12
- package/client/components/setting-panel/setting-terminal.jsx +7 -4
- package/client/components/sftp/confirm-modal-store.jsx +3 -11
- package/client/components/sftp/file-mode-modal.jsx +2 -2
- package/client/components/sftp/sftp-entry.jsx +4 -7
- package/client/components/sftp/transfer-conflict-store.jsx +70 -69
- package/client/components/sftp/transport-action-store.jsx +42 -49
- package/client/components/sftp/transports-action-store.jsx +15 -15
- package/client/components/sftp/transports-ui-store.jsx +9 -5
- package/client/components/side-panel-r/side-panel-r.jsx +13 -40
- package/client/components/sidebar/bookmark-select.jsx +1 -4
- 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 +5 -40
- package/client/components/sidebar/side-panel.jsx +27 -51
- package/client/components/sidebar/sidebar-panel.jsx +107 -0
- package/client/components/sidebar/sidebar.styl +14 -9
- 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/ssh-config/load-ssh-configs.jsx +106 -0
- package/client/components/ssh-config/ssh-config-item.jsx +26 -0
- package/client/components/ssh-config/ssh-config-load-notify.jsx +60 -0
- package/client/components/tabs/index.jsx +4 -4
- package/client/components/tabs/tab.jsx +28 -20
- package/client/components/tabs/tabs.styl +6 -1
- package/client/components/terminal/index.jsx +4 -18
- package/client/components/tree-list/bookmark-toolbar.jsx +203 -0
- package/client/components/tree-list/bookmark-transport.jsx +2 -0
- package/client/components/tree-list/tree-list.jsx +33 -42
- package/client/entry/worker.js +5 -3
- package/client/store/bookmark-group.js +5 -18
- package/client/store/bookmark.js +43 -1
- package/client/store/common.js +13 -9
- package/client/store/db-upgrade.js +0 -2
- package/client/store/index.js +45 -53
- package/client/store/init-state.js +20 -23
- package/client/store/item.js +0 -19
- package/client/store/load-data.js +7 -10
- package/client/store/setting.js +10 -66
- package/client/store/sidebar.js +7 -8
- package/client/store/sync.js +7 -8
- package/client/store/tab.js +93 -14
- package/client/store/terminal-theme.js +1 -1
- package/client/store/transfer-history.js +3 -9
- package/client/store/transfer-list.js +67 -75
- package/client/store/ui-theme.js +0 -9
- package/client/store/watch.js +17 -9
- package/package.json +1 -1
- package/client/components/setting-panel/tab-history.jsx +0 -43
|
@@ -98,7 +98,6 @@ export const paneMap = buildConst([
|
|
|
98
98
|
export const settingMap = buildConst([
|
|
99
99
|
'setting',
|
|
100
100
|
'bookmarks',
|
|
101
|
-
'history',
|
|
102
101
|
'terminalThemes',
|
|
103
102
|
'bookmarkGroups',
|
|
104
103
|
'quickCommands',
|
|
@@ -307,6 +306,7 @@ export const sshTunnelHelpLink = 'https://github.com/electerm/electerm/wiki/How-
|
|
|
307
306
|
export const batchOpHelpLink = 'https://github.com/electerm/electerm/wiki/batch-operation'
|
|
308
307
|
export const proxyHelpLink = 'https://github.com/electerm/electerm/wiki/proxy-format'
|
|
309
308
|
export const regexHelpLink = 'https://github.com/electerm/electerm/wiki/Terminal-keywords-highlight-regular-expression-exmaples'
|
|
309
|
+
export const connectionHoppingWikiLink = 'https://github.com/electerm/electerm/wiki/Connection-Hopping-Behavior-Change-in-electerm-since-v1.50.65'
|
|
310
310
|
export const modals = {
|
|
311
311
|
hide: 0,
|
|
312
312
|
setting: 1,
|
|
@@ -398,3 +398,17 @@ export const syncDataMaps = {
|
|
|
398
398
|
profiles: ['profiles'],
|
|
399
399
|
addressBookmarks: ['addressBookmarks']
|
|
400
400
|
}
|
|
401
|
+
export const terminalTypes = [
|
|
402
|
+
'xterm-256color',
|
|
403
|
+
'xterm-new',
|
|
404
|
+
'xterm-color',
|
|
405
|
+
'xterm-vt220',
|
|
406
|
+
'xterm',
|
|
407
|
+
'linux',
|
|
408
|
+
'vt100',
|
|
409
|
+
'ansi',
|
|
410
|
+
'rxvt'
|
|
411
|
+
]
|
|
412
|
+
export const sshConfigLoadKey = 'ssh-config-loaded'
|
|
413
|
+
export const sshConfigKey = 'ignore-ssh-config'
|
|
414
|
+
export const connectionHoppingWarnKey = 'connectionHoppingWarnned'
|
package/client/common/db.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import {
|
|
6
6
|
settingMap
|
|
7
7
|
} from '../common/constants'
|
|
8
|
-
import { without, isArray
|
|
8
|
+
import { without, isArray } from 'lodash-es'
|
|
9
9
|
import handleError from './error-handler'
|
|
10
10
|
import generate from './uid'
|
|
11
11
|
import safeParse from './to-simple-obj'
|
|
@@ -30,8 +30,7 @@ export const dbNames = without(
|
|
|
30
30
|
|
|
31
31
|
export const dbNamesForWatch = without(
|
|
32
32
|
Object.keys(settingMap),
|
|
33
|
-
settingMap.setting
|
|
34
|
-
settingMap.history
|
|
33
|
+
settingMap.setting
|
|
35
34
|
)
|
|
36
35
|
|
|
37
36
|
/**
|
|
@@ -146,10 +145,12 @@ export async function getData (name) {
|
|
|
146
145
|
export async function fetchInitData (dbName) {
|
|
147
146
|
const res = await find(dbName)
|
|
148
147
|
const order = await getData(`${dbName}:order`)
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
if (order && order.length) {
|
|
149
|
+
res.sort((a, b) => {
|
|
150
|
+
const ai = order.findIndex(r => r === a.id)
|
|
151
|
+
const bi = order.findIndex(r => r === b.id)
|
|
152
|
+
return ai - bi
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
return JSON.stringify(res)
|
|
155
156
|
}
|
|
@@ -17,17 +17,21 @@ function expandShorthandColor (color) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export default function isColorDark (_color) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
try {
|
|
21
|
+
let color = expandShorthandColor(_color)
|
|
22
|
+
if (color.charAt(0) === '#') {
|
|
23
|
+
color = color.slice(1) // Remove the '#' if present
|
|
24
|
+
}
|
|
25
|
+
const r = parseInt(color.substr(0, 2), 16)
|
|
26
|
+
const g = parseInt(color.substr(2, 2), 16)
|
|
27
|
+
const b = parseInt(color.substr(4, 2), 16)
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
// Formula to determine brightness
|
|
30
|
+
const brightness = (r * 299 + g * 587 + b * 114) / 1000
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
// Decide based on brightness threshold
|
|
33
|
+
return brightness < 128 // You can adjust this threshold as needed
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return true
|
|
36
|
+
}
|
|
33
37
|
}
|
|
@@ -11,11 +11,11 @@ const e = window.translate
|
|
|
11
11
|
window.et.tabCount = 0
|
|
12
12
|
|
|
13
13
|
export function updateCount (tab) {
|
|
14
|
-
tab.tabCount = window.et.tabCount
|
|
15
14
|
window.et.tabCount++
|
|
15
|
+
return window.et.tabCount
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export default (removeTitle
|
|
18
|
+
export default (removeTitle) => {
|
|
19
19
|
const res = {
|
|
20
20
|
id: uid(),
|
|
21
21
|
status: 'processing',
|
|
@@ -25,8 +25,5 @@ export default (removeTitle, noUpdateCount) => {
|
|
|
25
25
|
if (removeTitle) {
|
|
26
26
|
delete res.title
|
|
27
27
|
}
|
|
28
|
-
if (!noUpdateCount) {
|
|
29
|
-
updateCount(res)
|
|
30
|
-
}
|
|
31
28
|
return res
|
|
32
29
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function getReverseColor (hex) {
|
|
2
|
+
// Check if the input is a valid hex color code
|
|
3
|
+
if (!/^#[0-9a-fA-F]{6}$/.test(hex)) {
|
|
4
|
+
return '#0088cc'
|
|
5
|
+
}
|
|
6
|
+
// Convert the hex color code to an integer
|
|
7
|
+
const num = parseInt(hex.slice(1), 16)
|
|
8
|
+
// Bitwise XOR the integer with 0xFFFFFF to get the reverse color
|
|
9
|
+
const reverse = num ^ 0xFFFFFF
|
|
10
|
+
// Convert the reverse color to a hex string and pad with zeros if needed
|
|
11
|
+
return '#' + reverse.toString(16).padStart(6, '0')
|
|
12
|
+
}
|
package/client/common/ws.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import generate from './uid'
|
|
6
6
|
import wait from './wait'
|
|
7
7
|
import copy from 'json-deep-copy'
|
|
8
|
+
import { pick } from 'lodash-es'
|
|
8
9
|
|
|
9
10
|
const onces = {}
|
|
10
11
|
const wss = {}
|
|
@@ -151,7 +152,9 @@ export default (type, id, sessionId = '', sftpId = '', persist) => {
|
|
|
151
152
|
id,
|
|
152
153
|
sessionId,
|
|
153
154
|
sftpId,
|
|
154
|
-
window.store.config
|
|
155
|
+
pick(window.store.config, [
|
|
156
|
+
'host', 'port', 'tokenElecterm'
|
|
157
|
+
])
|
|
155
158
|
]
|
|
156
159
|
})
|
|
157
160
|
onces[id] = {
|
|
@@ -173,11 +173,15 @@ export default class BatchOp extends PureComponent {
|
|
|
173
173
|
run = async (conf, index) => {
|
|
174
174
|
this.updateState('working', index)
|
|
175
175
|
let tab = await this.createTab(conf)
|
|
176
|
-
.then(r => r)
|
|
177
176
|
.catch(err => {
|
|
177
|
+
console.log('create tab error', err)
|
|
178
|
+
if (this.ref) {
|
|
179
|
+
this.ref.stop()
|
|
180
|
+
delete this.ref
|
|
181
|
+
}
|
|
178
182
|
return 'Error: ' + err.message
|
|
179
183
|
})
|
|
180
|
-
if (
|
|
184
|
+
if (typeof tab === 'string') {
|
|
181
185
|
return this.updateState(tab, index)
|
|
182
186
|
}
|
|
183
187
|
|
|
@@ -189,9 +193,16 @@ export default class BatchOp extends PureComponent {
|
|
|
189
193
|
}
|
|
190
194
|
if (conf.remotePath) {
|
|
191
195
|
this.updateState('creating sftp', index)
|
|
192
|
-
tab = await this.createSftp(tab)
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
tab = await this.createSftp(tab).catch(err => {
|
|
197
|
+
console.log('create sftp error', err)
|
|
198
|
+
if (this.ref2) {
|
|
199
|
+
this.ref2.stop()
|
|
200
|
+
delete this.ref2
|
|
201
|
+
}
|
|
202
|
+
return 'Error: ' + err.message
|
|
203
|
+
})
|
|
204
|
+
if (typeof tab === 'string') {
|
|
205
|
+
return this.updateState(tab, index)
|
|
195
206
|
}
|
|
196
207
|
this.updateState('sftp created', index)
|
|
197
208
|
this.updateState('transferring file', index)
|
|
@@ -125,7 +125,7 @@ export default class BookmarkIndex extends PureComponent {
|
|
|
125
125
|
const {
|
|
126
126
|
type
|
|
127
127
|
} = this.props
|
|
128
|
-
if (type !== settingMap.bookmarks
|
|
128
|
+
if (type !== settingMap.bookmarks) {
|
|
129
129
|
return null
|
|
130
130
|
}
|
|
131
131
|
const { ready } = this.state
|
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
Button,
|
|
7
7
|
Table
|
|
8
8
|
} from 'antd'
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
formItemLayout,
|
|
11
|
+
tailFormItemLayout
|
|
12
|
+
} from '../../common/form-layout'
|
|
10
13
|
import {
|
|
11
14
|
MinusCircleFilled,
|
|
12
15
|
PlusOutlined
|
|
@@ -14,10 +17,13 @@ import {
|
|
|
14
17
|
import RenderAuth from './render-auth-ssh'
|
|
15
18
|
import uid from '../../common/uid'
|
|
16
19
|
import {
|
|
17
|
-
authTypeMap
|
|
20
|
+
authTypeMap,
|
|
21
|
+
connectionHoppingWarnKey
|
|
18
22
|
} from '../../common/constants'
|
|
19
23
|
import { useState } from 'react'
|
|
24
|
+
import ConnectionHoppingWarningText from '../common/connection-hopping-warning-text'
|
|
20
25
|
import BookmarkSelect from './bookmark-select'
|
|
26
|
+
import * as ls from '../../common/safe-local-storage'
|
|
21
27
|
|
|
22
28
|
const FormItem = Form.Item
|
|
23
29
|
const RadioButton = Radio.Button
|
|
@@ -35,6 +41,12 @@ export default function renderConnectionHopping (props) {
|
|
|
35
41
|
port: 22,
|
|
36
42
|
authType: authTypeMap.password
|
|
37
43
|
})
|
|
44
|
+
const [showWarn, setShowWarn] = useState(
|
|
45
|
+
window.store.hasOldConnectionHoppingBookmark && ls.getItem(connectionHoppingWarnKey) !== 'yes'
|
|
46
|
+
)
|
|
47
|
+
function closeWarn () {
|
|
48
|
+
setShowWarn(false)
|
|
49
|
+
}
|
|
38
50
|
const [list, setList] = useState(formData.connectionHoppings || [])
|
|
39
51
|
function onChangeAuthType (e) {
|
|
40
52
|
editState(old => {
|
|
@@ -139,6 +151,16 @@ export default function renderConnectionHopping (props) {
|
|
|
139
151
|
</FormItem>
|
|
140
152
|
)
|
|
141
153
|
}
|
|
154
|
+
function renderWarn () {
|
|
155
|
+
if (!showWarn) {
|
|
156
|
+
return null
|
|
157
|
+
}
|
|
158
|
+
return (
|
|
159
|
+
<FormItem {...tailFormItemLayout}>
|
|
160
|
+
<ConnectionHoppingWarningText closeWarn={closeWarn} />
|
|
161
|
+
</FormItem>
|
|
162
|
+
)
|
|
163
|
+
}
|
|
142
164
|
const treeProps = {
|
|
143
165
|
bookmarks: store.bookmarks.filter(d => {
|
|
144
166
|
return d.host && d.port && d.username
|
|
@@ -160,6 +182,7 @@ export default function renderConnectionHopping (props) {
|
|
|
160
182
|
initialValues={initialValues}
|
|
161
183
|
>
|
|
162
184
|
{renderList()}
|
|
185
|
+
{renderWarn()}
|
|
163
186
|
<FormItem
|
|
164
187
|
{...formItemLayout}
|
|
165
188
|
label={e('chooseFromBookmarks')}
|
|
@@ -5,7 +5,7 @@ import { PureComponent } from 'react'
|
|
|
5
5
|
import {
|
|
6
6
|
message
|
|
7
7
|
} from 'antd'
|
|
8
|
-
import {
|
|
8
|
+
import { uniq, isEqual, pick } from 'lodash-es'
|
|
9
9
|
import copy from 'json-deep-copy'
|
|
10
10
|
import generate from '../../common/uid'
|
|
11
11
|
import {
|
|
@@ -96,13 +96,11 @@ export default class BookmarkForm extends PureComponent {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
updateBookmarkGroups = (bookmarkGroups, bookmark, categoryId) => {
|
|
99
|
-
let index = findIndex(
|
|
100
|
-
bookmarkGroups,
|
|
99
|
+
let index = bookmarkGroups.findIndex(
|
|
101
100
|
bg => bg.id === categoryId
|
|
102
101
|
)
|
|
103
102
|
if (index < 0) {
|
|
104
|
-
index = findIndex(
|
|
105
|
-
bookmarkGroups,
|
|
103
|
+
index = bookmarkGroups.findIndex(
|
|
106
104
|
bg => bg.id === defaultBookmarkGroupId
|
|
107
105
|
)
|
|
108
106
|
}
|
|
@@ -167,19 +165,6 @@ export default class BookmarkForm extends PureComponent {
|
|
|
167
165
|
const bookmarkGroups = copy(
|
|
168
166
|
this.props.bookmarkGroups
|
|
169
167
|
)
|
|
170
|
-
if (type === settingMap.history) {
|
|
171
|
-
obj.id = generate()
|
|
172
|
-
runIdle(() => {
|
|
173
|
-
addItem(obj, settingMap.bookmarks)
|
|
174
|
-
})
|
|
175
|
-
this.updateBookmarkGroups(
|
|
176
|
-
bookmarkGroups,
|
|
177
|
-
obj,
|
|
178
|
-
categoryId
|
|
179
|
-
)
|
|
180
|
-
message.success('OK', 3)
|
|
181
|
-
return
|
|
182
|
-
}
|
|
183
168
|
if (!obj.id.startsWith(newBookmarkIdPrefix)) {
|
|
184
169
|
const tar = copy(obj)
|
|
185
170
|
delete tar.id
|
|
@@ -196,11 +181,6 @@ export default class BookmarkForm extends PureComponent {
|
|
|
196
181
|
}
|
|
197
182
|
} else {
|
|
198
183
|
obj.id = generate()
|
|
199
|
-
if (evt !== 'save' && evt !== 'saveAndCreateNew') {
|
|
200
|
-
runIdle(() => {
|
|
201
|
-
addItem(obj, settingMap.history)
|
|
202
|
-
})
|
|
203
|
-
}
|
|
204
184
|
runIdle(() => {
|
|
205
185
|
addItem(obj, settingMap.bookmarks)
|
|
206
186
|
})
|
|
@@ -217,8 +197,7 @@ export default class BookmarkForm extends PureComponent {
|
|
|
217
197
|
}
|
|
218
198
|
|
|
219
199
|
setNewItem = (
|
|
220
|
-
settingItem = getInitItem([],
|
|
221
|
-
settingMap.bookmarks)
|
|
200
|
+
settingItem = getInitItem([], settingMap.bookmarks)
|
|
222
201
|
) => {
|
|
223
202
|
const { store } = this.props
|
|
224
203
|
this.props.store.storeAssign({
|
|
@@ -4,22 +4,17 @@ import {
|
|
|
4
4
|
Button
|
|
5
5
|
} from 'antd'
|
|
6
6
|
import { defaultBookmarkGroupId, settingMap } from '../../common/constants'
|
|
7
|
+
import deepCopy from 'json-deep-copy'
|
|
7
8
|
|
|
8
9
|
const e = window.translate
|
|
9
10
|
|
|
10
11
|
export default class BookmarkTreeDelete extends StartSessionSelect {
|
|
11
12
|
onExpand = (expandedKeys) => {
|
|
12
|
-
window.store.
|
|
13
|
-
'expandedKeys',
|
|
14
|
-
expandedKeys
|
|
15
|
-
)
|
|
13
|
+
window.store.expandedKeys = deepCopy(expandedKeys)
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
onCheck = (checkedKeys) => {
|
|
19
|
-
window.store.
|
|
20
|
-
'checkedKeys',
|
|
21
|
-
checkedKeys
|
|
22
|
-
)
|
|
17
|
+
window.store.checkedKeys = deepCopy(checkedKeys)
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
handleDel = () => {
|
|
@@ -42,13 +37,13 @@ export default class BookmarkTreeDelete extends StartSessionSelect {
|
|
|
42
37
|
const arr = checkedKeys.filter(d => d !== defaultBookmarkGroupId)
|
|
43
38
|
store.delItems(arr, settingMap.bookmarks)
|
|
44
39
|
store.delItems(arr, settingMap.bookmarkGroups)
|
|
45
|
-
store.
|
|
40
|
+
store.checkedKeys = []
|
|
46
41
|
}
|
|
47
42
|
|
|
48
43
|
handleCancel = () => {
|
|
49
44
|
const { store } = window
|
|
50
45
|
store.bookmarkSelectMode = false
|
|
51
|
-
store.
|
|
46
|
+
store.checkedKeys = []
|
|
52
47
|
}
|
|
53
48
|
|
|
54
49
|
render () {
|
|
@@ -10,9 +10,6 @@ import {
|
|
|
10
10
|
Button,
|
|
11
11
|
Form
|
|
12
12
|
} from 'antd'
|
|
13
|
-
import {
|
|
14
|
-
settingMap
|
|
15
|
-
} from '../../common/constants'
|
|
16
13
|
import { tailFormItemLayout } from '../../common/form-layout'
|
|
17
14
|
import useFuncs from './use-form-funcs'
|
|
18
15
|
|
|
@@ -37,18 +34,12 @@ export default function useBookmarkSubmit (props) {
|
|
|
37
34
|
className='mg1r mg1b'
|
|
38
35
|
>{e('saveAndConnect')}
|
|
39
36
|
</Button>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
className='mg1r mg1b'
|
|
47
|
-
onClick={saveAndCreateNew}
|
|
48
|
-
>{e('saveAndCreateNew')}
|
|
49
|
-
</Button>
|
|
50
|
-
)
|
|
51
|
-
}
|
|
37
|
+
<Button
|
|
38
|
+
type='primary'
|
|
39
|
+
className='mg1r mg1b'
|
|
40
|
+
onClick={saveAndCreateNew}
|
|
41
|
+
>{e('saveAndCreateNew')}
|
|
42
|
+
</Button>
|
|
52
43
|
<Button
|
|
53
44
|
type='dashed'
|
|
54
45
|
className='mg1r mg1b'
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import { formItemLayout } from '../../common/form-layout'
|
|
17
17
|
import defaultSettings from '../../common/default-setting'
|
|
18
18
|
import mapper from '../../common/auto-complete-data-mapper'
|
|
19
|
-
import { defaultEnvLang } from '../../common/constants'
|
|
19
|
+
import { defaultEnvLang, terminalTypes } from '../../common/constants'
|
|
20
20
|
|
|
21
21
|
const FormItem = Form.Item
|
|
22
22
|
const e = window.translate
|
|
@@ -26,7 +26,6 @@ export default function useBookmarkFormUI (props) {
|
|
|
26
26
|
fontFamily: defaultFontFamily,
|
|
27
27
|
fontSize: defaultFontSize
|
|
28
28
|
} = defaultSettings
|
|
29
|
-
const { terminalTypes } = props.store.config
|
|
30
29
|
return [
|
|
31
30
|
<FormItem
|
|
32
31
|
{...formItemLayout}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button
|
|
3
|
+
} from 'antd'
|
|
4
|
+
import Link from './external-link'
|
|
5
|
+
import {
|
|
6
|
+
connectionHoppingWikiLink,
|
|
7
|
+
connectionHoppingWarnKey
|
|
8
|
+
} from '../../common/constants'
|
|
9
|
+
import * as ls from '../../common/safe-local-storage'
|
|
10
|
+
|
|
11
|
+
const e = window.translate
|
|
12
|
+
|
|
13
|
+
export default function ConnectionHoppingWarningText (props) {
|
|
14
|
+
function handleRead () {
|
|
15
|
+
ls.setItem(connectionHoppingWarnKey, 'yes')
|
|
16
|
+
props.closeWarn()
|
|
17
|
+
}
|
|
18
|
+
return (
|
|
19
|
+
<div className='pd1'>
|
|
20
|
+
<div className='pd1b'>
|
|
21
|
+
<span>{e('connectionHoppingWarning')}</span>
|
|
22
|
+
</div>
|
|
23
|
+
<div className='pd1b'>
|
|
24
|
+
<Link to={connectionHoppingWikiLink}>{connectionHoppingWikiLink}</Link>
|
|
25
|
+
</div>
|
|
26
|
+
<div className='pd1b'>
|
|
27
|
+
<Button
|
|
28
|
+
onClick={handleRead}
|
|
29
|
+
size='small'
|
|
30
|
+
>
|
|
31
|
+
{e('haveRead')}
|
|
32
|
+
</Button>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useCallback, useRef, useState, memo } from 'react'
|
|
2
|
+
import './drag-handle.styl'
|
|
3
|
+
|
|
4
|
+
export default memo(function DragHandle (props) {
|
|
5
|
+
const [isDragging, setIsDragging] = useState(false)
|
|
6
|
+
const dragStartRef = useRef(false)
|
|
7
|
+
const clientXRef = useRef(0)
|
|
8
|
+
const {
|
|
9
|
+
max,
|
|
10
|
+
min,
|
|
11
|
+
width,
|
|
12
|
+
left = true
|
|
13
|
+
} = props
|
|
14
|
+
|
|
15
|
+
const calc = useCallback((clientX) => {
|
|
16
|
+
let nw = left
|
|
17
|
+
? clientX - clientXRef.current + width
|
|
18
|
+
: clientXRef.current - clientX + width
|
|
19
|
+
if (nw < min) {
|
|
20
|
+
nw = min
|
|
21
|
+
} else if (nw > max) {
|
|
22
|
+
nw = max
|
|
23
|
+
}
|
|
24
|
+
return nw
|
|
25
|
+
}, [props.max, props.min, props.left])
|
|
26
|
+
|
|
27
|
+
const handleMousedown = useCallback((e) => {
|
|
28
|
+
e.stopPropagation()
|
|
29
|
+
setIsDragging(true)
|
|
30
|
+
dragStartRef.current = true
|
|
31
|
+
clientXRef.current = e.clientX
|
|
32
|
+
window.addEventListener('mouseup', handleMouseup)
|
|
33
|
+
window.addEventListener('mousemove', handleMousemove)
|
|
34
|
+
}, [])
|
|
35
|
+
|
|
36
|
+
const handleMouseup = useCallback((e) => {
|
|
37
|
+
setIsDragging(false)
|
|
38
|
+
dragStartRef.current = false
|
|
39
|
+
const nw = calc(e.clientX)
|
|
40
|
+
props.onDragEnd(nw)
|
|
41
|
+
window.store.onResize()
|
|
42
|
+
window.removeEventListener('mouseup', handleMouseup)
|
|
43
|
+
window.removeEventListener('mousemove', handleMousemove)
|
|
44
|
+
}, [])
|
|
45
|
+
|
|
46
|
+
const handleMousemove = useCallback((e) => {
|
|
47
|
+
const nw = calc(e.clientX)
|
|
48
|
+
props.onDragMove(nw)
|
|
49
|
+
}, [width])
|
|
50
|
+
const divProps = {
|
|
51
|
+
className: 'drag-handle' + (isDragging ? ' dragging' : ''),
|
|
52
|
+
onMouseDown: handleMousedown,
|
|
53
|
+
draggable: false
|
|
54
|
+
}
|
|
55
|
+
return (
|
|
56
|
+
<div
|
|
57
|
+
{...divProps}
|
|
58
|
+
/>
|
|
59
|
+
)
|
|
60
|
+
})
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
.context-menu
|
|
3
3
|
position: absolute
|
|
4
4
|
width 280px
|
|
5
|
-
background main
|
|
5
|
+
background main
|
|
6
6
|
box-shadow 0px 0px 3px 3px alpha(main-dark, .35)
|
|
7
7
|
padding 10px 0
|
|
8
8
|
z-index 999
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
line-height 28px
|
|
21
21
|
padding 0 16px
|
|
22
22
|
&:hover
|
|
23
|
-
background #
|
|
23
|
+
background #08c
|
|
24
24
|
color #eee
|
|
25
25
|
cursor pointer
|
|
26
26
|
&.disabled
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
position absolute
|
|
48
48
|
left 100%
|
|
49
49
|
top 0
|
|
50
|
-
background main
|
|
50
|
+
background main
|
|
51
51
|
box-shadow 0px 0px 3px 3px alpha(main, .35)
|
|
52
52
|
max-height 300px
|
|
53
53
|
overflow-y scroll
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
white-space nowrap
|
|
63
63
|
text-overflow ellipsis
|
|
64
64
|
&:hover, &.active
|
|
65
|
-
background-color
|
|
66
|
-
color
|
|
65
|
+
background-color #08c
|
|
66
|
+
color #eee
|
|
67
67
|
.bookmarks-sub-context-menu
|
|
68
68
|
width 380px
|
|
69
69
|
padding 20px 10px 10px 20px
|
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import HistoryItem from '../sidebar/history-item'
|
|
2
2
|
|
|
3
3
|
export default function HistorySubMenu (props) {
|
|
4
|
-
const { store } = window
|
|
5
4
|
return (
|
|
6
5
|
<div className='sub-context-menu'>
|
|
7
6
|
{
|
|
8
7
|
props.history.map(item => {
|
|
9
|
-
const title = createTitleWithTag(item)
|
|
10
8
|
return (
|
|
11
|
-
<
|
|
12
|
-
className='sub-context-menu-item'
|
|
13
|
-
title={title}
|
|
14
|
-
key={item.id}
|
|
15
|
-
onClick={() => store.onSelectHistory(item.id)}
|
|
16
|
-
>
|
|
17
|
-
{title}
|
|
18
|
-
</div>
|
|
9
|
+
<HistoryItem key={item.id} item={item} />
|
|
19
10
|
)
|
|
20
11
|
})
|
|
21
12
|
}
|
|
@@ -3,7 +3,7 @@ import { createTitleWithTag } from '../../common/create-title'
|
|
|
3
3
|
|
|
4
4
|
export default class TabsSubMenuChild extends PureComponent {
|
|
5
5
|
handleClick = () => {
|
|
6
|
-
window.store.
|
|
6
|
+
window.store.changeActiveTabId(this.props.item.id)
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
render () {
|
|
@@ -18,12 +18,7 @@ const e = window.translate
|
|
|
18
18
|
|
|
19
19
|
export default auto(function FooterEntry (props) {
|
|
20
20
|
function handleInfoPanel () {
|
|
21
|
-
|
|
22
|
-
store.rightPanelVisible = !store.rightPanelVisible
|
|
23
|
-
postMessage({
|
|
24
|
-
action: terminalActions.showInfoPanel,
|
|
25
|
-
activeTabId: store.activeTabId
|
|
26
|
-
})
|
|
21
|
+
window.store.openInfoPanel()
|
|
27
22
|
}
|
|
28
23
|
|
|
29
24
|
function batchInput (cmd, selectedTabIds) {
|
|
@@ -18,8 +18,8 @@ export default function LayoutItem (props) {
|
|
|
18
18
|
}
|
|
19
19
|
let currentElement = target
|
|
20
20
|
while (currentElement) {
|
|
21
|
-
if (currentElement.classList && currentElement.classList.contains('
|
|
22
|
-
|
|
21
|
+
if (currentElement.classList && currentElement.classList.contains('layout-item')) {
|
|
22
|
+
break
|
|
23
23
|
}
|
|
24
24
|
currentElement = currentElement.parentElement
|
|
25
25
|
}
|
|
@@ -40,9 +40,10 @@ export default auto(function Layout (props) {
|
|
|
40
40
|
rightPanelVisible,
|
|
41
41
|
rightPanelPinned,
|
|
42
42
|
rightPanelWidth,
|
|
43
|
-
resizeTrigger
|
|
43
|
+
resizeTrigger,
|
|
44
|
+
inActiveTerminal
|
|
44
45
|
} = props.store
|
|
45
|
-
const h = height - footerHeight - (pinnedQuickCommandBar ? quickCommandBoxHeight : 0) + resizeTrigger
|
|
46
|
+
const h = height - footerHeight - (inActiveTerminal && pinnedQuickCommandBar ? quickCommandBoxHeight : 0) + resizeTrigger
|
|
46
47
|
const l = pinned ? 43 + leftSidebarWidth : 43
|
|
47
48
|
const r = rightPanelVisible && rightPanelPinned ? rightPanelWidth : 0
|
|
48
49
|
return {
|