@electerm/electerm-react 1.34.30

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.
Files changed (273) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -0
  3. package/client/common/auto-complete-data-mapper.js +6 -0
  4. package/client/common/byte-format.js +14 -0
  5. package/client/common/class.js +52 -0
  6. package/client/common/clipboard.js +49 -0
  7. package/client/common/constants.js +308 -0
  8. package/client/common/create-lang-edit-link.js +7 -0
  9. package/client/common/create-title.js +29 -0
  10. package/client/common/db-fix.js +24 -0
  11. package/client/common/db.js +155 -0
  12. package/client/common/download-mirrors.js +10 -0
  13. package/client/common/download.js +16 -0
  14. package/client/common/error-handler.jsx +27 -0
  15. package/client/common/fetch-from-server.js +47 -0
  16. package/client/common/fetch.jsx +71 -0
  17. package/client/common/find-bookmark-group-id.js +15 -0
  18. package/client/common/find-parent.js +30 -0
  19. package/client/common/form-layout.js +27 -0
  20. package/client/common/fs.js +21 -0
  21. package/client/common/get-proxy.js +8 -0
  22. package/client/common/id-with-stamp.js +10 -0
  23. package/client/common/index-sorter.js +4 -0
  24. package/client/common/init-setting-item.js +32 -0
  25. package/client/common/is-absolute-path.js +3 -0
  26. package/client/common/is-ip.js +16 -0
  27. package/client/common/is-valid-path.js +7 -0
  28. package/client/common/key-control-pressed.js +13 -0
  29. package/client/common/key-pressed.js +13 -0
  30. package/client/common/key-shift-pressed.js +7 -0
  31. package/client/common/mode2permission.js +81 -0
  32. package/client/common/new-terminal.js +31 -0
  33. package/client/common/parse-int10.js +3 -0
  34. package/client/common/parse-json-safe.js +11 -0
  35. package/client/common/pass-enc.js +25 -0
  36. package/client/common/post-msg.js +3 -0
  37. package/client/common/pre.js +156 -0
  38. package/client/common/promise-timeout.js +27 -0
  39. package/client/common/resolve.js +31 -0
  40. package/client/common/run-idle.js +1 -0
  41. package/client/common/safe-local-storage.js +35 -0
  42. package/client/common/safe-name.js +19 -0
  43. package/client/common/sftp.js +74 -0
  44. package/client/common/terminal-theme.js +158 -0
  45. package/client/common/test-connection.js +12 -0
  46. package/client/common/time.js +30 -0
  47. package/client/common/to-simple-obj.js +5 -0
  48. package/client/common/track.js +7 -0
  49. package/client/common/transfer.js +76 -0
  50. package/client/common/trzsz.js +62 -0
  51. package/client/common/ui-theme.js +44 -0
  52. package/client/common/uid.js +5 -0
  53. package/client/common/update-check.js +79 -0
  54. package/client/common/upgrade.js +68 -0
  55. package/client/common/wait.js +8 -0
  56. package/client/common/ws.js +161 -0
  57. package/client/components/batch-op/batch-op.jsx +650 -0
  58. package/client/components/bookmark-form/bookmark-form.styl +8 -0
  59. package/client/components/bookmark-form/bookmark-group-tree-format.js +39 -0
  60. package/client/components/bookmark-form/encodes.js +44 -0
  61. package/client/components/bookmark-form/form-ssh-common.jsx +208 -0
  62. package/client/components/bookmark-form/form-tabs.jsx +69 -0
  63. package/client/components/bookmark-form/index.jsx +159 -0
  64. package/client/components/bookmark-form/local-form-ui.jsx +152 -0
  65. package/client/components/bookmark-form/local-form.jsx +16 -0
  66. package/client/components/bookmark-form/proxy.jsx +49 -0
  67. package/client/components/bookmark-form/quick-command-list.jsx +31 -0
  68. package/client/components/bookmark-form/quick-command.jsx +228 -0
  69. package/client/components/bookmark-form/render-auth-ssh.jsx +104 -0
  70. package/client/components/bookmark-form/render-connection-hopping.jsx +229 -0
  71. package/client/components/bookmark-form/render-delayed-scripts.jsx +88 -0
  72. package/client/components/bookmark-form/render-ssh-tunnel.jsx +116 -0
  73. package/client/components/bookmark-form/serial-form-ui.jsx +311 -0
  74. package/client/components/bookmark-form/serial-form.jsx +20 -0
  75. package/client/components/bookmark-form/sftp-enable.jsx +33 -0
  76. package/client/components/bookmark-form/ssh-form-ui.jsx +100 -0
  77. package/client/components/bookmark-form/ssh-form.jsx +348 -0
  78. package/client/components/bookmark-form/telnet-form-ui.jsx +154 -0
  79. package/client/components/bookmark-form/telnet-form.jsx +16 -0
  80. package/client/components/bookmark-form/tree-delete.jsx +87 -0
  81. package/client/components/bookmark-form/use-form-funcs.jsx +50 -0
  82. package/client/components/bookmark-form/use-quick-commands.jsx +83 -0
  83. package/client/components/bookmark-form/use-submit.jsx +77 -0
  84. package/client/components/bookmark-form/use-ui.jsx +82 -0
  85. package/client/components/bookmark-form/x11.jsx +23 -0
  86. package/client/components/common/animate-text.jsx +37 -0
  87. package/client/components/common/animate-text.styl +54 -0
  88. package/client/components/common/external-link.jsx +28 -0
  89. package/client/components/common/help-icon.jsx +25 -0
  90. package/client/components/common/highlight.jsx +23 -0
  91. package/client/components/common/highlight.styl +3 -0
  92. package/client/components/common/input-auto-focus.jsx +68 -0
  93. package/client/components/common/input-confirm.jsx +66 -0
  94. package/client/components/common/logo-elem.jsx +22 -0
  95. package/client/components/common/markdown.jsx +27 -0
  96. package/client/components/common/react-subx.jsx +1 -0
  97. package/client/components/common/resize-wrap.jsx +222 -0
  98. package/client/components/common/resize-wrap.styl +9 -0
  99. package/client/components/common/search.jsx +9 -0
  100. package/client/components/common/show-item.jsx +27 -0
  101. package/client/components/context-menu/boomarks.jsx +15 -0
  102. package/client/components/context-menu/context-menu.jsx +340 -0
  103. package/client/components/context-menu/context-menu.styl +90 -0
  104. package/client/components/context-menu/history.jsx +27 -0
  105. package/client/components/context-menu/icon-holder.jsx +5 -0
  106. package/client/components/context-menu/menu-btn.jsx +224 -0
  107. package/client/components/context-menu/sub-tab-menu.jsx +23 -0
  108. package/client/components/context-menu/tabs.jsx +22 -0
  109. package/client/components/context-menu/zoom.jsx +40 -0
  110. package/client/components/footer/batch-input.jsx +177 -0
  111. package/client/components/footer/footer-entry.jsx +141 -0
  112. package/client/components/footer/footer.styl +47 -0
  113. package/client/components/icons/match-case.jsx +10 -0
  114. package/client/components/icons/match-whole-word.jsx +13 -0
  115. package/client/components/icons/regular-exp.jsx +10 -0
  116. package/client/components/main/css-overwrite.jsx +92 -0
  117. package/client/components/main/error-wrapper.jsx +59 -0
  118. package/client/components/main/index.jsx +11 -0
  119. package/client/components/main/loading.jsx +25 -0
  120. package/client/components/main/main.jsx +149 -0
  121. package/client/components/main/term-fullscreen-control.jsx +21 -0
  122. package/client/components/main/term-fullscreen.styl +27 -0
  123. package/client/components/main/ui-theme.jsx +31 -0
  124. package/client/components/main/upgrade.jsx +351 -0
  125. package/client/components/main/upgrade.styl +27 -0
  126. package/client/components/main/wrapper.styl +41 -0
  127. package/client/components/quick-commands/qm.styl +29 -0
  128. package/client/components/quick-commands/quick-command-item.jsx +36 -0
  129. package/client/components/quick-commands/quick-command-transport-mod.jsx +54 -0
  130. package/client/components/quick-commands/quick-command-transport.jsx +12 -0
  131. package/client/components/quick-commands/quick-commands-box.jsx +233 -0
  132. package/client/components/quick-commands/quick-commands-form-elem.jsx +119 -0
  133. package/client/components/quick-commands/quick-commands-form.jsx +33 -0
  134. package/client/components/quick-commands/quick-commands-list.jsx +128 -0
  135. package/client/components/quick-commands/quick-commands-select.jsx +38 -0
  136. package/client/components/session/session.jsx +533 -0
  137. package/client/components/session/session.styl +53 -0
  138. package/client/components/session/sessions.jsx +445 -0
  139. package/client/components/setting-panel/bookmark-transport.jsx +148 -0
  140. package/client/components/setting-panel/bookmark-tree-list.jsx +14 -0
  141. package/client/components/setting-panel/col.jsx +18 -0
  142. package/client/components/setting-panel/list.jsx +186 -0
  143. package/client/components/setting-panel/list.styl +33 -0
  144. package/client/components/setting-panel/on-tree-drop.js +222 -0
  145. package/client/components/setting-panel/setting-modal.jsx +163 -0
  146. package/client/components/setting-panel/setting-wrap.jsx +37 -0
  147. package/client/components/setting-panel/setting-wrap.styl +52 -0
  148. package/client/components/setting-panel/setting.jsx +858 -0
  149. package/client/components/setting-panel/setting.styl +4 -0
  150. package/client/components/setting-panel/start-session-select.jsx +91 -0
  151. package/client/components/setting-panel/tab-bookmarks.jsx +37 -0
  152. package/client/components/setting-panel/tab-history.jsx +44 -0
  153. package/client/components/setting-panel/tab-quick-commands.jsx +38 -0
  154. package/client/components/setting-panel/tab-settings.jsx +42 -0
  155. package/client/components/setting-panel/tab-themes.jsx +34 -0
  156. package/client/components/setting-panel/tree-list.jsx +978 -0
  157. package/client/components/setting-panel/tree-list.styl +57 -0
  158. package/client/components/setting-sync/data-import.jsx +65 -0
  159. package/client/components/setting-sync/setting-sync-form.jsx +271 -0
  160. package/client/components/setting-sync/setting-sync.jsx +81 -0
  161. package/client/components/setting-sync/sync.styl +7 -0
  162. package/client/components/sftp/address-bar.jsx +139 -0
  163. package/client/components/sftp/address-bookmark-item.jsx +47 -0
  164. package/client/components/sftp/address-bookmark.jsx +81 -0
  165. package/client/components/sftp/address-bookmark.styl +8 -0
  166. package/client/components/sftp/confirm-modal.jsx +184 -0
  167. package/client/components/sftp/file-icon.jsx +22 -0
  168. package/client/components/sftp/file-item.jsx +1226 -0
  169. package/client/components/sftp/file-mode-modal.jsx +205 -0
  170. package/client/components/sftp/file-props-modal.jsx +211 -0
  171. package/client/components/sftp/file-read.js +81 -0
  172. package/client/components/sftp/list-table-ui.jsx +547 -0
  173. package/client/components/sftp/owner-list.js +97 -0
  174. package/client/components/sftp/paged-list.jsx +60 -0
  175. package/client/components/sftp/permission-render.jsx +42 -0
  176. package/client/components/sftp/sftp-entry.jsx +1069 -0
  177. package/client/components/sftp/sftp.styl +217 -0
  178. package/client/components/sftp/transfer-common.js +9 -0
  179. package/client/components/sftp/transfer-conflict.jsx +315 -0
  180. package/client/components/sftp/transfer-speed-format.js +60 -0
  181. package/client/components/sftp/transfer-tag.jsx +40 -0
  182. package/client/components/sftp/transfer-tag.styl +11 -0
  183. package/client/components/sftp/transfer.styl +55 -0
  184. package/client/components/sftp/transport-action.jsx +410 -0
  185. package/client/components/sftp/transport-entry.jsx +108 -0
  186. package/client/components/sftp/transport-types.js +8 -0
  187. package/client/components/sftp/transports-action.jsx +111 -0
  188. package/client/components/sftp/transports-ui.jsx +93 -0
  189. package/client/components/sftp/zip.js +42 -0
  190. package/client/components/sidebar/bookmark-select.jsx +48 -0
  191. package/client/components/sidebar/bookmark.jsx +82 -0
  192. package/client/components/sidebar/history.jsx +66 -0
  193. package/client/components/sidebar/index.jsx +230 -0
  194. package/client/components/sidebar/info-modal.jsx +250 -0
  195. package/client/components/sidebar/info.styl +27 -0
  196. package/client/components/sidebar/side-icon.jsx +25 -0
  197. package/client/components/sidebar/sidebar.styl +128 -0
  198. package/client/components/sidebar/transfer-history-modal.jsx +110 -0
  199. package/client/components/sidebar/transfer-history.styl +3 -0
  200. package/client/components/sidebar/transfer-list-control.jsx +205 -0
  201. package/client/components/sidebar/transfer-list.jsx +55 -0
  202. package/client/components/sidebar/transfer-modal.jsx +76 -0
  203. package/client/components/sidebar/transfer.styl +8 -0
  204. package/client/components/sidebar/transport-ui.jsx +109 -0
  205. package/client/components/tabs/index.jsx +320 -0
  206. package/client/components/tabs/tab.jsx +427 -0
  207. package/client/components/tabs/tabs.styl +220 -0
  208. package/client/components/tabs/window-control.jsx +55 -0
  209. package/client/components/terminal/attach-addon-custom.js +70 -0
  210. package/client/components/terminal/build-ls-term-id.js +5 -0
  211. package/client/components/terminal/index.jsx +1358 -0
  212. package/client/components/terminal/normal-buffer.jsx +33 -0
  213. package/client/components/terminal/term-search.jsx +224 -0
  214. package/client/components/terminal/term-search.styl +15 -0
  215. package/client/components/terminal/terminal-apis.js +31 -0
  216. package/client/components/terminal/terminal-interactive.jsx +148 -0
  217. package/client/components/terminal/terminal.styl +96 -0
  218. package/client/components/terminal/xterm-zmodem.js +48 -0
  219. package/client/components/terminal/zmodem-transfer.jsx +98 -0
  220. package/client/components/terminal/zmodem.styl +14 -0
  221. package/client/components/terminal-info/activity.jsx +54 -0
  222. package/client/components/terminal-info/base.jsx +25 -0
  223. package/client/components/terminal-info/content.jsx +101 -0
  224. package/client/components/terminal-info/data-cols-parser.jsx +50 -0
  225. package/client/components/terminal-info/disk.jsx +29 -0
  226. package/client/components/terminal-info/index.jsx +25 -0
  227. package/client/components/terminal-info/network.jsx +114 -0
  228. package/client/components/terminal-info/resource.jsx +80 -0
  229. package/client/components/terminal-info/run-cmd.jsx +273 -0
  230. package/client/components/terminal-info/terminal-info.styl +29 -0
  231. package/client/components/terminal-info/up.jsx +15 -0
  232. package/client/components/terminal-theme/index.jsx +264 -0
  233. package/client/components/terminal-theme/terminal-theme-list.styl +3 -0
  234. package/client/components/terminal-theme/theme-list.jsx +146 -0
  235. package/client/components/text-editor/text-editor-form.jsx +97 -0
  236. package/client/components/text-editor/text-editor.jsx +182 -0
  237. package/client/css/antd-overwrite.styl +14 -0
  238. package/client/css/basic.styl +38 -0
  239. package/client/css/includes/box.styl +154 -0
  240. package/client/css/includes/font-size.styl +6 -0
  241. package/client/css/includes/index.styl +3 -0
  242. package/client/css/includes/text.styl +31 -0
  243. package/client/css/includes/theme-default.styl +20 -0
  244. package/client/entry/basic.js +58 -0
  245. package/client/entry/index.jsx +15 -0
  246. package/client/entry/worker.js +137 -0
  247. package/client/store/address-bookmark.js +25 -0
  248. package/client/store/app-upgrade.js +23 -0
  249. package/client/store/batch-input-history.js +26 -0
  250. package/client/store/bookmark-group.js +128 -0
  251. package/client/store/bookmark.js +22 -0
  252. package/client/store/common.js +140 -0
  253. package/client/store/context-menu.js +23 -0
  254. package/client/store/db-upgrade.js +43 -0
  255. package/client/store/event.js +70 -0
  256. package/client/store/index.js +335 -0
  257. package/client/store/init-state.js +191 -0
  258. package/client/store/item.js +120 -0
  259. package/client/store/load-data.js +198 -0
  260. package/client/store/quick-command.js +43 -0
  261. package/client/store/session.js +54 -0
  262. package/client/store/setting.js +208 -0
  263. package/client/store/sidebar.js +48 -0
  264. package/client/store/sync.js +390 -0
  265. package/client/store/system-menu.js +120 -0
  266. package/client/store/tab.js +74 -0
  267. package/client/store/terminal-theme.js +116 -0
  268. package/client/store/transfer-history.js +27 -0
  269. package/client/store/transfer-list.js +20 -0
  270. package/client/store/ui-theme.js +71 -0
  271. package/client/store/watch.js +116 -0
  272. package/client/views/index.pug +58 -0
  273. package/package.json +34 -0
