@electerm/electerm-react 2.3.85 → 2.3.103
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/components/bookmark-form/config/common-fields.js +16 -0
- package/client/components/bookmark-form/form-renderer.jsx +1 -1
- package/client/components/terminal/terminal.jsx +3 -1
- package/client/components/text-editor/simple-editor.jsx +17 -11
- package/client/components/tree-list/bookmark-transport.jsx +4 -4
- package/client/components/tree-list/tree-list.styl +1 -1
- package/client/store/tab.js +6 -2
- package/package.json +1 -1
|
@@ -43,6 +43,20 @@ export const commonFields = {
|
|
|
43
43
|
label: e('password')
|
|
44
44
|
},
|
|
45
45
|
|
|
46
|
+
loginPrompt: {
|
|
47
|
+
type: 'input',
|
|
48
|
+
name: 'loginPrompt',
|
|
49
|
+
label: e('loginPrompt'),
|
|
50
|
+
props: { placeholder: '/login[: ]*$/i' }
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
passwordPrompt: {
|
|
54
|
+
type: 'input',
|
|
55
|
+
name: 'passwordPrompt',
|
|
56
|
+
label: e('passwordPrompt'),
|
|
57
|
+
props: { placeholder: '/password[: ]*$/i' }
|
|
58
|
+
},
|
|
59
|
+
|
|
46
60
|
port: {
|
|
47
61
|
type: 'number',
|
|
48
62
|
name: 'port',
|
|
@@ -274,6 +288,8 @@ export const telnetAuthFields = [
|
|
|
274
288
|
commonFields.host,
|
|
275
289
|
commonFields.username,
|
|
276
290
|
commonFields.password,
|
|
291
|
+
commonFields.loginPrompt,
|
|
292
|
+
commonFields.passwordPrompt,
|
|
277
293
|
{ type: 'profileItem', name: '__profile__', label: '', profileFilter: d => !isEmpty(d.telnet) },
|
|
278
294
|
commonFields.port,
|
|
279
295
|
commonFields.runScripts,
|
|
@@ -20,24 +20,32 @@ export default function SimpleEditor (props) {
|
|
|
20
20
|
if (currentMatch >= 0 && occurrences.length > 0) {
|
|
21
21
|
const match = occurrences[currentMatch]
|
|
22
22
|
if (editorRef.current) {
|
|
23
|
+
const textarea = editorRef.current.resizableTextArea.textArea
|
|
24
|
+
|
|
23
25
|
// Set selection range to select the matched text
|
|
24
|
-
|
|
26
|
+
textarea.setSelectionRange(match.start, match.end)
|
|
25
27
|
|
|
26
28
|
// Only focus the textarea when explicitly navigating between matches
|
|
27
29
|
if (isNavigating) {
|
|
28
|
-
|
|
30
|
+
textarea.focus()
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
// Scroll to the selection position
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
// Use setTimeout to ensure the selection is rendered before scrolling
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
const textBeforeSelection = props.value.substring(0, match.start)
|
|
37
|
+
const lineBreaks = textBeforeSelection.split('\n').length - 1
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
// Estimate the scroll position
|
|
40
|
+
const lineHeight = parseInt(window.getComputedStyle(textarea).lineHeight) || 20
|
|
41
|
+
const scrollPosition = lineHeight * lineBreaks
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
// Scroll to center the match, but ensure we can scroll to the bottom
|
|
44
|
+
const targetScroll = scrollPosition - textarea.clientHeight / 2
|
|
45
|
+
const maxScroll = textarea.scrollHeight - textarea.clientHeight
|
|
46
|
+
|
|
47
|
+
textarea.scrollTop = Math.max(0, Math.min(targetScroll, maxScroll))
|
|
48
|
+
}, 0)
|
|
41
49
|
}
|
|
42
50
|
}
|
|
43
51
|
// Reset navigating flag after using it
|
|
@@ -89,8 +97,6 @@ export default function SimpleEditor (props) {
|
|
|
89
97
|
|
|
90
98
|
function handleChange (e) {
|
|
91
99
|
setSearchKeyword(e.target.value)
|
|
92
|
-
findMatches()
|
|
93
|
-
goToNextMatch()
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
// Navigate to next match
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { PureComponent } from 'react'
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
ExportOutlined,
|
|
8
|
+
ImportOutlined,
|
|
9
9
|
EditOutlined
|
|
10
10
|
} from '@ant-design/icons'
|
|
11
11
|
import { Upload, Button } from 'antd'
|
|
@@ -36,7 +36,7 @@ export default class BookmarkTransport extends PureComponent {
|
|
|
36
36
|
return [
|
|
37
37
|
this.renderEdit(),
|
|
38
38
|
<Button
|
|
39
|
-
icon={<
|
|
39
|
+
icon={<ExportOutlined />}
|
|
40
40
|
onClick={this.handleDownload}
|
|
41
41
|
title={e('export')}
|
|
42
42
|
className='download-bookmark-icon'
|
|
@@ -49,7 +49,7 @@ export default class BookmarkTransport extends PureComponent {
|
|
|
49
49
|
key='Upload'
|
|
50
50
|
>
|
|
51
51
|
<Button
|
|
52
|
-
icon={<
|
|
52
|
+
icon={<ImportOutlined />}
|
|
53
53
|
title={e('importFromFile')}
|
|
54
54
|
/>
|
|
55
55
|
</Upload>
|
package/client/store/tab.js
CHANGED
|
@@ -227,9 +227,13 @@ export default Store => {
|
|
|
227
227
|
const removedSet = new Set(removedIds)
|
|
228
228
|
const batchFirstTabs = {}
|
|
229
229
|
const currentIdNeedFix = removedSet.has(store.activeTabId)
|
|
230
|
-
|
|
230
|
+
const copiedTabs = remainingTabs.map(t => ({
|
|
231
|
+
id: t.id,
|
|
232
|
+
batch: t.batch,
|
|
233
|
+
tabCount: t.tabCount
|
|
234
|
+
})).sort((a, b) => b.tabCount - a.tabCount)
|
|
231
235
|
// Get first valid tab for each batch
|
|
232
|
-
for (const tab of
|
|
236
|
+
for (const tab of copiedTabs) {
|
|
233
237
|
if (!batchFirstTabs[tab.batch]) {
|
|
234
238
|
batchFirstTabs[tab.batch] = tab.id
|
|
235
239
|
}
|