@electerm/electerm-react 5.3.5 → 5.3.15
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.
|
@@ -29,7 +29,9 @@ import {
|
|
|
29
29
|
PlayCircleFilled,
|
|
30
30
|
StopOutlined,
|
|
31
31
|
DownloadOutlined,
|
|
32
|
-
SwapOutlined
|
|
32
|
+
SwapOutlined,
|
|
33
|
+
PushpinOutlined,
|
|
34
|
+
PushpinFilled
|
|
33
35
|
} from '@ant-design/icons'
|
|
34
36
|
import IconHolder from './icon-holder'
|
|
35
37
|
|
|
@@ -62,5 +64,7 @@ export default {
|
|
|
62
64
|
PlayCircleFilled,
|
|
63
65
|
StopOutlined,
|
|
64
66
|
DownloadOutlined,
|
|
65
|
-
SwapOutlined
|
|
67
|
+
SwapOutlined,
|
|
68
|
+
PushpinOutlined,
|
|
69
|
+
PushpinFilled
|
|
66
70
|
}
|
|
@@ -122,11 +122,23 @@ export default class Tabs extends Component {
|
|
|
122
122
|
)
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
// desktop tabs bar renders pinned tabs first: stable partition that keeps
|
|
126
|
+
// the original relative order inside the pinned and unpinned groups.
|
|
127
|
+
// store.tabs order itself is untouched by pinning.
|
|
128
|
+
getSortedTabs = () => {
|
|
129
|
+
const { tabs = [] } = this.props
|
|
130
|
+
return [
|
|
131
|
+
...tabs.filter(t => t.isPinned),
|
|
132
|
+
...tabs.filter(t => !t.isPinned)
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
|
|
125
136
|
adjustScroll = () => {
|
|
126
137
|
if (this.props.isMobile || !this.domRef.current) {
|
|
127
138
|
return
|
|
128
139
|
}
|
|
129
|
-
const {
|
|
140
|
+
const { currentBatchTabId, batch } = this.props
|
|
141
|
+
const tabs = this.getSortedTabs()
|
|
130
142
|
const index = tabs.findIndex(t => t.id === currentBatchTabId)
|
|
131
143
|
const tabsDomWith = Array.from(
|
|
132
144
|
document.querySelectorAll(`.v${batch + 1} .tab`)
|
|
@@ -209,7 +221,7 @@ export default class Tabs extends Component {
|
|
|
209
221
|
}
|
|
210
222
|
|
|
211
223
|
renderExtra () {
|
|
212
|
-
const items = this.
|
|
224
|
+
const items = this.getSortedTabs().map((t, i) => {
|
|
213
225
|
return {
|
|
214
226
|
key: i + '##' + t.id,
|
|
215
227
|
label: (
|
|
@@ -261,7 +273,8 @@ export default class Tabs extends Component {
|
|
|
261
273
|
}
|
|
262
274
|
|
|
263
275
|
renderContentInner () {
|
|
264
|
-
const {
|
|
276
|
+
const { width, config } = this.props
|
|
277
|
+
const tabs = this.getSortedTabs()
|
|
265
278
|
const len = tabs.length
|
|
266
279
|
const tabsWidthAll = tabMargin * len + 10 + this.tabsWidth()
|
|
267
280
|
const { overflow } = this.state
|
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
CloseOutlined,
|
|
10
10
|
Loading3QuartersOutlined,
|
|
11
11
|
BorderlessTableOutlined,
|
|
12
|
-
LockOutlined
|
|
12
|
+
LockOutlined,
|
|
13
|
+
PushpinFilled
|
|
13
14
|
} from '@ant-design/icons'
|
|
14
15
|
import {
|
|
15
16
|
Tooltip,
|
|
@@ -239,8 +240,15 @@ class Tab extends Component {
|
|
|
239
240
|
}
|
|
240
241
|
}
|
|
241
242
|
|
|
242
|
-
handleReloadTab = async () => {
|
|
243
|
-
|
|
243
|
+
handleReloadTab = async (e) => {
|
|
244
|
+
// stop propagation so the parent tab-title click doesn't re-activate
|
|
245
|
+
// this tab by its now-stale (removed) id after reloadTab replaces it
|
|
246
|
+
e && e.stopPropagation()
|
|
247
|
+
const { tab, batch } = this.props
|
|
248
|
+
const newTab = window.store.reloadTab(tab.id)
|
|
249
|
+
if (newTab) {
|
|
250
|
+
window.store.clickTab(newTab.id, batch)
|
|
251
|
+
}
|
|
244
252
|
}
|
|
245
253
|
|
|
246
254
|
handleReloadAll = () => {
|
|
@@ -309,8 +317,13 @@ class Tab extends Component {
|
|
|
309
317
|
window.store.closeTabsRight(this.props.tab.id)
|
|
310
318
|
}
|
|
311
319
|
|
|
320
|
+
togglePin = () => {
|
|
321
|
+
const { tab } = this.props
|
|
322
|
+
window.store.pinTab(tab.id, !tab.isPinned)
|
|
323
|
+
}
|
|
324
|
+
|
|
312
325
|
renderContext = () => {
|
|
313
|
-
const { tabs, tabIndex } = this.props
|
|
326
|
+
const { tabs, tabIndex, tab } = this.props
|
|
314
327
|
const len = tabs.length
|
|
315
328
|
const index = tabIndex
|
|
316
329
|
const noRight = index >= len - 1
|
|
@@ -359,6 +372,13 @@ class Tab extends Component {
|
|
|
359
372
|
icon: <iconsMap.EditOutlined />,
|
|
360
373
|
label: e('rename')
|
|
361
374
|
},
|
|
375
|
+
!window.store.isMobile && {
|
|
376
|
+
key: 'togglePin',
|
|
377
|
+
icon: tab.isPinned
|
|
378
|
+
? <iconsMap.PushpinFilled />
|
|
379
|
+
: <iconsMap.PushpinOutlined />,
|
|
380
|
+
label: tab.isPinned ? e('unpin') : e('pin')
|
|
381
|
+
},
|
|
362
382
|
{
|
|
363
383
|
key: 'handleReloadTab',
|
|
364
384
|
icon: <iconsMap.ReloadOutlined />,
|
|
@@ -542,6 +562,7 @@ class Tab extends Component {
|
|
|
542
562
|
}
|
|
543
563
|
<span className='tab-title'>
|
|
544
564
|
<span className='iblock mg1r tab-count' style={styleTag}>{tabCount}</span>
|
|
565
|
+
{tab.isPinned && <PushpinFilled className='tab-pin' />}
|
|
545
566
|
<span className='mg1r'>{title}</span>
|
|
546
567
|
</span>
|
|
547
568
|
</div>
|
|
@@ -29,7 +29,6 @@ import {
|
|
|
29
29
|
import * as ls from '../common/safe-local-storage'
|
|
30
30
|
import { exclude } from 'manate'
|
|
31
31
|
import initSettingItem from '../common/init-setting-item'
|
|
32
|
-
import { getRandomDefaultColor } from '../common/rand-hex-color'
|
|
33
32
|
|
|
34
33
|
const e = window.translate
|
|
35
34
|
|
|
@@ -39,7 +38,7 @@ function getDefaultBookmarkGroups (bookmarks) {
|
|
|
39
38
|
title: e(defaultBookmarkGroupId),
|
|
40
39
|
id: defaultBookmarkGroupId,
|
|
41
40
|
bookmarkIds: bookmarks.map(d => d.id),
|
|
42
|
-
color:
|
|
41
|
+
color: '#0088cc'
|
|
43
42
|
})
|
|
44
43
|
]
|
|
45
44
|
}
|
package/client/store/tab.js
CHANGED
|
@@ -127,6 +127,8 @@ export default Store => {
|
|
|
127
127
|
if (store[batchProp] === tabId) {
|
|
128
128
|
store[batchProp] = newTab.id
|
|
129
129
|
}
|
|
130
|
+
|
|
131
|
+
return newTab
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
Store.prototype.reloadAllTabs = function () {
|
|
@@ -168,6 +170,17 @@ export default Store => {
|
|
|
168
170
|
store[`activeTabId${sourceTab.batch}`] = duplicatedTab.id
|
|
169
171
|
}
|
|
170
172
|
|
|
173
|
+
// only toggles the flag: the tabs bar renders pinned tabs first,
|
|
174
|
+
// store.tabs order itself is never changed by pinning
|
|
175
|
+
Store.prototype.pinTab = function (tabId, isPinned = true) {
|
|
176
|
+
const { store } = window
|
|
177
|
+
const tab = store.tabs.find(t => t.id === tabId)
|
|
178
|
+
if (!tab || Boolean(tab.isPinned) === isPinned) {
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
tab.isPinned = isPinned
|
|
182
|
+
}
|
|
183
|
+
|
|
171
184
|
Store.prototype.closeOtherTabs = function (id) {
|
|
172
185
|
const { store } = window
|
|
173
186
|
const { tabs } = store
|
|
@@ -534,7 +547,8 @@ export default Store => {
|
|
|
534
547
|
'sshSftpSplitView',
|
|
535
548
|
'sshTunnelResults',
|
|
536
549
|
'displayRaw',
|
|
537
|
-
'autoReConnect'
|
|
550
|
+
'autoReConnect',
|
|
551
|
+
'isPinned'
|
|
538
552
|
]
|
|
539
553
|
const { history } = store
|
|
540
554
|
const index = history.filter(d => d.id && d.tab).findIndex(d => {
|