@electerm/electerm-react 2.3.75 → 2.3.100

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.
@@ -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,
@@ -281,7 +281,7 @@ export default function FormRenderer ({ config, props }) {
281
281
  onSelectProxy,
282
282
  onChangeAuthType,
283
283
  handleBlur: onBlur,
284
- onPaste,
284
+ handlePaste: onPaste,
285
285
  useIp
286
286
  }
287
287
 
@@ -61,7 +61,10 @@ export default memo(function TransferHistoryModal (props) {
61
61
  dataIndex: 'fromPath',
62
62
  key: 'fromPath',
63
63
  render: (txt, inst) => {
64
- return inst.fromPathReal || txt
64
+ const t = inst.fromPathReal || txt
65
+ return (
66
+ <div className='sftp-file history-file' title={t}>{t}</div>
67
+ )
65
68
  },
66
69
  sorter: sorterFactory('fromPath')
67
70
  }, {
@@ -69,7 +72,10 @@ export default memo(function TransferHistoryModal (props) {
69
72
  dataIndex: 'toPath',
70
73
  key: 'toPath',
71
74
  render: (txt, inst) => {
72
- return inst.toPathReal || txt
75
+ const t = inst.toPathReal || txt
76
+ return (
77
+ <div className='sftp-file history-file' title={t}>{t}</div>
78
+ )
73
79
  },
74
80
  sorter: sorterFactory('toPath')
75
81
  }, {
@@ -4,4 +4,11 @@
4
4
  .ant-badge-multiple-words
5
5
  padding 0 3px
6
6
  .transfer-list-card
7
- width calc(100% - 48px)
7
+ width calc(100vw - 48px)
8
+ .sftp-file
9
+ max-width calc(50vw - 250px)
10
+ overflow hidden
11
+ text-overflow ellipsis
12
+ white-space nowrap
13
+ &.history-file
14
+ max-width calc(50vw - 440px)
@@ -367,12 +367,14 @@ class Tab extends Component {
367
367
  if (name) {
368
368
  tunnel = `[${name}] ${tunnel}`
369
369
  }
370
- return <div key={tunnel}>{tunnel}</div>
370
+ return <div key={tunnel + '-' + i} className='ssh-tunnel-item'>{tunnel}</div>
371
371
  })
372
372
  return (
373
373
  <>
374
374
  <div>{title}</div>
375
- {list}
375
+ <div className='ssh-tunnel-list-wrapper'>
376
+ {list}
377
+ </div>
376
378
  </>
377
379
  )
378
380
  }
@@ -241,3 +241,8 @@
241
241
  .sidebar-panel-history .pd2x
242
242
  width 400px
243
243
  margin 0 auto
244
+
245
+ .ssh-tunnel-list-wrapper
246
+ max-height 300px
247
+ overflow-y auto
248
+
@@ -314,7 +314,9 @@ class Term extends Component {
314
314
  <div>
315
315
  <p>{e('paste')}:</p>
316
316
  <div className='paste-text'>
317
- {readClipboard()}
317
+ <pre>
318
+ <code>{readClipboard()}</code>
319
+ </pre>
318
320
  </div>
319
321
  </div>
320
322
  ),
@@ -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
- editorRef.current.resizableTextArea.textArea.setSelectionRange(match.start, match.end)
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
- editorRef.current.resizableTextArea.textArea.focus()
30
+ textarea.focus()
29
31
  }
30
32
 
31
33
  // Scroll to the selection position
32
- const textarea = editorRef.current.resizableTextArea.textArea
33
- const textBeforeSelection = props.value.substring(0, match.start)
34
- const lineBreaks = textBeforeSelection.split('\n').length - 1
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
- // Estimate the scroll position
37
- const lineHeight = 20 // Approximate line height in pixels
38
- const scrollPosition = lineHeight * lineBreaks
39
+ // Estimate the scroll position
40
+ const lineHeight = parseInt(window.getComputedStyle(textarea).lineHeight) || 20
41
+ const scrollPosition = lineHeight * lineBreaks
39
42
 
40
- textarea.scrollTop = Math.max(0, scrollPosition - textarea.clientHeight / 2)
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
- DownloadOutlined,
8
- UploadOutlined,
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={<DownloadOutlined />}
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={<UploadOutlined />}
52
+ icon={<ImportOutlined />}
53
53
  title={e('importFromFile')}
54
54
  />
55
55
  </Upload>
@@ -188,7 +188,7 @@ export default function TreeListItem (props) {
188
188
  {
189
189
  selected: selectedItemId === item.id
190
190
  },
191
- 'tree-item elli',
191
+ 'tree-item',
192
192
  {
193
193
  'is-category': isGroup,
194
194
  level2: item.level === 2
@@ -232,10 +232,7 @@ export default function TreeListItem (props) {
232
232
  onClick: onSelect,
233
233
  'data-item-id': item.id,
234
234
  'data-is-group': isGroup ? 'true' : 'false',
235
- 'data-parent-id': props.parentId,
236
- style: props.staticList
237
- ? { maxWidth: (props.leftSidebarWidth - 110) + 'px' }
238
- : undefined
235
+ 'data-parent-id': props.parentId
239
236
  }
240
237
  const key = item.id || uid()
241
238
  return (
@@ -11,6 +11,9 @@
11
11
  line-height 26px
12
12
  padding-left 5px
13
13
  border-radius 3px
14
+ overflow hidden
15
+ white-space nowrap
16
+ text-overflow ellipsis
14
17
  &.is-category
15
18
  .tree-item-title
16
19
  font-weight bold
@@ -30,13 +33,12 @@
30
33
  .tree-item-title
31
34
  flex-grow 1
32
35
  line-height 26px
33
- max-width 300px
34
36
  overflow hidden
35
37
  white-space nowrap
36
38
  text-overflow ellipsis
37
39
 
38
40
  .sidebar-panel .tree-item-title
39
- max-width 180px
41
+ max-width 100%
40
42
  .with-plus
41
43
  &:after
42
44
  content '+'
@@ -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 remainingTabs) {
236
+ for (const tab of copiedTabs) {
233
237
  if (!batchFirstTabs[tab.batch]) {
234
238
  batchFirstTabs[tab.batch] = tab.id
235
239
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "2.3.75",
3
+ "version": "2.3.100",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",