@@ -0,0 +1,427 @@
1
+ /**
2
+ * file section
3
+ */
4
+
5
+ import React from 'react'
6
+ import runIdle from '../../common/run-idle'
7
+ import {
8
+ CloseOutlined,
9
+ Loading3QuartersOutlined,
10
+ BorderlessTableOutlined
11
+ } from '@ant-design/icons'
12
+ import generate from '../../common/uid'
13
+ import { Tooltip, message } from 'antd'
14
+ import classnames from 'classnames'
15
+ import copy from 'json-deep-copy'
16
+ import { isEqual, findIndex, some, pick } from 'lodash-es'
17
+ import Input from '../common/input-auto-focus'
18
+ import createName from '../../common/create-title'
19
+ import { addClass, removeClass } from '../../common/class'
20
+ import {
21
+ terminalSshConfigType,
22
+ ctrlOrCmd,
23
+ commonActions
24
+ } from '../../common/constants'
25
+
26
+ const { prefix } = window
27
+ const e = prefix('tabs')
28
+ const m = prefix('menu')
29
+ const onDragCls = 'ondrag-tab'
30
+ const onDragOverCls = 'dragover-tab'
31
+
32
+ export default class Tab extends React.Component {
33
+ constructor (props) {
34
+ super(props)
35
+ this.state = {
36
+ terminalOnData: false,
37
+ tab: copy(props.tab)
38
+ }
39
+ }
40
+
41
+ componentDidMount () {
42
+ this.dom = document.getElementById('id' + this.state.tab.id)
43
+ window.addEventListener('message', this.onEvent)
44
+ }
45
+
46
+ componentDidUpdate (prevProps) {
47
+ if (!isEqual(prevProps.tab, this.props.tab)) {
48
+ this.setState({
49
+ tab: copy(this.props.tab)
50
+ })
51
+ }
52
+ }
53
+
54
+ componentWillUnmount () {
55
+ window.removeEventListener('message', this.onEvent)
56
+ window.removeEventListener('message', this.onContextAction)
57
+ clearTimeout(this.handler)
58
+ }
59
+
60
+ modifier = (...args) => {
61
+ runIdle(() => this.setState(...args))
62
+ }
63
+
64
+ onEvent = (e) => {
65
+ if (
66
+ e.data &&
67
+ e.data.action === 'terminal-receive-data' &&
68
+ e.data.tabId === this.state.tab.id
69
+ ) {
70
+ this.modifier({
71
+ terminalOnData: true
72
+ })
73
+ if (this.handler) {
74
+ clearTimeout(this.handler)
75
+ }
76
+ this.handler = setTimeout(this.offTerminalOnData, 4000)
77
+ }
78
+ }
79
+
80
+ offTerminalOnData = () => {
81
+ this.modifier({
82
+ terminalOnData: false
83
+ })
84
+ }
85
+
86
+ clearCls = () => {
87
+ document.querySelectorAll('.' + onDragOverCls).forEach((d) => {
88
+ removeClass(d, onDragOverCls)
89
+ })
90
+ }
91
+
92
+ handleClick = (e) => {
93
+ const {
94
+ onChangeTabId
95
+ } = this.props
96
+ const { id } = this.state.tab
97
+ onChangeTabId(id)
98
+ }
99
+
100
+ onDrag = () => {
101
+ addClass(this.dom, onDragCls)
102
+ }
103
+
104
+ onDragEnter = () => {
105
+ this.clearCls()
106
+ addClass(this.dom, onDragOverCls)
107
+ }
108
+
109
+ onDragExit = () => {
110
+ // debug('ondragexit')
111
+ // let {target} = e
112
+ // removeClass(target, 'sftp-dragover')
113
+ }
114
+
115
+ onDragLeave = e => {
116
+ // debug('ondragleave')
117
+ const { target } = e
118
+ removeClass(target, onDragOverCls)
119
+ }
120
+
121
+ onDragOver = e => {
122
+ // debug('ondragover')
123
+ // debug(e.target)
124
+ // removeClass(this.dom, 'sftp-dragover')
125
+ e.preventDefault()
126
+ }
127
+
128
+ onDragStart = e => {
129
+ // debug('ondragstart')
130
+ // debug(e.target)
131
+ e.dataTransfer.setData('fromFile', JSON.stringify(this.state.tab))
132
+ // e.effectAllowed = 'copyMove'
133
+ }
134
+
135
+ onDrop = e => {
136
+ e.preventDefault()
137
+ const { target } = e
138
+ if (!target) {
139
+ return
140
+ }
141
+ // debug('target drop', target)
142
+ const fromTab = JSON.parse(e.dataTransfer.getData('fromFile'))
143
+ const onDropTab = document.querySelector('.' + onDragOverCls)
144
+ if (!onDropTab || !fromTab) {
145
+ return
146
+ }
147
+ const dropId = onDropTab.getAttribute('data-id')
148
+ if (!dropId || dropId === fromTab.id) {
149
+ return
150
+ }
151
+ const { id } = fromTab
152
+ const tabs = copy(this.props.tabs)
153
+ const indexFrom = findIndex(tabs, t => t.id === id)
154
+ let indexDrop = findIndex(tabs, t => t.id === dropId)
155
+ if (indexDrop > indexFrom) {
156
+ indexDrop = indexDrop - 1
157
+ }
158
+ tabs.splice(indexFrom, 1)
159
+ tabs.splice(indexDrop, 0, fromTab)
160
+ this.props.setTabs(
161
+ tabs
162
+ )
163
+ window.store.focus()
164
+ }
165
+
166
+ handleReloadTab = async () => {
167
+ this.props.reloadTab(this.state.tab)
168
+ }
169
+
170
+ onDragEnd = e => {
171
+ removeClass(this.dom, onDragCls)
172
+ this.clearCls()
173
+ e && e.dataTransfer && e.dataTransfer.clearData()
174
+ }
175
+
176
+ handleClose = () => {
177
+ this.props.delTab(this.state.tab.id)
178
+ }
179
+
180
+ handleDup = () => {
181
+ this.props.onDuplicateTab(
182
+ this.state.tab
183
+ )
184
+ }
185
+
186
+ newTab = () => {
187
+ this.props.addTab()
188
+ }
189
+
190
+ doRename = () => {
191
+ const tab = copy(this.state.tab)
192
+ tab.titleTemp = tab.title || ''
193
+ tab.isEditting = true
194
+ this.setState({
195
+ tab
196
+ })
197
+ }
198
+
199
+ handleBlur = () => {
200
+ const tab = copy(this.state.tab)
201
+ const { titleTemp, title, id, host } = tab
202
+ if (!titleTemp && !host) {
203
+ return message.warning(e('titleEmptyWarn'))
204
+ }
205
+ delete tab.isEditting
206
+ if (title === titleTemp) {
207
+ delete tab.titleTemp
208
+ return this.setState({
209
+ tab
210
+ })
211
+ }
212
+ this.setState({
213
+ tab
214
+ })
215
+ this.props.editTab(id, { title: titleTemp })
216
+ }
217
+
218
+ handleChange = e => {
219
+ const titleTemp = e.target.value
220
+ const tab = copy(this.state.tab)
221
+ tab.titleTemp = titleTemp
222
+ this.setState({
223
+ tab
224
+ })
225
+ }
226
+
227
+ closeOther = () => {
228
+ const { setTabs, onChangeTabId } = this.props
229
+ onChangeTabId(this.props.tab.id)
230
+ setTabs([this.props.tab])
231
+ }
232
+
233
+ closeTabsRight = () => {
234
+ const {
235
+ tab, currentTabId,
236
+ onChangeTabId,
237
+ setTabs
238
+ } = this.props
239
+ let tabs = copy(this.props.tabs)
240
+ const index = findIndex(tabs, t => t.id === tab.id)
241
+ tabs = tabs.slice(0, index + 1)
242
+ if (!some(tabs, t => t.id === currentTabId)) {
243
+ onChangeTabId(tabs[0].id)
244
+ }
245
+ setTabs(tabs)
246
+ }
247
+
248
+ renderContext () {
249
+ const { tabs, tab } = this.props
250
+ const len = tabs.length
251
+ const index = findIndex(tabs, t => t.id === tab.id)
252
+ const noRight = index >= len - 1
253
+ const isSshConfig = tab.type === terminalSshConfigType
254
+ const res = []
255
+ res.push({
256
+ func: 'handleClose',
257
+ icon: 'CloseOutlined',
258
+ text: e('close'),
259
+ subText: `${ctrlOrCmd} + W`
260
+ })
261
+ res.push({
262
+ func: 'closeOther',
263
+ icon: 'CloseOutlined',
264
+ text: e('closeOtherTabs')
265
+ })
266
+ if (!noRight) {
267
+ res.push({
268
+ func: 'closeTabsRight',
269
+ icon: 'CloseOutlined',
270
+ text: e('closeTabRight')
271
+ })
272
+ }
273
+ res.push({
274
+ func: 'newTab',
275
+ icon: 'CodeOutlined',
276
+ text: e('newTab')
277
+ })
278
+ res.push({
279
+ func: 'handleDup',
280
+ icon: 'CopyOutlined',
281
+ text: e('duplicate')
282
+ })
283
+ res.push({
284
+ disabled: isSshConfig,
285
+ func: 'doRename',
286
+ icon: 'EditOutlined',
287
+ text: e('rename')
288
+ })
289
+ res.push({
290
+ func: 'handleReloadTab',
291
+ icon: 'Loading3QuartersOutlined',
292
+ text: m('reload')
293
+ })
294
+ return res
295
+ }
296
+
297
+ onContextAction = e => {
298
+ const {
299
+ action,
300
+ id,
301
+ args = [],
302
+ func
303
+ } = e.data || {}
304
+ if (
305
+ action !== commonActions.clickContextMenu ||
306
+ id !== this.uid ||
307
+ !this[func]
308
+ ) {
309
+ return false
310
+ }
311
+ window.removeEventListener('message', this.onContextAction)
312
+ this[func](...args)
313
+ }
314
+
315
+ handleContextMenu = e => {
316
+ e.preventDefault()
317
+ const { target } = e
318
+ const rect = target.getBoundingClientRect()
319
+ const items = this.renderContext()
320
+ this.uid = generate()
321
+ window.store.openContextMenu({
322
+ items,
323
+ pos: {
324
+ left: rect.left,
325
+ top: rect.top + 20
326
+ },
327
+ id: this.uid
328
+ })
329
+ window.addEventListener('message', this.onContextAction)
330
+ }
331
+
332
+ renderEditting (tab, cls) {
333
+ const {
334
+ titleTemp
335
+ } = tab
336
+ return (
337
+ <div className={cls + ' pd1x'}>
338
+ <Input
339
+ value={titleTemp}
340
+ onChange={this.handleChange}
341
+ onBlur={this.handleBlur}
342
+ onPressEnter={this.handleBlur}
343
+ />
344
+ </div>
345
+ )
346
+ }
347
+
348
+ renderCloseIcon () {
349
+ return (
350
+ <span className='tab-close pointer'>
351
+ <CloseOutlined onClick={this.handleClose} />
352
+ </span>
353
+ )
354
+ }
355
+
356
+ render () {
357
+ const {
358
+ currentTabId
359
+ } = this.props
360
+ const { isLast } = this.props
361
+ const { tab, terminalOnData } = this.state
362
+ const { id, isEditting, status, isTransporting, tabCount } = tab
363
+ const active = id === currentTabId
364
+ const cls = classnames(
365
+ `tab-${id}`,
366
+ 'tab',
367
+ { active },
368
+ {
369
+ 'tab-last': isLast
370
+ },
371
+ status,
372
+ {
373
+ 'is-terminal-active': terminalOnData
374
+ },
375
+ {
376
+ 'is-transporting': isTransporting
377
+ }
378
+ )
379
+ const title = createName(tab)
380
+ if (isEditting) {
381
+ return this.renderEditting(tab, cls)
382
+ }
383
+ return (
384
+ <Tooltip
385
+ title={title}
386
+ placement='top'
387
+ >
388
+ <div
389
+ className={cls}
390
+ draggable
391
+ id={'id' + id}
392
+ data-id={id}
393
+ {...pick(this, [
394
+ 'onDrag',
395
+ 'onDragEnter',
396
+ 'onDragExit',
397
+ 'onDragLeave',
398
+ 'onDragOver',
399
+ 'onDragStart',
400
+ 'onDrop',
401
+ 'onDragEnd'
402
+ ])}
403
+ >
404
+ <div
405
+ className='tab-title elli pd1x'
406
+ onClick={this.handleClick}
407
+ onDoubleClick={this.handleDup}
408
+ onContextMenu={this.handleContextMenu}
409
+ >
410
+ <Loading3QuartersOutlined
411
+ className='pointer tab-reload mg1r'
412
+ onClick={this.handleReloadTab}
413
+ title={m('reload')}
414
+ />
415
+ {tabCount}. {title}
416
+ </div>
417
+ <div className={'tab-status ' + status} />
418
+ <div className='tab-traffic' />
419
+ <BorderlessTableOutlined className='tab-terminal-feed' />
420
+ {
421
+ this.renderCloseIcon()
422
+ }
423
+ </div>
424
+ </Tooltip>
425
+ )
426
+ }
427
+ }
@@ -0,0 +1,220 @@
1
+ @require '../../css/includes/theme-default'
2
+ .tabs
3
+ position relative
4
+ height 56px
5
+ overflow hidden
6
+ background main-dark
7
+ .app-drag-area
8
+ .app-drag
9
+ position absolute
10
+ left 0
11
+ top 0
12
+ height 15px
13
+ right 0
14
+ z-index 1
15
+ .app-drag
16
+ -webkit-app-region drag
17
+ .tabs-inner
18
+ position relative
19
+ z-index 2
20
+ padding 0 5px 0 0
21
+ margin-top 10px
22
+ display inline-block
23
+ height 63px
24
+ overflow-x scroll
25
+ overflow-y hidden
26
+ margin-left 42px
27
+ -webkit-app-region drag
28
+ .tabs-wrapper
29
+ z-index 3
30
+ .tab
31
+ -webkit-app-region no-drag
32
+ display inline-block
33
+ vertical-align middle
34
+ cursor pointer
35
+ position relative
36
+ min-width 100px
37
+ max-width 200px
38
+ line-height 36px
39
+ margin 10px 1px 0 0
40
+ border-radius 3px 3px 0 0
41
+ background main-dark
42
+ text-align center
43
+ color text-dark
44
+ &.tab-last
45
+ margin-right 5px
46
+ .tab-reload
47
+ .tab-close
48
+ display none
49
+ &.active
50
+ color text
51
+ background main
52
+ &:hover
53
+ .tab-close
54
+ display block
55
+ &.dragover-tab::after
56
+ position absolute
57
+ content ''
58
+ left -2px
59
+ top 0
60
+ width 1px
61
+ border 1px dashed text-dark
62
+ height 36px
63
+ &.error
64
+ .tab-reload
65
+ display inline-block
66
+ color text-light
67
+ @keyframes blink
68
+ 0%
69
+ opacity 0.3
70
+ 50%
71
+ opacity 1
72
+ 100%
73
+ opacity 0.3
74
+
75
+ .tab-terminal-feed
76
+ .tab-traffic
77
+ .tab-status
78
+ position absolute
79
+ left 2px
80
+ top 2px
81
+ width 5px
82
+ height 5px
83
+ border-radius 5px
84
+ background-color text-dark
85
+ &.success
86
+ background-color success
87
+ &.error
88
+ background-color error
89
+ &.processing
90
+ background-color primary
91
+ .is-transporting .tab-traffic
92
+ display block
93
+ animation blink 2s infinite
94
+ .tab-traffic
95
+ display none
96
+ left 10px
97
+ width 5px
98
+ border-radius 0
99
+ background-color success
100
+ .is-terminal-active .tab-terminal-feed
101
+ display block
102
+ animation blink 2s infinite
103
+ .tab-terminal-feed
104
+ display none
105
+ left 20px
106
+ border-radius 0
107
+ color success
108
+ background none
109
+ font-size 8px
110
+ left 2px
111
+ top 24px
112
+ .tab-close
113
+ position absolute
114
+ right 5px
115
+ cursor pointer
116
+ top 50%
117
+ margin-top -8px
118
+ background text-dark
119
+ border-radius 100%
120
+ color text
121
+ height 16px
122
+ width 16px
123
+ text-align center
124
+ line-height 16px
125
+ font-size 10px
126
+ &:hover
127
+ color text-light
128
+
129
+ .tabs-add-btn
130
+ display inline-block
131
+ vertical-align middle
132
+ margin 10px 3px 0 3px
133
+ -webkit-app-region no-drag
134
+ color text
135
+ &:hover
136
+ color text-light
137
+ .tabs-extra
138
+ position absolute
139
+ height 20px
140
+ top 34px
141
+ right 0
142
+ line-height 20px
143
+ z-index 20
144
+ -webkit-app-region no-drag
145
+ // .ant-btn
146
+ // background #333
147
+ // color #aaa
148
+ // border-color: #333
149
+ // &:hover
150
+ // color #ccc
151
+ .tabs-dd-icon
152
+ color text
153
+ font-size 12px
154
+ .tabs-add-btn
155
+ margin-top 0
156
+
157
+ .window-controls
158
+ position absolute
159
+ right 0
160
+ -webkit-app-region no-drag
161
+ top 0
162
+ z-index 200
163
+ border-radius 0 0 3px 3px
164
+ padding 0
165
+ background main-light
166
+
167
+ .window-control-box
168
+ display inline-block
169
+ padding 5px 10px
170
+ color text
171
+ -webkit-app-region no-drag
172
+ &:hover
173
+ color primary
174
+ cursor pointer
175
+ .icon-maximize
176
+ border-color primary
177
+ .icon-maximize
178
+ width 10px
179
+ height 7px
180
+ border 1px solid text
181
+ cursor pointer
182
+ &.is-max
183
+ height 6px
184
+ position relative
185
+ &:before
186
+ position absolute
187
+ content ''
188
+ left -3px
189
+ top 3px
190
+ width 8px
191
+ height 4px
192
+ border 1px solid text
193
+ border-top none
194
+ border-right none
195
+
196
+ .control-icon:hover
197
+ color text-light
198
+ .tab-scroll-icon
199
+ color text-dark
200
+ &:hover
201
+ color text
202
+
203
+ .add-menu-wrap
204
+ overflow-y scroll
205
+ .window-controls
206
+ .window-control-minimize
207
+ .window-control-maximize
208
+ &:hover
209
+ background main-dark
210
+ .window-control-close:hover
211
+ background error
212
+
213
+ .system-ui
214
+ .window-controls
215
+ .app-drag
216
+ display none
217
+ .tabs
218
+ height 45px
219
+ .tabs-inner
220
+ margin-top 0
@@ -0,0 +1,55 @@
1
+ /**
2
+ * btns
3
+ */
4
+
5
+ import { CloseOutlined, MinusOutlined } from '@ant-design/icons'
6
+ import { Component } from '../common/react-subx'
7
+
8
+ const { prefix } = window
9
+ const m = prefix('menu')
10
+
11
+ export default class WindowControl extends Component {
12
+ render () {
13
+ const {
14
+ isMaximized
15
+ } = this.props.store
16
+ const minimize = () => {
17
+ window.pre.runGlobalAsync('minimize')
18
+ }
19
+ const maximize = () => {
20
+ window.pre.runGlobalAsync('maximize')
21
+ }
22
+ const unmaximize = () => {
23
+ window.pre.runGlobalAsync('unmaximize')
24
+ }
25
+ const closeApp = () => {
26
+ window.store.exit()
27
+ }
28
+ return (
29
+ <div className='window-controls'>
30
+ <div className='window-control-box window-control-minimize' onClick={minimize}>
31
+ <MinusOutlined title={m('minimize')} className='iblock font12 widnow-control-icon' />
32
+ </div>
33
+ <div
34
+ className='window-control-box window-control-maximize'
35
+ onClick={
36
+ isMaximized ? unmaximize : maximize
37
+ }
38
+ >
39
+ <span
40
+ title={
41
+ isMaximized ? m('unmaximize') : m('maximize')
42
+ }
43
+ className={
44
+ 'iblock font12 icon-maximize widnow-control-icon ' +
45
+ (isMaximized ? 'is-max' : 'not-max')
46
+ }
47
+ />
48
+ </div>
49
+ <div className='window-control-box window-control-close' onClick={closeApp}>
50
+ <CloseOutlined title={m('close')} className='iblock font12 widnow-control-icon' />
51
+ </div>
52
+ </div>
53
+ )
54
+ }
55
+ }