@electerm/electerm-react 2.3.136 → 2.3.151
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/batch-op/batch-op.jsx +3 -8
- package/client/components/bookmark-form/common/color-picker.jsx +16 -5
- package/client/components/bookmark-form/common/color-picker.styl +1 -2
- package/client/components/bookmark-form/common/connection-hopping.jsx +1 -0
- package/client/components/bookmark-form/config/common-fields.js +1 -0
- package/client/components/common/drawer.jsx +62 -0
- package/client/components/common/drawer.styl +34 -0
- package/client/components/profile/profile-form.jsx +1 -1
- package/client/components/quick-commands/qm.styl +2 -1
- package/client/components/quick-commands/quick-commands-form.jsx +1 -1
- package/client/components/setting-panel/list.jsx +1 -1
- package/client/components/setting-panel/setting-common.jsx +1 -1
- package/client/components/setting-panel/setting-terminal.jsx +1 -1
- package/client/components/setting-panel/setting-wrap.jsx +4 -10
- package/client/components/setting-panel/setting-wrap.styl +8 -6
- package/client/components/sftp/paged-list.jsx +2 -1
- package/client/components/sftp/sftp-entry.jsx +1 -1
- package/client/components/sftp/sftp.styl +13 -0
- package/client/components/tree-list/move-item-modal.jsx +114 -30
- package/client/components/tree-list/tree-list.jsx +1 -1
- package/client/components/tree-list/tree-list.styl +6 -1
- package/package.json +1 -1
|
@@ -11,9 +11,9 @@ import {
|
|
|
11
11
|
Input,
|
|
12
12
|
Button,
|
|
13
13
|
Table,
|
|
14
|
-
Drawer,
|
|
15
14
|
Tabs
|
|
16
15
|
} from 'antd'
|
|
16
|
+
import Drawer from '../common/drawer'
|
|
17
17
|
import {
|
|
18
18
|
sidebarWidth,
|
|
19
19
|
statusMap,
|
|
@@ -672,15 +672,10 @@ export default class BatchOp extends PureComponent {
|
|
|
672
672
|
const pops = {
|
|
673
673
|
open: showBatchOp,
|
|
674
674
|
onClose: this.handleCancel,
|
|
675
|
-
className: 'setting-wrap',
|
|
675
|
+
className: 'setting-wrap batch-op-wrap',
|
|
676
676
|
size: innerWidth - sidebarWidth,
|
|
677
677
|
zIndex: 888,
|
|
678
|
-
placement: 'left'
|
|
679
|
-
styles: {
|
|
680
|
-
header: {
|
|
681
|
-
display: 'none'
|
|
682
|
-
}
|
|
683
|
-
}
|
|
678
|
+
placement: 'left'
|
|
684
679
|
}
|
|
685
680
|
return (
|
|
686
681
|
<Drawer
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
|
-
import { Popover } from 'antd'
|
|
3
|
-
import { HexColorPicker, RgbaColorPicker } from 'react-colorful'
|
|
2
|
+
import { Popover, ColorPicker as AntColorPicker } from 'antd'
|
|
4
3
|
import { defaultColors, getRandomHexColor } from '../../../common/rand-hex-color.js'
|
|
5
4
|
import { HexInput } from './hex-input.jsx'
|
|
6
5
|
import './color-picker.styl'
|
|
@@ -18,8 +17,11 @@ export const ColorPicker = React.forwardRef((props, ref) => {
|
|
|
18
17
|
setVisible(vis)
|
|
19
18
|
}
|
|
20
19
|
|
|
20
|
+
function onColorChange (color) {
|
|
21
|
+
handleChange(props.isRgba ? color.toRgbString() : color.toHexString())
|
|
22
|
+
}
|
|
23
|
+
|
|
21
24
|
function renderContent () {
|
|
22
|
-
const Picker = props.isRgba ? RgbaColorPicker : HexColorPicker
|
|
23
25
|
return (
|
|
24
26
|
<div className='color-picker-box'>
|
|
25
27
|
<div className='fix'>
|
|
@@ -40,7 +42,10 @@ export const ColorPicker = React.forwardRef((props, ref) => {
|
|
|
40
42
|
}
|
|
41
43
|
</div>
|
|
42
44
|
<div className='fright'>
|
|
43
|
-
<
|
|
45
|
+
<AntColorPicker
|
|
46
|
+
value={value}
|
|
47
|
+
onChange={onColorChange}
|
|
48
|
+
/>
|
|
44
49
|
</div>
|
|
45
50
|
</div>
|
|
46
51
|
<div className='pd1y'>
|
|
@@ -57,7 +62,13 @@ export const ColorPicker = React.forwardRef((props, ref) => {
|
|
|
57
62
|
if (props.disabled) return inner
|
|
58
63
|
|
|
59
64
|
return (
|
|
60
|
-
<Popover
|
|
65
|
+
<Popover
|
|
66
|
+
content={renderContent()}
|
|
67
|
+
trigger='click'
|
|
68
|
+
open={visible}
|
|
69
|
+
placement='bottomLeft'
|
|
70
|
+
onOpenChange={handleVisibleChange}
|
|
71
|
+
>
|
|
61
72
|
{inner}
|
|
62
73
|
</Popover>
|
|
63
74
|
)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple drawer component without animation
|
|
3
|
+
* Replaces antd Drawer for better performance
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import classnames from 'classnames'
|
|
7
|
+
import './drawer.styl'
|
|
8
|
+
|
|
9
|
+
export default function Drawer (props) {
|
|
10
|
+
const {
|
|
11
|
+
open,
|
|
12
|
+
placement = 'left',
|
|
13
|
+
size,
|
|
14
|
+
zIndex = 1000,
|
|
15
|
+
className,
|
|
16
|
+
children,
|
|
17
|
+
styles = {},
|
|
18
|
+
onClose
|
|
19
|
+
} = props
|
|
20
|
+
|
|
21
|
+
function handleMaskClick (e) {
|
|
22
|
+
if (e.target === e.currentTarget && onClose) {
|
|
23
|
+
onClose()
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!open) {
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const drawerStyle = {
|
|
32
|
+
zIndex
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const contentStyle = {
|
|
36
|
+
width: typeof size === 'number' ? `${size}px` : size,
|
|
37
|
+
...styles.content
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const cls = classnames(
|
|
41
|
+
'custom-drawer',
|
|
42
|
+
`custom-drawer-${placement}`,
|
|
43
|
+
className
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<div className={cls} style={drawerStyle}>
|
|
48
|
+
<div
|
|
49
|
+
className='custom-drawer-mask'
|
|
50
|
+
onClick={handleMaskClick}
|
|
51
|
+
/>
|
|
52
|
+
<div
|
|
53
|
+
className='custom-drawer-content-wrapper'
|
|
54
|
+
style={contentStyle}
|
|
55
|
+
>
|
|
56
|
+
<div className='custom-drawer-content'>
|
|
57
|
+
{children}
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
.custom-drawer
|
|
2
|
+
position fixed
|
|
3
|
+
top 0
|
|
4
|
+
left 43px
|
|
5
|
+
right 0
|
|
6
|
+
bottom 0
|
|
7
|
+
|
|
8
|
+
.custom-drawer-mask
|
|
9
|
+
position absolute
|
|
10
|
+
top 0
|
|
11
|
+
left 0
|
|
12
|
+
right 0
|
|
13
|
+
bottom 0
|
|
14
|
+
background rgba(0, 0, 0, 0.45)
|
|
15
|
+
|
|
16
|
+
.custom-drawer-content-wrapper
|
|
17
|
+
position absolute
|
|
18
|
+
top 0
|
|
19
|
+
bottom 0
|
|
20
|
+
background var(--main)
|
|
21
|
+
box-shadow 2px 0 8px rgba(0, 0, 0, 0.15)
|
|
22
|
+
overflow auto
|
|
23
|
+
color var(--text)
|
|
24
|
+
|
|
25
|
+
.custom-drawer-left .custom-drawer-content-wrapper
|
|
26
|
+
left 0
|
|
27
|
+
|
|
28
|
+
.custom-drawer-right .custom-drawer-content-wrapper
|
|
29
|
+
right 0
|
|
30
|
+
|
|
31
|
+
.custom-drawer-content
|
|
32
|
+
position relative
|
|
33
|
+
height 100%
|
|
34
|
+
width 100%
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { Component } from 'react'
|
|
6
|
-
import
|
|
6
|
+
import Drawer from '../common/drawer'
|
|
7
7
|
import { CloseCircleOutlined } from '@ant-design/icons'
|
|
8
8
|
import { sidebarWidth } from '../../common/constants'
|
|
9
9
|
import AppDrag from '../tabs/app-drag'
|
|
@@ -23,13 +23,7 @@ export default class SettingWrap extends Component {
|
|
|
23
23
|
className: 'setting-wrap',
|
|
24
24
|
size: this.props.innerWidth - sidebarWidth,
|
|
25
25
|
zIndex: 888,
|
|
26
|
-
placement: 'left'
|
|
27
|
-
destroyOnHidden: true,
|
|
28
|
-
styles: {
|
|
29
|
-
header: {
|
|
30
|
-
display: 'none'
|
|
31
|
-
}
|
|
32
|
-
}
|
|
26
|
+
placement: 'left'
|
|
33
27
|
}
|
|
34
28
|
return (
|
|
35
29
|
<Drawer
|
|
@@ -40,13 +34,13 @@ export default class SettingWrap extends Component {
|
|
|
40
34
|
onClick={this.props.onCancel}
|
|
41
35
|
/>
|
|
42
36
|
<CloseCircleOutlined
|
|
43
|
-
className='close-setting-wrap
|
|
37
|
+
className='close-setting-wrap alt-close-setting-wrap'
|
|
44
38
|
onClick={this.props.onCancel}
|
|
45
39
|
/>
|
|
46
40
|
{
|
|
47
41
|
this.props.useSystemTitleBar ? null : <AppDrag />
|
|
48
42
|
}
|
|
49
|
-
{this.props.
|
|
43
|
+
{this.props.children}
|
|
50
44
|
</Drawer>
|
|
51
45
|
)
|
|
52
46
|
}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
.close-setting-wrap-icon
|
|
2
|
+
|
|
3
|
+
.close-setting-wrap
|
|
5
4
|
position absolute
|
|
6
5
|
top 70px
|
|
7
6
|
font-size 16px
|
|
8
7
|
cursor pointer
|
|
9
8
|
z-index 889
|
|
9
|
+
right 20px
|
|
10
10
|
&:hover
|
|
11
11
|
color var(--success)
|
|
12
12
|
.alt-close-setting-wrap
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
left 20px
|
|
14
|
+
right auto
|
|
15
|
+
.batch-op-wrap .close-setting-wrap
|
|
16
|
+
top 40px
|
|
17
|
+
right 30px
|
|
16
18
|
.setting-row
|
|
17
19
|
position absolute
|
|
18
20
|
top 127px
|
|
@@ -37,8 +37,9 @@ export default class ScrollFiles extends Component {
|
|
|
37
37
|
current: this.state.page,
|
|
38
38
|
pageSize: this.state.pageSize,
|
|
39
39
|
total: this.props.list.length,
|
|
40
|
+
showLessItems: true,
|
|
40
41
|
showSizeChanger: false,
|
|
41
|
-
simple:
|
|
42
|
+
simple: false,
|
|
42
43
|
onChange: this.onChange
|
|
43
44
|
}
|
|
44
45
|
return (
|
|
@@ -164,6 +164,19 @@
|
|
|
164
164
|
.pager-wrap
|
|
165
165
|
z-index 4
|
|
166
166
|
position relative
|
|
167
|
+
|
|
168
|
+
.sftp-has-pager
|
|
169
|
+
.sftp-table-content
|
|
170
|
+
position static
|
|
171
|
+
padding-bottom 42px
|
|
172
|
+
.pager-wrap
|
|
173
|
+
position absolute
|
|
174
|
+
bottom 0
|
|
175
|
+
left 0
|
|
176
|
+
width 100%
|
|
177
|
+
background var(--main)
|
|
178
|
+
border-top 1px solid var(--main-darker)
|
|
179
|
+
|
|
167
180
|
.file-header-context-menu
|
|
168
181
|
position fixed
|
|
169
182
|
z-index 999
|
|
@@ -1,17 +1,62 @@
|
|
|
1
|
-
// render bookmark select, use antd tree
|
|
1
|
+
// render bookmark select, use antd tree
|
|
2
2
|
import { useState, useEffect } from 'react'
|
|
3
3
|
import {
|
|
4
|
-
MergeOutlined
|
|
4
|
+
MergeOutlined,
|
|
5
|
+
SearchOutlined
|
|
5
6
|
} from '@ant-design/icons'
|
|
6
7
|
import buildGroupData from '../bookmark-form/common/bookmark-group-tree-format'
|
|
7
|
-
import {
|
|
8
|
+
import { Tree, Modal, Button, Input } from 'antd'
|
|
8
9
|
import { auto } from 'manate/react'
|
|
9
10
|
const e = window.translate
|
|
10
11
|
|
|
11
12
|
const rootId = '__root__'
|
|
12
13
|
|
|
14
|
+
// Helper function to filter tree data based on search text
|
|
15
|
+
function filterTreeData (data, searchText) {
|
|
16
|
+
if (!searchText) {
|
|
17
|
+
return data
|
|
18
|
+
}
|
|
19
|
+
const lowerSearch = searchText.toLowerCase()
|
|
20
|
+
|
|
21
|
+
function filterNodes (nodes) {
|
|
22
|
+
return nodes.reduce((acc, node) => {
|
|
23
|
+
const titleText = typeof node.title === 'string'
|
|
24
|
+
? node.title
|
|
25
|
+
: (node.title?.props?.children?.[1] || node.title?.props?.children || '')
|
|
26
|
+
const titleStr = String(titleText).toLowerCase()
|
|
27
|
+
const children = node.children ? filterNodes(node.children) : []
|
|
28
|
+
|
|
29
|
+
if (titleStr.includes(lowerSearch) || children.length > 0) {
|
|
30
|
+
acc.push({
|
|
31
|
+
...node,
|
|
32
|
+
children: children.length > 0 ? children : node.children
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
return acc
|
|
36
|
+
}, [])
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return filterNodes(data)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Helper function to get all keys from tree data
|
|
43
|
+
function getAllKeys (data) {
|
|
44
|
+
const keys = []
|
|
45
|
+
function traverse (nodes) {
|
|
46
|
+
for (const node of nodes) {
|
|
47
|
+
keys.push(node.key)
|
|
48
|
+
if (node.children) {
|
|
49
|
+
traverse(node.children)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
traverse(data)
|
|
54
|
+
return keys
|
|
55
|
+
}
|
|
56
|
+
|
|
13
57
|
export default auto(function MoveItemModal (props) {
|
|
14
58
|
const [groupId, setGroupId] = useState(undefined)
|
|
59
|
+
const [searchText, setSearchText] = useState('')
|
|
15
60
|
const {
|
|
16
61
|
openMoveModal,
|
|
17
62
|
moveItem,
|
|
@@ -27,10 +72,11 @@ export default auto(function MoveItemModal (props) {
|
|
|
27
72
|
})
|
|
28
73
|
}
|
|
29
74
|
|
|
30
|
-
// Reset groupId when modal opens
|
|
75
|
+
// Reset groupId and search when modal opens
|
|
31
76
|
useEffect(() => {
|
|
32
77
|
if (openMoveModal) {
|
|
33
78
|
setGroupId(undefined)
|
|
79
|
+
setSearchText('')
|
|
34
80
|
}
|
|
35
81
|
}, [openMoveModal])
|
|
36
82
|
|
|
@@ -60,6 +106,31 @@ export default auto(function MoveItemModal (props) {
|
|
|
60
106
|
disabled: false
|
|
61
107
|
})
|
|
62
108
|
}
|
|
109
|
+
|
|
110
|
+
// Filter tree data based on search
|
|
111
|
+
const filteredData = filterTreeData(data, searchText)
|
|
112
|
+
const expandedKeys = getAllKeys(filteredData)
|
|
113
|
+
|
|
114
|
+
function onTreeSelect (selectedKeys) {
|
|
115
|
+
if (selectedKeys.length > 0) {
|
|
116
|
+
// Find the node to check if it's disabled
|
|
117
|
+
const findNode = (nodes, key) => {
|
|
118
|
+
for (const node of nodes) {
|
|
119
|
+
if (node.key === key) return node
|
|
120
|
+
if (node.children) {
|
|
121
|
+
const found = findNode(node.children, key)
|
|
122
|
+
if (found) return found
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return null
|
|
126
|
+
}
|
|
127
|
+
const node = findNode(data, selectedKeys[0])
|
|
128
|
+
if (node && !node.disabled) {
|
|
129
|
+
setGroupId(selectedKeys[0])
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
63
134
|
function onSelect () {
|
|
64
135
|
const {
|
|
65
136
|
bookmarkGroups
|
|
@@ -109,43 +180,56 @@ export default auto(function MoveItemModal (props) {
|
|
|
109
180
|
}
|
|
110
181
|
onCancelMoveItem()
|
|
111
182
|
}
|
|
183
|
+
|
|
184
|
+
const footer = (
|
|
185
|
+
<>
|
|
186
|
+
<Button
|
|
187
|
+
type='primary'
|
|
188
|
+
onClick={onSelect}
|
|
189
|
+
disabled={!groupId}
|
|
190
|
+
>
|
|
191
|
+
{e('ok')}
|
|
192
|
+
</Button>
|
|
193
|
+
<Button
|
|
194
|
+
onClick={onCancelMoveItem}
|
|
195
|
+
className='mg1l'
|
|
196
|
+
>
|
|
197
|
+
{e('cancel')}
|
|
198
|
+
</Button>
|
|
199
|
+
</>
|
|
200
|
+
)
|
|
201
|
+
|
|
112
202
|
const modalProps = {
|
|
113
203
|
open: openMoveModal,
|
|
114
204
|
title: e('moveTo'),
|
|
115
|
-
footer
|
|
205
|
+
footer,
|
|
116
206
|
onCancel: onCancelMoveItem
|
|
117
207
|
}
|
|
208
|
+
|
|
118
209
|
const treeProps = {
|
|
119
|
-
treeData:
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
treeDefaultExpandAll: true,
|
|
126
|
-
className: 'width-100'
|
|
210
|
+
treeData: filteredData,
|
|
211
|
+
onSelect: onTreeSelect,
|
|
212
|
+
selectedKeys: groupId ? [groupId] : [],
|
|
213
|
+
expandedKeys,
|
|
214
|
+
autoExpandParent: true,
|
|
215
|
+
className: 'width-100 move-item-tree'
|
|
127
216
|
}
|
|
217
|
+
|
|
128
218
|
return (
|
|
129
219
|
<Modal {...modalProps}>
|
|
130
|
-
<div className='
|
|
131
|
-
<
|
|
132
|
-
{
|
|
220
|
+
<div className='pd1b'>
|
|
221
|
+
<Input
|
|
222
|
+
placeholder={e('search')}
|
|
223
|
+
prefix={<SearchOutlined />}
|
|
224
|
+
value={searchText}
|
|
225
|
+
onChange={e => setSearchText(e.target.value)}
|
|
226
|
+
allowClear
|
|
133
227
|
/>
|
|
134
228
|
</div>
|
|
135
|
-
<div className='
|
|
136
|
-
<
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
disabled={!groupId}
|
|
140
|
-
>
|
|
141
|
-
{e('ok')}
|
|
142
|
-
</Button>
|
|
143
|
-
<Button
|
|
144
|
-
onClick={onCancelMoveItem}
|
|
145
|
-
className='mg1l'
|
|
146
|
-
>
|
|
147
|
-
{e('cancel')}
|
|
148
|
-
</Button>
|
|
229
|
+
<div className='move-item-tree-wrap'>
|
|
230
|
+
<Tree
|
|
231
|
+
{...treeProps}
|
|
232
|
+
/>
|
|
149
233
|
</div>
|
|
150
234
|
</Modal>
|
|
151
235
|
)
|