@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,547 @@
1
+ /**
2
+ * file list table
3
+ * features:
4
+ * - drag to resize table
5
+ * - context menu to set props to show
6
+ * - click header to sort
7
+ */
8
+
9
+ import React from 'react'
10
+ import classnames from 'classnames'
11
+ import { isEqual, pick, find, isNull, isArray, isUndefined } from 'lodash-es'
12
+ import generate from '../../common/uid'
13
+ import parseInt10 from '../../common/parse-int10'
14
+ import {
15
+ splitDraggerWidth,
16
+ filePropMinWidth,
17
+ maxDragMove,
18
+ sftpControlHeight,
19
+ eventTypes,
20
+ paneMap,
21
+ commonActions
22
+ } from '../../common/constants'
23
+ import copy from 'json-deep-copy'
24
+ import FileSection from './file-item'
25
+ import PagedList from './paged-list'
26
+
27
+ const { prefix } = window
28
+ const e = prefix('sftp')
29
+
30
+ export default class FileListTable extends React.Component {
31
+ constructor (props) {
32
+ super(props)
33
+ this.state = this.initFromProps()
34
+ }
35
+
36
+ componentDidMount () {
37
+ this.saveOldStyle()
38
+ window.addEventListener('message', this.onMsg)
39
+ }
40
+
41
+ componentDidUpdate (prevProps, prevState) {
42
+ if (this.state.properties.length < 2) {
43
+ return
44
+ }
45
+ if (
46
+ !isEqual(prevState.properties, this.state.properties) ||
47
+ (
48
+ this.toVisible(prevProps, this.props) &&
49
+ !this.inited
50
+ )
51
+ ) {
52
+ if (!this.inited) {
53
+ this.inited = true
54
+ }
55
+ this.saveOldStyle()
56
+ }
57
+ }
58
+
59
+ componentWillUnmount () {
60
+ window.removeEventListener('message', this.onContextAction)
61
+ window.removeEventListener('message', this.onMsg)
62
+ }
63
+
64
+ toVisible = (prevProps, props) => {
65
+ return (
66
+ prevProps.pane === paneMap.ssh ||
67
+ prevProps.pane === paneMap.terminal
68
+ ) &&
69
+ (
70
+ props.pane === paneMap.sftp ||
71
+ props.pane === paneMap.fileManager
72
+ )
73
+ }
74
+
75
+ onMsg = e => {
76
+ const { type, data } = e.data || {}
77
+ if (
78
+ type === eventTypes.resetFileListTable &&
79
+ data.id === this.props.id
80
+ ) {
81
+ this.resetWidth()
82
+ }
83
+ }
84
+
85
+ initFromProps = (pps = this.getPropsDefault()) => {
86
+ const { length } = pps
87
+ const { width } = this.props
88
+ const padding = 5
89
+ const w = (width - padding * 2) / length
90
+ const properties = pps.map((name, i) => {
91
+ return {
92
+ name,
93
+ id: generate(),
94
+ style: {
95
+ width: w + 'px',
96
+ left: (w * i) + 'px',
97
+ zIndex: 3 + i
98
+ }
99
+ }
100
+ })
101
+ const splitHandles = properties.reduce((prev, { name }, i) => {
102
+ if (i === length - 1) {
103
+ return prev
104
+ }
105
+ return [
106
+ ...prev,
107
+ {
108
+ id: generate(),
109
+ prevProp: name,
110
+ nextProp: properties[i + 1].name,
111
+ style: {
112
+ left: (w * (i + 1) - (splitDraggerWidth / 2)) + 'px',
113
+ width: splitDraggerWidth + 'px'
114
+ }
115
+ }
116
+ ]
117
+ }, [])
118
+ return {
119
+ pageSize: 100,
120
+ properties,
121
+ splitHandles
122
+ }
123
+ }
124
+
125
+ getPropsDefault = () => {
126
+ return [
127
+ 'name',
128
+ 'size',
129
+ 'modifyTime'
130
+ ]
131
+ }
132
+
133
+ getPropsAll = () => {
134
+ return [
135
+ 'name',
136
+ 'size',
137
+ 'modifyTime',
138
+ 'accessTime',
139
+ 'owner',
140
+ 'group',
141
+ 'mode',
142
+ 'path',
143
+ 'ext'
144
+ ]
145
+ }
146
+
147
+ otherDirection = (direction) => {
148
+ return direction === this.props.directions[0]
149
+ ? this.props.directions[1]
150
+ : this.props.directions[0]
151
+ }
152
+
153
+ renderTableHeader = () => {
154
+ const { properties, splitHandles } = this.state
155
+ const arr = properties.reduce((prev, p, i) => {
156
+ return [
157
+ ...prev,
158
+ p,
159
+ splitHandles[i]
160
+ ]
161
+ }, []).filter(d => d)
162
+ return (
163
+ <div
164
+ className='sftp-file-table-header relative'
165
+ onContextMenu={this.handleContextMenu}
166
+ >
167
+ {
168
+ arr.map(this.renderHeaderItem)
169
+ }
170
+ </div>
171
+ )
172
+ }
173
+
174
+ renderHeaderItem = (item) => {
175
+ const {
176
+ name,
177
+ id,
178
+ style
179
+ } = item
180
+ const isHandle = !name
181
+ const { sortDirection, sortProp } = this.props
182
+ const isSorting = !isHandle && sortProp === name
183
+ const cls = classnames(
184
+ 'sftp-header-item',
185
+ isHandle ? `shi-${id}` : `sftp-header-box shi-${name}`,
186
+ {
187
+ 'sftp-header-handle': isHandle
188
+ },
189
+ {
190
+ 'sftp-header-name': !isHandle
191
+ },
192
+ {
193
+ 'is-sorting': isSorting
194
+ },
195
+ isSorting ? sortDirection : ''
196
+ )
197
+ const props = isHandle
198
+ ? pick(this, [
199
+ 'onDoubleClick',
200
+ 'onDrag',
201
+ 'onDragStart',
202
+ 'onDragEnd'
203
+ ])
204
+ : {
205
+ onClick: this.onClickName
206
+ }
207
+ const text = e(name || '')
208
+ return (
209
+ <div
210
+ className={cls}
211
+ style={style}
212
+ id={id}
213
+ key={id}
214
+ draggable={isHandle}
215
+ {...props}
216
+ title={text}
217
+ >
218
+ {text}
219
+ </div>
220
+ )
221
+ }
222
+
223
+ computePos = (e, height) => {
224
+ return {
225
+ left: e.clientX,
226
+ top: e.clientY
227
+ }
228
+ }
229
+
230
+ onToggleProp = name => {
231
+ const { properties } = this.state
232
+ const names = properties.map(d => d.name)
233
+ const all = this.getPropsAll()
234
+ const newProps = names.includes(name)
235
+ ? names.filter(d => d !== name)
236
+ : [...names, name]
237
+ const props = all.filter(g => newProps.includes(g))
238
+ const update = this.initFromProps(props)
239
+ this.setState(update)
240
+ }
241
+
242
+ onContextAction = e => {
243
+ const {
244
+ action,
245
+ id,
246
+ args = [],
247
+ func
248
+ } = e.data || {}
249
+ if (
250
+ action !== commonActions.clickContextMenu ||
251
+ id !== this.uid ||
252
+ !this[func]
253
+ ) {
254
+ return false
255
+ }
256
+ window.removeEventListener('message', this.onContextAction)
257
+ this[func](...args)
258
+ }
259
+
260
+ handleContextMenu = e => {
261
+ e && e.preventDefault()
262
+ const items = this.renderContext()
263
+ const pos = e
264
+ ? this.computePos(e)
265
+ : this.pos
266
+ this.pos = pos
267
+ this.uid = generate()
268
+ window.store.openContextMenu({
269
+ id: this.uid,
270
+ items,
271
+ pos
272
+ })
273
+ window.addEventListener('message', this.onContextAction)
274
+ }
275
+
276
+ onClickName = (e) => {
277
+ const id = e.target.getAttribute('id')
278
+ const { properties } = this.state
279
+ const propObj = find(
280
+ properties,
281
+ p => p.id === id
282
+ )
283
+ if (!propObj) {
284
+ return
285
+ }
286
+ const { name } = propObj
287
+ const { sortDirection, sortProp } = this.props
288
+ const sortDirectionNew = sortProp === name
289
+ ? this.otherDirection(sortDirection)
290
+ : this.props.defaultDirection()
291
+ const { type } = this.props
292
+ window.store.setSftpSortSetting({
293
+ [type]: {
294
+ direction: sortDirectionNew,
295
+ prop: name
296
+ }
297
+ })
298
+
299
+ this.props.modifier({
300
+ [`sortDirection.${type}`]: sortDirectionNew,
301
+ [`sortProp.${type}`]: name
302
+ })
303
+ }
304
+
305
+ renderContext = () => {
306
+ const { properties } = this.state
307
+ const all = this.getPropsAll()
308
+ const selectedNames = properties.map(d => d.name)
309
+ return all.map((p, i) => {
310
+ const selected = selectedNames.includes(p)
311
+ const disabled = !i
312
+ const cls = classnames(
313
+ { selected },
314
+ { unselected: !selected }
315
+ )
316
+ return {
317
+ func: 'onToggleProp',
318
+ icon: disabled || selected ? 'CheckOutlined' : 'IconHolder',
319
+ text: e(p),
320
+ disabled,
321
+ args: [p],
322
+ noCloseMenu: true,
323
+ className: cls
324
+ }
325
+ })
326
+ }
327
+
328
+ positionProps = [
329
+ 'width',
330
+ 'left'
331
+ ]
332
+
333
+ saveOldStyle = () => {
334
+ const { properties, splitHandles } = this.state
335
+ const ids = [
336
+ ...properties,
337
+ ...splitHandles
338
+ ]
339
+ const { type, id } = this.props
340
+ const parentWidth = document.querySelector(
341
+ `#id-${id} .tw-${type} .sftp-table`
342
+ ).clientWidth
343
+ this.oldStyles = ids.reduce((prev, { id, name }) => {
344
+ const sel = `.session-current .tw-${type} .sftp-file-table-header .shi-${name || id}`
345
+ return {
346
+ ...prev,
347
+ [name || id]: {
348
+ style: pick(
349
+ document.querySelector(sel)?.style || {},
350
+ this.positionProps
351
+ ),
352
+ parentWidth
353
+ }
354
+ }
355
+ }, {})
356
+ }
357
+
358
+ onDrag = (e) => {
359
+ if (isNull(e.pageX)) {
360
+ return
361
+ }
362
+ const dom = e.target
363
+ const { splitHandles } = this.state
364
+ const { type } = this.props
365
+ const id = dom.getAttribute('id')
366
+ const splitHandle = find(
367
+ splitHandles,
368
+ s => s.id === id
369
+ )
370
+ const {
371
+ prevProp,
372
+ nextProp
373
+ } = splitHandle
374
+ const selPrev = `.session-current .tw-${type} .shi-${prevProp}`
375
+ const selNext = `.session-current .tw-${type} .shi-${nextProp}`
376
+ const prev = Array.from(document.querySelectorAll(selPrev))
377
+ const next = Array.from(document.querySelectorAll(selNext))
378
+ const { startPosition } = this
379
+ const currentPosition = {
380
+ x: e.pageX
381
+ }
382
+
383
+ const types = ['dom', 'prev', 'next']
384
+ const doms = [dom, prev, next]
385
+ const styles = doms.map(d => {
386
+ const dd = isArray(d) ? d[0] : d
387
+ const { style } = dd
388
+ const rect = dd.getBoundingClientRect()
389
+ const obj = pick(style, this.positionProps)
390
+ const res = Object.keys(obj).reduce((prev, k) => {
391
+ const v = obj[k]
392
+ return {
393
+ ...prev,
394
+ [k]: isUndefined(v)
395
+ ? v
396
+ : parseInt10(obj[k].replace('px', ''))
397
+ }
398
+ }, {})
399
+ res.width = rect.right - rect.left
400
+ return res
401
+ })
402
+ let xDiff = currentPosition.x - startPosition.x
403
+ if (Math.abs(xDiff) > maxDragMove) {
404
+ return
405
+ }
406
+ const prevStyle = styles[1]
407
+ const nextStyle = styles[2]
408
+ const minW = filePropMinWidth
409
+ if (xDiff > 0 && xDiff > nextStyle.width - minW) {
410
+ xDiff = nextStyle.width - minW
411
+ } else if (xDiff < 0 && xDiff < -(prevStyle.width - minW)) {
412
+ xDiff = -(prevStyle.width - minW)
413
+ }
414
+ doms.forEach((d, i) => {
415
+ this.changePosition(d, xDiff, types[i], styles[i])
416
+ })
417
+ this.startPosition = currentPosition
418
+ }
419
+
420
+ onDragStart = (e) => {
421
+ this.startPosition = {
422
+ x: e.pageX
423
+ }
424
+ }
425
+
426
+ changePosition = (
427
+ dom,
428
+ xDiff,
429
+ type,
430
+ style
431
+ ) => {
432
+ const realWidth = style.width
433
+ const realLeft = style.left
434
+ if (type === 'prev') {
435
+ dom.forEach(d => {
436
+ d.style.width = (realWidth + xDiff) + 'px'
437
+ })
438
+ } else if (type === 'dom') {
439
+ dom.style.left = (realLeft + xDiff) + 'px'
440
+ } else {
441
+ dom.forEach(d => {
442
+ d.style.width = (realWidth - xDiff) + 'px'
443
+ d.style.left = (realLeft + xDiff) + 'px'
444
+ })
445
+ }
446
+ }
447
+
448
+ // onDragEnd = () => {}
449
+
450
+ onDoubleClick = () => this.resetWidth()
451
+
452
+ hasPager = () => {
453
+ const {
454
+ pageSize
455
+ } = this.state
456
+ const {
457
+ fileList
458
+ } = this.props
459
+ const len = fileList.length
460
+ return len > pageSize
461
+ }
462
+
463
+ rebuildStyle = (name) => {
464
+ let { style, parentWidth } = this.oldStyles[name]
465
+ style = copy(style)
466
+ const {
467
+ type,
468
+ id
469
+ } = this.props
470
+ const currentParentWidth = document.querySelector(
471
+ `#id-${id} .tw-${type} .sftp-table`
472
+ ).clientWidth
473
+ style.width = (parseFloat(style.width) * currentParentWidth / parentWidth) + 'px'
474
+ style.left = (parseFloat(style.left) * currentParentWidth / parentWidth) + 'px'
475
+ return style
476
+ }
477
+
478
+ // reset
479
+ resetWidth = () => {
480
+ const { properties, splitHandles } = this.state
481
+ const ids = [
482
+ ...properties,
483
+ ...splitHandles
484
+ ]
485
+ const { type } = this.props
486
+ ids.forEach(({ id, name }) => {
487
+ const sel = `.session-current .tw-${type} .shi-${name || id}`
488
+ const arr = Array.from(
489
+ document.querySelectorAll(sel)
490
+ )
491
+ arr.forEach(d => {
492
+ Object.assign(
493
+ d.style,
494
+ this.rebuildStyle(
495
+ name || id
496
+ )
497
+ )
498
+ })
499
+ })
500
+ }
501
+
502
+ renderItem = (item, i) => {
503
+ const { type } = this.props
504
+ return (
505
+ <FileSection
506
+ {...this.props.getFileProps(item, type)}
507
+ key={i + '*f*' + item.id}
508
+ cls='real-file-item'
509
+ properties={this.state.properties}
510
+ />
511
+ )
512
+ }
513
+
514
+ render () {
515
+ const { fileList, height, type } = this.props
516
+ const tableHeaderHeight = 30
517
+ const props = {
518
+ className: 'sftp-table-content overscroll-y relative',
519
+ style: {
520
+ height: height - sftpControlHeight - tableHeaderHeight
521
+ },
522
+ draggable: false
523
+ }
524
+ const hasPager = this.hasPager()
525
+ const cls = classnames(
526
+ 'sftp-table relative',
527
+ {
528
+ 'sftp-has-pager': hasPager
529
+ }
530
+ )
531
+ return (
532
+ <div className={cls}>
533
+ {this.renderTableHeader()}
534
+ <div
535
+ {...props}
536
+ >
537
+ {this.props.renderEmptyFile(type)}
538
+ <PagedList
539
+ list={fileList}
540
+ renderItem={this.renderItem}
541
+ hasPager={hasPager}
542
+ />
543
+ </div>
544
+ </div>
545
+ )
546
+ }
547
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * get owner group/users list of local and remote sessions
3
+ *
4
+ * for mac list users: `dscl . -list /Users UniqueID`
5
+ * for mac list groups: `dscl . list /Groups PrimaryGroupID`
6
+ * for linux list users: `cat /etc/passwd`
7
+ * for linux list groups: `cat /etc/group`
8
+ * for windows list users: do not know yet
9
+ * for windows list groups: do not know yet
10
+ */
11
+
12
+ import fs from '../../common/fs'
13
+ import { runCmd } from '../terminal/terminal-apis'
14
+ import { isWin, isMac } from '../../common/constants'
15
+
16
+ function parseNames (str) {
17
+ return str.split('\n')
18
+ .reduce((p, d) => {
19
+ const [name, , id] = d.split(':')
20
+ return {
21
+ ...p,
22
+ [id + '']: name
23
+ }
24
+ }, {})
25
+ }
26
+
27
+ const linuxListUser = 'cat /etc/passwd'
28
+ const linuxListGroup = 'cat /etc/group'
29
+
30
+ export async function remoteListUsers (pid, sessionId) {
31
+ const users = await runCmd(pid, sessionId, linuxListUser)
32
+ .catch(log.error)
33
+ if (users) {
34
+ return parseNames(users)
35
+ }
36
+ return {}
37
+ }
38
+
39
+ export async function remoteListGroups (pid, sessionId) {
40
+ const groups = await runCmd(pid, sessionId, linuxListGroup)
41
+ .catch(log.error)
42
+ if (groups) {
43
+ return parseNames(groups)
44
+ }
45
+ return {}
46
+ }
47
+
48
+ export async function localListUsers () {
49
+ if (isWin) {
50
+ return {}
51
+ } else if (isMac) {
52
+ const g = await fs.run('dscl . -list /Users UniqueID')
53
+ .catch(log.error)
54
+ return g
55
+ ? g.split('\n')
56
+ .reduce((p, s) => {
57
+ const [name, id] = s.split(/\s+/)
58
+ if (!id) {
59
+ return p
60
+ }
61
+ return {
62
+ ...p,
63
+ [id + '']: name
64
+ }
65
+ }, {})
66
+ : {}
67
+ } else {
68
+ const g = await fs.run(linuxListUser).catch(log.error)
69
+ return g
70
+ ? parseNames(g)
71
+ : {}
72
+ }
73
+ }
74
+
75
+ export async function localListGroups () {
76
+ if (isWin) {
77
+ return {}
78
+ } else if (isMac) {
79
+ const g = await fs.run('dscl . list /Groups PrimaryGroupID')
80
+ .catch(log.error)
81
+ return g
82
+ ? g.split('\n')
83
+ .reduce((p, s) => {
84
+ const [name, id] = s.split(/\s+/)
85
+ return {
86
+ ...p,
87
+ [id + '']: name
88
+ }
89
+ }, {})
90
+ : {}
91
+ } else {
92
+ const g = await fs.run(linuxListGroup).catch(log.error)
93
+ return g
94
+ ? parseNames(g)
95
+ : {}
96
+ }
97
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * file list module to limit files rendered to increase performance
3
+ */
4
+
5
+ import { Component } from 'react'
6
+ import { Pagination } from 'antd'
7
+
8
+ export default class ScrollFiles extends Component {
9
+ state = {
10
+ page: 1,
11
+ pageSize: 100
12
+ }
13
+
14
+ onChange = page => {
15
+ this.setState({
16
+ page
17
+ })
18
+ }
19
+
20
+ renderList () {
21
+ const {
22
+ page, pageSize
23
+ } = this.state
24
+ const start = (page - 1) * pageSize
25
+ const end = start + pageSize
26
+ const {
27
+ list, hasPager
28
+ } = this.props
29
+ const arr = hasPager
30
+ ? list.slice(start, end)
31
+ : list
32
+ return arr.map(this.props.renderItem)
33
+ }
34
+
35
+ renderPager () {
36
+ const props = {
37
+ current: this.state.page,
38
+ pageSize: this.state.pageSize,
39
+ total: this.props.list.length,
40
+ showSizeChanger: false,
41
+ size: 'small',
42
+ onChange: this.onChange
43
+ }
44
+ return (
45
+ <div className='pd1b pager-wrap'>
46
+ <Pagination
47
+ {...props}
48
+ />
49
+ </div>
50
+ )
51
+ }
52
+
53
+ render () {
54
+ const arr = this.renderList()
55
+ if (this.props.hasPager) {
56
+ arr.push(this.renderPager())
57
+ }
58
+ return arr
59
+ }
60
+ }