@electerm/electerm-react 1.60.16 → 1.60.29
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/clipboard.js +1 -14
- package/client/common/constants.js +0 -43
- package/client/common/data-compare.js +55 -0
- package/client/common/default-setting.js +2 -10
- package/client/common/resolve.js +18 -22
- package/client/common/sftp.js +0 -3
- package/client/components/ai/ai-chat.jsx +30 -6
- package/client/components/ai/ai-config.jsx +17 -6
- package/client/components/batch-op/batch-op.jsx +3 -24
- package/client/components/bookmark-form/bookmark-group-tree-format.js +7 -9
- package/client/components/bookmark-form/form-ssh-common.jsx +0 -2
- package/client/components/bookmark-form/ssh-form.jsx +8 -41
- package/client/components/bookmark-form/tree-delete.jsx +6 -15
- package/client/components/common/animate-text.jsx +3 -4
- package/client/components/common/drag-handle.jsx +59 -45
- package/client/components/common/drag-handle.styl +2 -1
- package/client/components/common/input-auto-focus.jsx +29 -63
- package/client/components/common/ref.js +24 -0
- package/client/components/footer/batch-input.jsx +1 -6
- package/client/components/footer/footer-entry.jsx +13 -16
- package/client/components/footer/footer.styl +0 -5
- package/client/components/icons/ai-icon.jsx +17 -0
- package/client/components/icons/ai-icon.styl +3 -0
- package/client/components/layout/layout-item.jsx +14 -0
- package/client/components/main/main.jsx +8 -19
- package/client/components/main/upgrade.jsx +13 -25
- package/client/components/profile/profile-form-elem.jsx +1 -2
- package/client/components/quick-commands/on-drop.js +1 -12
- package/client/components/quick-commands/quick-command-transport-mod.jsx +3 -13
- package/client/components/quick-commands/quick-commands-form-elem.jsx +1 -2
- package/client/components/rdp/rdp-session.jsx +4 -4
- package/client/components/session/session.jsx +9 -11
- package/client/components/setting-panel/on-tree-drop.js +4 -35
- package/client/components/setting-panel/setting-common.jsx +4 -1
- package/client/components/setting-panel/setting-modal.jsx +7 -5
- package/client/components/setting-panel/tab-settings.jsx +0 -1
- package/client/components/setting-sync/setting-sync.jsx +0 -1
- package/client/components/sftp/address-bookmark-item.jsx +1 -15
- package/client/components/sftp/confirm-modal-store.jsx +2 -2
- package/client/components/sftp/{file-mode-modal.jsx → file-info-modal.jsx} +137 -37
- package/client/components/sftp/file-item.jsx +156 -192
- package/client/components/sftp/file-table-header.jsx +98 -0
- package/client/components/sftp/list-table-ui.jsx +125 -416
- package/client/components/sftp/sftp-entry.jsx +102 -128
- package/client/components/sftp/sftp.styl +6 -22
- package/client/components/sftp/transfer-conflict-store.jsx +8 -12
- package/client/components/sftp/transport-action-store.jsx +7 -15
- package/client/components/shortcuts/shortcut-control.jsx +72 -3
- package/client/components/shortcuts/shortcut-handler.js +0 -1
- package/client/components/side-panel-r/side-panel-r.jsx +7 -4
- package/client/components/sidebar/history.jsx +3 -0
- package/client/components/sidebar/index.jsx +1 -1
- package/client/components/sidebar/info-modal.jsx +3 -0
- package/client/components/sidebar/side-panel.jsx +7 -4
- package/client/components/sidebar/sidebar-panel.jsx +1 -1
- package/client/components/sidebar/sidebar.styl +3 -3
- package/client/components/sys-menu/icons-map.jsx +52 -0
- package/client/components/{context-menu → sys-menu}/menu-btn.jsx +33 -45
- package/client/components/sys-menu/sys-menu.jsx +163 -0
- package/client/components/{context-menu/context-menu.styl → sys-menu/sys-menu.styl} +2 -11
- package/client/components/tabs/index.jsx +5 -97
- package/client/components/tabs/tab.jsx +121 -73
- package/client/components/tabs/tabs.styl +4 -1
- package/client/components/terminal/term-search.jsx +16 -28
- package/client/components/terminal/terminal-interactive.jsx +0 -2
- package/client/components/terminal/{index.jsx → terminal.jsx} +126 -248
- package/client/components/terminal-info/base.jsx +21 -46
- package/client/components/terminal-info/terminal-info.jsx +3 -0
- package/client/components/text-editor/text-editor.jsx +38 -53
- package/client/components/theme/theme-form.jsx +0 -2
- package/client/components/tree-list/bookmark-toolbar.jsx +23 -47
- package/client/components/tree-list/bookmark-transport.jsx +2 -90
- package/client/components/tree-list/move-item-modal.jsx +101 -0
- package/client/components/tree-list/tree-list-item.jsx +6 -8
- package/client/components/tree-list/tree-list.jsx +48 -273
- package/client/components/vnc/vnc-session.jsx +5 -3
- package/client/store/app-upgrade.js +2 -5
- package/client/store/bookmark-group.js +74 -28
- package/client/store/common.js +36 -54
- package/client/store/event.js +4 -37
- package/client/store/init-state.js +9 -12
- package/client/store/item.js +34 -39
- package/client/store/load-data.js +5 -1
- package/client/store/quick-command.js +2 -12
- package/client/store/session.js +6 -7
- package/client/store/setting.js +3 -7
- package/client/store/sidebar.js +2 -8
- package/client/store/store.js +0 -20
- package/client/store/system-menu.js +1 -2
- package/client/store/tab.js +29 -1
- package/client/store/terminal-theme.js +0 -4
- package/client/store/watch.js +26 -4
- package/package.json +1 -1
- package/client/common/post-msg.js +0 -3
- package/client/components/common/native-input.jsx +0 -30
- package/client/components/context-menu/context-menu.jsx +0 -339
- package/client/components/sftp/file-props-modal.jsx +0 -210
- package/client/store/context-menu.js +0 -23
- /package/client/components/{context-menu → sys-menu}/boomarks.jsx +0 -0
- /package/client/components/{context-menu → sys-menu}/history.jsx +0 -0
- /package/client/components/{context-menu → sys-menu}/icon-holder.jsx +0 -0
- /package/client/components/{context-menu → sys-menu}/sub-tab-menu.jsx +0 -0
- /package/client/components/{context-menu → sys-menu}/tabs.jsx +0 -0
- /package/client/components/{context-menu → sys-menu}/zoom.jsx +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* terminal/sftp wrapper
|
|
3
3
|
*/
|
|
4
|
-
import { Component } from 'react'
|
|
5
|
-
import Term from '../terminal'
|
|
4
|
+
import { Component, createRef } from 'react'
|
|
5
|
+
import Term from '../terminal/terminal.jsx'
|
|
6
6
|
import Sftp from '../sftp/sftp-entry'
|
|
7
7
|
import RdpSession from '../rdp/rdp-session'
|
|
8
8
|
import VncSession from '../vnc/vnc-session'
|
|
@@ -23,14 +23,13 @@ import copy from 'json-deep-copy'
|
|
|
23
23
|
import classnames from 'classnames'
|
|
24
24
|
import {
|
|
25
25
|
paneMap,
|
|
26
|
-
terminalActions,
|
|
27
26
|
connectionMap,
|
|
28
27
|
terminalRdpType,
|
|
29
28
|
terminalVncType,
|
|
30
29
|
terminalWebType
|
|
31
30
|
} from '../../common/constants'
|
|
31
|
+
import { refs } from '../common/ref'
|
|
32
32
|
import safeName from '../../common/safe-name'
|
|
33
|
-
import postMessage from '../../common/post-msg'
|
|
34
33
|
import './session.styl'
|
|
35
34
|
|
|
36
35
|
const e = window.translate
|
|
@@ -38,6 +37,8 @@ const e = window.translate
|
|
|
38
37
|
export default class SessionWrapper extends Component {
|
|
39
38
|
constructor (props) {
|
|
40
39
|
super(props)
|
|
40
|
+
// Add ref
|
|
41
|
+
this.domRef = createRef()
|
|
41
42
|
this.state = {
|
|
42
43
|
enableSftp: false,
|
|
43
44
|
cwd: '',
|
|
@@ -59,7 +60,7 @@ export default class SessionWrapper extends Component {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
getDom = () => {
|
|
62
|
-
return
|
|
63
|
+
return this.domRef.current
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
handleClick = () => {
|
|
@@ -358,10 +359,7 @@ export default class SessionWrapper extends Component {
|
|
|
358
359
|
}
|
|
359
360
|
|
|
360
361
|
handleOpenSearch = () => {
|
|
361
|
-
|
|
362
|
-
action: terminalActions.openTerminalSearch,
|
|
363
|
-
activeTabId: this.props.tab.id
|
|
364
|
-
})
|
|
362
|
+
refs.get('term-' + this.props.tab.id)?.toggleSearch()
|
|
365
363
|
}
|
|
366
364
|
|
|
367
365
|
renderSearchIcon = () => {
|
|
@@ -507,7 +505,7 @@ export default class SessionWrapper extends Component {
|
|
|
507
505
|
}
|
|
508
506
|
|
|
509
507
|
render () {
|
|
510
|
-
const { pane
|
|
508
|
+
const { pane } = this.props.tab
|
|
511
509
|
const cls = classnames(
|
|
512
510
|
'term-sftp-box',
|
|
513
511
|
pane,
|
|
@@ -520,7 +518,6 @@ export default class SessionWrapper extends Component {
|
|
|
520
518
|
)
|
|
521
519
|
const divProps = {
|
|
522
520
|
className: cls,
|
|
523
|
-
id: `is-${id}`,
|
|
524
521
|
onDragEnter: this.onDragEnter,
|
|
525
522
|
onDragLeave: this.onDragLeave,
|
|
526
523
|
onDrop: this.onDrop,
|
|
@@ -529,6 +526,7 @@ export default class SessionWrapper extends Component {
|
|
|
529
526
|
}
|
|
530
527
|
return (
|
|
531
528
|
<div
|
|
529
|
+
ref={this.domRef}
|
|
532
530
|
{...divProps}
|
|
533
531
|
>
|
|
534
532
|
{this.renderControl()}
|
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
} from '../../common/constants'
|
|
8
8
|
import { isEqual, find, last, remove } from 'lodash-es'
|
|
9
9
|
import copy from 'json-deep-copy'
|
|
10
|
+
import { action } from 'manate'
|
|
10
11
|
|
|
11
|
-
export default (info, props) => {
|
|
12
|
+
export default action((info, props) => {
|
|
12
13
|
const {
|
|
13
14
|
dropToGap,
|
|
14
15
|
dragNode,
|
|
@@ -23,10 +24,7 @@ export default (info, props) => {
|
|
|
23
24
|
const toPosesLevel = toPoses.slice(0, toPoses.length - 1)
|
|
24
25
|
const isSameLevel = fromPosesLevel.length === toPosesLevel.length
|
|
25
26
|
const isSameCat = isEqual(fromPosesLevel, toPosesLevel) && dropToGap
|
|
26
|
-
const bookmarks =
|
|
27
|
-
const bookmarkGroups = copy(
|
|
28
|
-
props.bookmarkGroups
|
|
29
|
-
)
|
|
27
|
+
const { bookmarks, bookmarkGroups } = window.store
|
|
30
28
|
let from = find(
|
|
31
29
|
bookmarks,
|
|
32
30
|
d => d.id === fromId
|
|
@@ -163,7 +161,6 @@ export default (info, props) => {
|
|
|
163
161
|
if (!fromLeaf) {
|
|
164
162
|
from.level = toFirstLevel ? 1 : 2
|
|
165
163
|
}
|
|
166
|
-
const updates = []
|
|
167
164
|
if (toFirstLevel) {
|
|
168
165
|
fromIndex = bookmarkGroups.findIndex(d => d.id === fromId)
|
|
169
166
|
from = copy(from)
|
|
@@ -191,32 +188,4 @@ export default (info, props) => {
|
|
|
191
188
|
remove(arr, d => d === 'tobedel')
|
|
192
189
|
}
|
|
193
190
|
}
|
|
194
|
-
|
|
195
|
-
const { id, ...rest } = fromGroup
|
|
196
|
-
updates.push({
|
|
197
|
-
id,
|
|
198
|
-
db: 'bookmarkGroups',
|
|
199
|
-
update: rest,
|
|
200
|
-
upsert: false
|
|
201
|
-
})
|
|
202
|
-
}
|
|
203
|
-
if (toGroup) {
|
|
204
|
-
const { id, ...rest } = toGroup
|
|
205
|
-
updates.push({
|
|
206
|
-
id,
|
|
207
|
-
db: 'bookmarkGroups',
|
|
208
|
-
update: rest,
|
|
209
|
-
upsert: false
|
|
210
|
-
})
|
|
211
|
-
} else if (from) {
|
|
212
|
-
const { id, ...rest } = from
|
|
213
|
-
updates.push({
|
|
214
|
-
id,
|
|
215
|
-
db: 'bookmarkGroups',
|
|
216
|
-
update: rest,
|
|
217
|
-
upsert: false
|
|
218
|
-
})
|
|
219
|
-
}
|
|
220
|
-
props.store.setBookmarkGroups(bookmarkGroups)
|
|
221
|
-
props.store.batchDbUpdate(updates)
|
|
222
|
-
}
|
|
191
|
+
})
|
|
@@ -183,6 +183,9 @@ export default class SettingCommon extends Component {
|
|
|
183
183
|
if (name === 'useSystemTitleBar') {
|
|
184
184
|
message.info(e('useSystemTitleBarTip'), 5)
|
|
185
185
|
}
|
|
186
|
+
if (name === 'disableConnectionHistory' && value) {
|
|
187
|
+
window.store.history = []
|
|
188
|
+
}
|
|
186
189
|
this.saveConfig({
|
|
187
190
|
[name]: value
|
|
188
191
|
})
|
|
@@ -658,7 +661,7 @@ export default class SettingCommon extends Component {
|
|
|
658
661
|
'showHiddenFilesOnSftpStart',
|
|
659
662
|
'screenReaderMode',
|
|
660
663
|
'initDefaultTabOnStart',
|
|
661
|
-
'
|
|
664
|
+
'disableConnectionHistory',
|
|
662
665
|
'disableTransferHistory',
|
|
663
666
|
'checkUpdateOnStart',
|
|
664
667
|
'useSystemTitleBar',
|
|
@@ -15,6 +15,7 @@ import TabQuickCommands from './tab-quick-commands'
|
|
|
15
15
|
import TabSettings from './tab-settings'
|
|
16
16
|
import TabThemes from './tab-themes'
|
|
17
17
|
import TabProfiles from './tab-profiles'
|
|
18
|
+
import deepCopy from 'json-deep-copy'
|
|
18
19
|
|
|
19
20
|
const e = window.translate
|
|
20
21
|
|
|
@@ -38,6 +39,8 @@ export default auto(function SettingModalWrap (props) {
|
|
|
38
39
|
shouldConfirmDel: tabsShouldConfirmDel.includes(settingTab),
|
|
39
40
|
list: settingSidebarList
|
|
40
41
|
}
|
|
42
|
+
const bookmarks = deepCopy(store.bookmarks)
|
|
43
|
+
const bookmarkGroups = deepCopy(store.bookmarkGroups)
|
|
41
44
|
const formProps = {
|
|
42
45
|
store,
|
|
43
46
|
formData: settingItem,
|
|
@@ -47,19 +50,18 @@ export default auto(function SettingModalWrap (props) {
|
|
|
47
50
|
'currentBookmarkGroupId',
|
|
48
51
|
'config'
|
|
49
52
|
]),
|
|
50
|
-
bookmarkGroups
|
|
51
|
-
bookmarks
|
|
53
|
+
bookmarkGroups,
|
|
54
|
+
bookmarks,
|
|
52
55
|
serials: store.serials,
|
|
53
56
|
loaddingSerials: store.loaddingSerials
|
|
54
57
|
}
|
|
55
58
|
const treeProps = {
|
|
56
59
|
...props0,
|
|
57
60
|
bookmarkSelectMode,
|
|
58
|
-
bookmarkGroups
|
|
59
|
-
bookmarks
|
|
61
|
+
bookmarkGroups,
|
|
62
|
+
bookmarks,
|
|
60
63
|
...pick(store, [
|
|
61
64
|
'currentBookmarkGroupId',
|
|
62
|
-
'autofocustrigger',
|
|
63
65
|
'config',
|
|
64
66
|
'checkedKeys',
|
|
65
67
|
'expandedKeys',
|
|
@@ -39,24 +39,10 @@ export default class AddrBookmarkItem extends Component {
|
|
|
39
39
|
const { store } = window
|
|
40
40
|
const [host, idDragged] = e.dataTransfer.getData('idDragged').split('#')
|
|
41
41
|
const idDrop = e.target.getAttribute('data-id').split('#')[1]
|
|
42
|
-
const addressBookmarks = host
|
|
43
|
-
? store.addressBookmarks
|
|
44
|
-
: store.addressBookmarksLocal
|
|
45
42
|
const dataName = host
|
|
46
43
|
? 'addressBookmarks'
|
|
47
44
|
: 'addressBookmarksLocal'
|
|
48
|
-
|
|
49
|
-
({ id }) => id === idDragged
|
|
50
|
-
)
|
|
51
|
-
const targetIndex = addressBookmarks.findIndex(
|
|
52
|
-
({ id }) => id === idDrop
|
|
53
|
-
)
|
|
54
|
-
if (idDraggedIndex < targetIndex) {
|
|
55
|
-
addressBookmarks.splice(targetIndex, 0, addressBookmarks.splice(idDraggedIndex, 1)[0])
|
|
56
|
-
} else {
|
|
57
|
-
addressBookmarks.splice(targetIndex + 1, 0, addressBookmarks.splice(idDraggedIndex, 1)[0])
|
|
58
|
-
}
|
|
59
|
-
store.setItems(dataName, addressBookmarks)
|
|
45
|
+
store.adjustOrder(dataName, idDragged, idDrop)
|
|
60
46
|
}
|
|
61
47
|
|
|
62
48
|
render () {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
fileActions
|
|
13
13
|
} from '../../common/constants'
|
|
14
14
|
import deepCopy from 'json-deep-copy'
|
|
15
|
-
import
|
|
15
|
+
import { refsStatic } from '../common/ref'
|
|
16
16
|
|
|
17
17
|
const e = window.translate
|
|
18
18
|
|
|
@@ -34,7 +34,7 @@ export default function ConfirmModalStore (props) {
|
|
|
34
34
|
id,
|
|
35
35
|
transferGroupId
|
|
36
36
|
} = transferToConfirm
|
|
37
|
-
|
|
37
|
+
refsStatic.get('transfer-conflict')?.onDecision({
|
|
38
38
|
transferGroupId,
|
|
39
39
|
fileId,
|
|
40
40
|
id,
|
|
@@ -8,47 +8,58 @@ import resolve from '../../common/resolve'
|
|
|
8
8
|
import time from '../../common/time'
|
|
9
9
|
import { update } from 'lodash-es'
|
|
10
10
|
import { mode2permission, permission2mode } from '../../common/mode2permission'
|
|
11
|
-
import { commonActions } from '../../common/constants'
|
|
12
11
|
import renderPermission from './permission-render'
|
|
13
|
-
import postMessage from '../../common/post-msg'
|
|
14
12
|
import FileIcon from './file-icon'
|
|
13
|
+
import fs from '../../common/fs'
|
|
14
|
+
import { filesize } from 'filesize'
|
|
15
|
+
import { runCmd } from '../terminal/terminal-apis'
|
|
16
|
+
import {
|
|
17
|
+
isWin,
|
|
18
|
+
typeMap
|
|
19
|
+
} from '../../common/constants'
|
|
20
|
+
import { refsStatic, refs } from '../common/ref'
|
|
15
21
|
|
|
16
22
|
const e = window.translate
|
|
17
23
|
const formatTime = time
|
|
18
24
|
|
|
19
25
|
export default class FileMode extends React.PureComponent {
|
|
20
26
|
state = {
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
fileId: '',
|
|
28
|
+
loading: false,
|
|
29
|
+
tab: null,
|
|
30
|
+
pid: '',
|
|
31
|
+
sessionId: '',
|
|
32
|
+
size: 0,
|
|
33
|
+
file: {},
|
|
34
|
+
editPermission: false
|
|
23
35
|
}
|
|
24
36
|
|
|
25
37
|
componentDidMount () {
|
|
26
|
-
|
|
38
|
+
refsStatic.add('file-modal', this)
|
|
27
39
|
}
|
|
28
40
|
|
|
29
41
|
setStateProxy = (state, cb) => {
|
|
30
42
|
if (state && typeof state.file !== 'undefined') {
|
|
31
|
-
|
|
32
|
-
action: commonActions.updateStore,
|
|
33
|
-
value: !!state.file.id,
|
|
34
|
-
prop: 'showFileModal'
|
|
35
|
-
})
|
|
43
|
+
window.store.showFileModal = !!state.file.id
|
|
36
44
|
}
|
|
37
45
|
return this.setState(state, cb)
|
|
38
46
|
}
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
showFileInfoModal (data) {
|
|
49
|
+
this.setStateProxy({
|
|
50
|
+
...data,
|
|
51
|
+
size: 0,
|
|
52
|
+
editPermission: false
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
showFileModeModal = (data, file, fileId) => {
|
|
57
|
+
this.setStateProxy({
|
|
58
|
+
...data,
|
|
59
|
+
file: this.addPermission(file),
|
|
60
|
+
fileId,
|
|
61
|
+
editPermission: true
|
|
62
|
+
})
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
addPermission = file => {
|
|
@@ -63,6 +74,9 @@ export default class FileMode extends React.PureComponent {
|
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
onChangePermission = (name, permName) => {
|
|
77
|
+
if (!this.state.editPermission) {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
66
80
|
const { file } = this.state
|
|
67
81
|
const perms = mode2permission(file.mode)
|
|
68
82
|
const i = perms.findIndex(p => p.name === name)
|
|
@@ -83,24 +97,65 @@ export default class FileMode extends React.PureComponent {
|
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
onClose = () => {
|
|
86
|
-
postMessage({
|
|
87
|
-
action: commonActions.submitFileModeClose
|
|
88
|
-
})
|
|
89
100
|
this.setStateProxy({
|
|
90
101
|
file: {},
|
|
91
|
-
|
|
102
|
+
visible: false
|
|
92
103
|
})
|
|
93
104
|
}
|
|
94
105
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
getSize = (str = '') => {
|
|
107
|
+
if (isWin) {
|
|
108
|
+
const s = (str.stdout || '').split('\n').find(s => s.trim().startsWith('Sum'))
|
|
109
|
+
return s ? filesize(parseInt((s.split(':')[1]).trim(), 10)) : 0
|
|
110
|
+
} else {
|
|
111
|
+
return str.split(/\s+/)[0]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
calcLocal = async (folder) => {
|
|
116
|
+
const cmd = isWin
|
|
117
|
+
? `Get-ChildItem -Recurse '${folder}' | Measure-Object -Property Length -Sum`
|
|
118
|
+
: `du -sh '${folder}'`
|
|
119
|
+
const func = isWin ? 'runWinCmd' : 'run'
|
|
120
|
+
const res = await fs[func](cmd).catch(window.store.onError)
|
|
121
|
+
return this.getSize(res)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
calcRemote = async (folder) => {
|
|
125
|
+
const cmd = `du -sh '${folder}'`
|
|
126
|
+
const r = await runCmd(
|
|
127
|
+
this.state.pid,
|
|
128
|
+
this.state.sessionId,
|
|
129
|
+
cmd
|
|
130
|
+
).catch(window.store.onError)
|
|
131
|
+
return r ? r.split(/\s+/)[0] : 0
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
handleCalc = async () => {
|
|
135
|
+
const { file } = this.state
|
|
136
|
+
const { type, path, name } = file
|
|
137
|
+
this.setStateProxy({
|
|
138
|
+
loading: true
|
|
99
139
|
})
|
|
140
|
+
const fp = resolve(path, name)
|
|
141
|
+
const size = type === typeMap.local
|
|
142
|
+
? await this.calcLocal(fp)
|
|
143
|
+
: await this.calcRemote(fp)
|
|
144
|
+
this.setState({
|
|
145
|
+
loading: false,
|
|
146
|
+
size
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
handleSubmit = () => {
|
|
151
|
+
refs.get(this.state.fileId)?.changeFileMode(this.state.file)
|
|
100
152
|
this.onClose()
|
|
101
153
|
}
|
|
102
154
|
|
|
103
155
|
renderFooter () {
|
|
156
|
+
if (!this.state.editPermission) {
|
|
157
|
+
return null
|
|
158
|
+
}
|
|
104
159
|
return (
|
|
105
160
|
<Button
|
|
106
161
|
type='primary'
|
|
@@ -111,20 +166,63 @@ export default class FileMode extends React.PureComponent {
|
|
|
111
166
|
)
|
|
112
167
|
}
|
|
113
168
|
|
|
169
|
+
getFileSize = () => {
|
|
170
|
+
const { isDirectory, size } = this.state.file
|
|
171
|
+
if (isDirectory) {
|
|
172
|
+
return this.state.size || 0
|
|
173
|
+
}
|
|
174
|
+
return size
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
renderSizeRow = () => {
|
|
178
|
+
const size = this.getFileSize()
|
|
179
|
+
if (this.state.editPermission) {
|
|
180
|
+
return (
|
|
181
|
+
<>
|
|
182
|
+
<p className='bold'>{e('size')}:</p>
|
|
183
|
+
<p className='pd1b'>{size}</p>
|
|
184
|
+
</>
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
return (
|
|
188
|
+
<>
|
|
189
|
+
<p className='bold'>{e('size')}:</p>
|
|
190
|
+
<p className='pd1b'>{this.getFileSize()}{this.renderCalc()}</p>
|
|
191
|
+
</>
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
renderCalc () {
|
|
196
|
+
const { isDirectory } = this.state.file
|
|
197
|
+
if (isDirectory) {
|
|
198
|
+
const { loading } = this.state
|
|
199
|
+
return (
|
|
200
|
+
<Button
|
|
201
|
+
onClick={this.handleCalc}
|
|
202
|
+
loading={loading}
|
|
203
|
+
disabled={loading}
|
|
204
|
+
className='mg1l'
|
|
205
|
+
>
|
|
206
|
+
{e('calculate')}
|
|
207
|
+
</Button>
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
114
212
|
render () {
|
|
115
213
|
const {
|
|
116
214
|
visible,
|
|
117
215
|
tab,
|
|
118
216
|
uidTree,
|
|
119
|
-
gidTree
|
|
120
|
-
|
|
217
|
+
gidTree,
|
|
218
|
+
file,
|
|
219
|
+
editPermission
|
|
220
|
+
} = this.state
|
|
121
221
|
if (!visible) {
|
|
122
222
|
return null
|
|
123
223
|
}
|
|
124
|
-
const { file } = this.state
|
|
125
224
|
const {
|
|
126
225
|
name,
|
|
127
|
-
size,
|
|
128
226
|
accessTime,
|
|
129
227
|
modifyTime,
|
|
130
228
|
isDirectory,
|
|
@@ -141,10 +239,13 @@ export default class FileMode extends React.PureComponent {
|
|
|
141
239
|
username
|
|
142
240
|
} = tab
|
|
143
241
|
const iconType = isDirectory ? 'folder' : 'file'
|
|
242
|
+
const title = editPermission
|
|
243
|
+
? `${e('edit')} ` + e(iconType) + ` ${e('permission')}`
|
|
244
|
+
: e(iconType) + ` ${e('attributes')}`
|
|
144
245
|
const ps = {
|
|
145
246
|
open: visible,
|
|
146
247
|
width: 500,
|
|
147
|
-
title
|
|
248
|
+
title,
|
|
148
249
|
footer: this.renderFooter(),
|
|
149
250
|
onCancel: this.onClose
|
|
150
251
|
}
|
|
@@ -193,8 +294,7 @@ export default class FileMode extends React.PureComponent {
|
|
|
193
294
|
<p className='pd1b'>{uidTree['' + owner]}</p>
|
|
194
295
|
<p className='bold'>{e('group')}</p>
|
|
195
296
|
<p className='pd1b'>{gidTree['' + group]}</p>
|
|
196
|
-
|
|
197
|
-
<p className='pd1b'>{size}</p>
|
|
297
|
+
{this.renderSizeRow()}
|
|
198
298
|
<p className='bold'>{e('accessTime')}:</p>
|
|
199
299
|
<p className='pd1b'>{formatTime(accessTime)}</p>
|
|
200
300
|
<p className='bold'>{e('modifyTime')}:</p>
|