@electerm/electerm-react 2.3.136 → 2.3.166
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 +4 -2
- package/client/common/db.js +2 -1
- package/client/common/init-setting-item.js +7 -0
- 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/common/modal.jsx +89 -0
- package/client/components/common/modal.styl +77 -0
- package/client/components/common/notification-with-details.jsx +34 -0
- package/client/components/file-transfer/conflict-resolve.jsx +2 -1
- package/client/components/file-transfer/transfer-speed-format.js +6 -0
- package/client/components/file-transfer/transfer.jsx +5 -2
- package/client/components/file-transfer/transports-action-store.jsx +14 -1
- package/client/components/main/main.jsx +2 -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 +5 -4
- 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/setting-panel/start-session-select.jsx +146 -21
- package/client/components/setting-panel/text-bg-modal.jsx +15 -4
- package/client/components/sftp/file-info-modal.jsx +2 -1
- package/client/components/sftp/file-item.jsx +2 -0
- 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/sidebar/info-modal.jsx +53 -34
- package/client/components/sidebar/info.styl +0 -7
- package/client/components/tabs/index.jsx +6 -58
- package/client/components/tabs/layout-menu.jsx +75 -0
- package/client/components/tabs/layout-select.jsx +60 -0
- package/client/components/tabs/tabs.styl +64 -0
- package/client/components/tabs/workspace-save-modal.jsx +117 -0
- package/client/components/tabs/workspace-select.jsx +79 -0
- package/client/components/terminal/attach-addon-custom.js +7 -1
- package/client/components/terminal/terminal-interactive.jsx +2 -1
- package/client/components/terminal/terminal.jsx +0 -1
- package/client/components/text-editor/text-editor.jsx +2 -1
- package/client/components/tree-list/move-item-modal.jsx +115 -30
- package/client/components/tree-list/tree-list.jsx +1 -1
- package/client/components/tree-list/tree-list.styl +6 -1
- package/client/components/vnc/vnc-session.jsx +2 -2
- package/client/components/widgets/widget-control.jsx +4 -5
- package/client/components/widgets/widget-form.jsx +3 -8
- package/client/components/widgets/widget-instance.jsx +44 -9
- package/client/components/widgets/widget-notification-with-details.jsx +34 -0
- package/client/css/basic.styl +3 -1
- package/client/store/init-state.js +4 -0
- package/client/store/load-data.js +15 -6
- package/client/store/store.js +2 -0
- package/client/store/workspace.js +108 -0
- package/package.json +1 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { Popconfirm } from 'antd'
|
|
2
|
-
import { CloseOutlined } from '@ant-design/icons'
|
|
1
|
+
import { Popconfirm, Popover } from 'antd'
|
|
2
|
+
import { CloseOutlined, CopyOutlined } from '@ant-design/icons'
|
|
3
|
+
import { copy } from '../../common/clipboard'
|
|
3
4
|
|
|
4
5
|
const e = window.translate
|
|
5
6
|
|
|
6
7
|
export default function WidgetInstance ({ item }) {
|
|
7
|
-
const { id, title } = item
|
|
8
|
+
const { id, title, serverInfo } = item
|
|
8
9
|
const cls = 'item-list-unit'
|
|
9
10
|
const delProps = {
|
|
10
11
|
title: e('del'),
|
|
@@ -25,17 +26,51 @@ export default function WidgetInstance ({ item }) {
|
|
|
25
26
|
cancelText: e('cancel'),
|
|
26
27
|
placement: 'top'
|
|
27
28
|
}
|
|
29
|
+
const handleCopy = () => {
|
|
30
|
+
if (serverInfo && serverInfo.url) {
|
|
31
|
+
copy(serverInfo.url)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const popoverContent = serverInfo
|
|
35
|
+
? (
|
|
36
|
+
<div>
|
|
37
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
38
|
+
<span>URL: {serverInfo.url}</span>
|
|
39
|
+
<CopyOutlined
|
|
40
|
+
className='pointer mg1l'
|
|
41
|
+
onClick={handleCopy}
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
<div>Path: {serverInfo.path}</div>
|
|
45
|
+
</div>
|
|
46
|
+
)
|
|
47
|
+
: null
|
|
48
|
+
const titleDiv = (
|
|
49
|
+
<div
|
|
50
|
+
title={title}
|
|
51
|
+
className='elli pd1y pd2x list-item-title'
|
|
52
|
+
>
|
|
53
|
+
{title}
|
|
54
|
+
</div>
|
|
55
|
+
)
|
|
28
56
|
return (
|
|
29
57
|
<div
|
|
30
58
|
key={id}
|
|
31
59
|
className={cls}
|
|
32
60
|
>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
61
|
+
{
|
|
62
|
+
serverInfo
|
|
63
|
+
? (
|
|
64
|
+
<Popover
|
|
65
|
+
content={popoverContent}
|
|
66
|
+
trigger='hover'
|
|
67
|
+
placement='top'
|
|
68
|
+
>
|
|
69
|
+
{titleDiv}
|
|
70
|
+
</Popover>
|
|
71
|
+
)
|
|
72
|
+
: titleDiv
|
|
73
|
+
}
|
|
39
74
|
<Popconfirm
|
|
40
75
|
{...popProps}
|
|
41
76
|
>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { notification } from 'antd'
|
|
2
|
+
import { CopyOutlined } from '@ant-design/icons'
|
|
3
|
+
import { copy } from '../../common/clipboard'
|
|
4
|
+
|
|
5
|
+
export function showMsg (message, type = 'success', serverInfo = null, duration = 10, description = '') {
|
|
6
|
+
const handleCopy = () => {
|
|
7
|
+
if (serverInfo && serverInfo.url) {
|
|
8
|
+
copy(serverInfo.url)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let desc = description
|
|
13
|
+
if (serverInfo) {
|
|
14
|
+
desc = (
|
|
15
|
+
<div>
|
|
16
|
+
{description && <div>{description}</div>}
|
|
17
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
18
|
+
<span>URL: {serverInfo.url}</span>
|
|
19
|
+
<CopyOutlined
|
|
20
|
+
className='pointer mg1l'
|
|
21
|
+
onClick={handleCopy}
|
|
22
|
+
/>
|
|
23
|
+
</div>
|
|
24
|
+
<div>Path: {serverInfo.path}</div>
|
|
25
|
+
</div>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
notification[type]({
|
|
30
|
+
message,
|
|
31
|
+
description: desc,
|
|
32
|
+
duration
|
|
33
|
+
})
|
|
34
|
+
}
|
package/client/css/basic.styl
CHANGED
|
@@ -75,6 +75,10 @@ export default () => {
|
|
|
75
75
|
resolutions: ls.getItemJSON(resolutionsLsKey, []),
|
|
76
76
|
terminalCommandHistory: new Set(ls.getItemJSON(cmdHistoryKey, [])),
|
|
77
77
|
|
|
78
|
+
// workspaces
|
|
79
|
+
workspaces: [],
|
|
80
|
+
workspaceSaveModalVisible: false,
|
|
81
|
+
|
|
78
82
|
// init session control
|
|
79
83
|
selectedSessions: [],
|
|
80
84
|
sessionModalVisible: false,
|
|
@@ -115,13 +115,22 @@ export async function addTabFromCommandLine (store, opts) {
|
|
|
115
115
|
export default (Store) => {
|
|
116
116
|
Store.prototype.openInitSessions = function () {
|
|
117
117
|
const { store } = window
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
const onStartSessions = store.config.onStartSessions
|
|
119
|
+
|
|
120
|
+
// If onStartSessions is a string, it's a workspace ID
|
|
121
|
+
if (typeof onStartSessions === 'string' && onStartSessions) {
|
|
122
|
+
store.loadWorkspace(onStartSessions)
|
|
123
|
+
} else {
|
|
124
|
+
// Otherwise, it's an array of bookmark IDs
|
|
125
|
+
const arr = Array.isArray(onStartSessions) ? onStartSessions : []
|
|
126
|
+
for (const s of arr) {
|
|
127
|
+
store.onSelectBookmark(s)
|
|
128
|
+
}
|
|
129
|
+
if (!arr.length && store.config.initDefaultTabOnStart) {
|
|
130
|
+
store.initFirstTab()
|
|
131
|
+
}
|
|
124
132
|
}
|
|
133
|
+
|
|
125
134
|
store.confirmLoad()
|
|
126
135
|
const { initTime, loadTime } = window.pre.runSync('getLoadTime')
|
|
127
136
|
if (loadTime) {
|
package/client/store/store.js
CHANGED
|
@@ -25,6 +25,7 @@ import batchInputHistory from './batch-input-history'
|
|
|
25
25
|
import transferExtend from './transfer-list'
|
|
26
26
|
import addressBookmarkExtend from './address-bookmark'
|
|
27
27
|
import widgetsExtend from './widgets'
|
|
28
|
+
import workspaceExtend from './workspace'
|
|
28
29
|
import isColorDark from '../common/is-color-dark'
|
|
29
30
|
import { getReverseColor } from '../common/reverse-color'
|
|
30
31
|
import { uniq } from 'lodash-es'
|
|
@@ -297,5 +298,6 @@ batchInputHistory(Store)
|
|
|
297
298
|
transferExtend(Store)
|
|
298
299
|
addressBookmarkExtend(Store)
|
|
299
300
|
widgetsExtend(Store)
|
|
301
|
+
workspaceExtend(Store)
|
|
300
302
|
|
|
301
303
|
export const StateStore = Store
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workspace related functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
settingMap
|
|
7
|
+
} from '../common/constants'
|
|
8
|
+
import getInitItem from '../common/init-setting-item'
|
|
9
|
+
import generate from '../common/uid'
|
|
10
|
+
|
|
11
|
+
export default Store => {
|
|
12
|
+
/**
|
|
13
|
+
* Get current workspace state (layout + tabs for each batch)
|
|
14
|
+
*/
|
|
15
|
+
Store.prototype.getCurrentWorkspaceState = function () {
|
|
16
|
+
const { store } = window
|
|
17
|
+
const { layout, tabs } = store
|
|
18
|
+
// Group tabs by batch and get bookmark srcIds
|
|
19
|
+
const tabsByBatch = {}
|
|
20
|
+
for (const tab of tabs) {
|
|
21
|
+
const batch = tab.batch || 0
|
|
22
|
+
if (!tabsByBatch[batch]) {
|
|
23
|
+
tabsByBatch[batch] = []
|
|
24
|
+
}
|
|
25
|
+
// Store srcId (bookmark id) if available, otherwise store basic connection info
|
|
26
|
+
if (tab.srcId) {
|
|
27
|
+
tabsByBatch[batch].push({
|
|
28
|
+
srcId: tab.srcId
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
layout,
|
|
34
|
+
tabsByBatch
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Save current workspace
|
|
40
|
+
*/
|
|
41
|
+
Store.prototype.saveWorkspace = function (name, id = null) {
|
|
42
|
+
const { store } = window
|
|
43
|
+
const state = store.getCurrentWorkspaceState()
|
|
44
|
+
const workspace = {
|
|
45
|
+
id: id || generate(),
|
|
46
|
+
name,
|
|
47
|
+
...state,
|
|
48
|
+
createdAt: Date.now(),
|
|
49
|
+
updatedAt: Date.now()
|
|
50
|
+
}
|
|
51
|
+
if (id) {
|
|
52
|
+
// Update existing
|
|
53
|
+
store.editItem(id, workspace, settingMap.workspaces)
|
|
54
|
+
} else {
|
|
55
|
+
// Add new
|
|
56
|
+
store.addItem(workspace, settingMap.workspaces)
|
|
57
|
+
}
|
|
58
|
+
return workspace
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Load a workspace - set layout and open tabs
|
|
63
|
+
*/
|
|
64
|
+
Store.prototype.loadWorkspace = function (workspaceId) {
|
|
65
|
+
const { store } = window
|
|
66
|
+
const workspace = store.workspaces.find(w => w.id === workspaceId)
|
|
67
|
+
if (!workspace) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
const { layout, tabsByBatch } = workspace
|
|
71
|
+
|
|
72
|
+
// Close all existing tabs first
|
|
73
|
+
store.removeTabs(() => true)
|
|
74
|
+
|
|
75
|
+
// Set layout
|
|
76
|
+
store.setLayout(layout)
|
|
77
|
+
// Open tabs for each batch
|
|
78
|
+
for (const [batchStr, tabInfos] of Object.entries(tabsByBatch)) {
|
|
79
|
+
const batch = parseInt(batchStr, 10)
|
|
80
|
+
for (const tabInfo of tabInfos) {
|
|
81
|
+
if (tabInfo.srcId) {
|
|
82
|
+
// Open from bookmark
|
|
83
|
+
window.openTabBatch = batch
|
|
84
|
+
store.onSelectBookmark(tabInfo.srcId)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Delete a workspace
|
|
92
|
+
*/
|
|
93
|
+
Store.prototype.deleteWorkspace = function (id) {
|
|
94
|
+
window.store.delItem({ id }, settingMap.workspaces)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Open workspace settings
|
|
99
|
+
*/
|
|
100
|
+
Store.prototype.openWorkspaceSettings = function () {
|
|
101
|
+
const { store } = window
|
|
102
|
+
store.storeAssign({
|
|
103
|
+
settingTab: settingMap.workspaces
|
|
104
|
+
})
|
|
105
|
+
store.setSettingItem(getInitItem([], settingMap.workspaces))
|
|
106
|
+
store.openSettingModal()
|
|
107
|
+
}
|
|
108
|
+
}
|