@electerm/electerm-react 1.60.18 → 1.60.32

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 (106) hide show
  1. package/client/common/clipboard.js +1 -14
  2. package/client/common/constants.js +0 -43
  3. package/client/common/data-compare.js +55 -0
  4. package/client/common/default-setting.js +2 -10
  5. package/client/common/resolve.js +18 -22
  6. package/client/common/sftp.js +0 -3
  7. package/client/components/ai/ai-chat.jsx +30 -6
  8. package/client/components/ai/ai-config.jsx +17 -6
  9. package/client/components/batch-op/batch-op.jsx +3 -24
  10. package/client/components/bookmark-form/bookmark-group-tree-format.js +7 -9
  11. package/client/components/bookmark-form/form-ssh-common.jsx +0 -2
  12. package/client/components/bookmark-form/ssh-form.jsx +8 -41
  13. package/client/components/bookmark-form/tree-delete.jsx +1 -13
  14. package/client/components/common/animate-text.jsx +3 -4
  15. package/client/components/common/drag-handle.jsx +59 -45
  16. package/client/components/common/drag-handle.styl +2 -1
  17. package/client/components/common/input-auto-focus.jsx +29 -63
  18. package/client/components/common/ref.js +24 -0
  19. package/client/components/footer/batch-input.jsx +1 -6
  20. package/client/components/footer/footer-entry.jsx +13 -16
  21. package/client/components/footer/footer.styl +0 -5
  22. package/client/components/icons/ai-icon.jsx +17 -0
  23. package/client/components/icons/ai-icon.styl +3 -0
  24. package/client/components/layout/layout-item.jsx +14 -0
  25. package/client/components/main/main.jsx +8 -19
  26. package/client/components/main/upgrade.jsx +13 -25
  27. package/client/components/profile/profile-form-elem.jsx +1 -2
  28. package/client/components/quick-commands/on-drop.js +1 -12
  29. package/client/components/quick-commands/quick-command-transport-mod.jsx +3 -13
  30. package/client/components/quick-commands/quick-commands-form-elem.jsx +1 -2
  31. package/client/components/rdp/rdp-session.jsx +4 -4
  32. package/client/components/session/session.jsx +9 -11
  33. package/client/components/setting-panel/on-tree-drop.js +4 -35
  34. package/client/components/setting-panel/setting-common.jsx +4 -1
  35. package/client/components/setting-panel/setting-modal.jsx +7 -5
  36. package/client/components/setting-panel/tab-settings.jsx +0 -1
  37. package/client/components/setting-sync/setting-sync.jsx +0 -1
  38. package/client/components/sftp/address-bookmark-item.jsx +1 -15
  39. package/client/components/sftp/confirm-modal-store.jsx +2 -2
  40. package/client/components/sftp/{file-mode-modal.jsx → file-info-modal.jsx} +137 -37
  41. package/client/components/sftp/file-item.jsx +156 -192
  42. package/client/components/sftp/file-table-header.jsx +98 -0
  43. package/client/components/sftp/list-table-ui.jsx +125 -416
  44. package/client/components/sftp/sftp-entry.jsx +102 -128
  45. package/client/components/sftp/sftp.styl +6 -22
  46. package/client/components/sftp/transfer-conflict-store.jsx +8 -12
  47. package/client/components/sftp/transport-action-store.jsx +7 -15
  48. package/client/components/shortcuts/shortcut-control.jsx +72 -3
  49. package/client/components/shortcuts/shortcut-handler.js +0 -1
  50. package/client/components/side-panel-r/side-panel-r.jsx +7 -4
  51. package/client/components/sidebar/bookmark-select.jsx +5 -3
  52. package/client/components/sidebar/history.jsx +3 -0
  53. package/client/components/sidebar/index.jsx +1 -1
  54. package/client/components/sidebar/info-modal.jsx +3 -0
  55. package/client/components/sidebar/side-panel.jsx +7 -4
  56. package/client/components/sidebar/sidebar-panel.jsx +1 -1
  57. package/client/components/sidebar/sidebar.styl +3 -3
  58. package/client/components/sys-menu/icons-map.jsx +52 -0
  59. package/client/components/{context-menu → sys-menu}/menu-btn.jsx +33 -45
  60. package/client/components/sys-menu/sys-menu.jsx +163 -0
  61. package/client/components/{context-menu/context-menu.styl → sys-menu/sys-menu.styl} +2 -11
  62. package/client/components/tabs/index.jsx +5 -97
  63. package/client/components/tabs/tab.jsx +121 -73
  64. package/client/components/tabs/tabs.styl +4 -1
  65. package/client/components/terminal/term-search.jsx +16 -28
  66. package/client/components/terminal/terminal-interactive.jsx +0 -2
  67. package/client/components/terminal/{index.jsx → terminal.jsx} +110 -240
  68. package/client/components/terminal-info/base.jsx +21 -46
  69. package/client/components/terminal-info/terminal-info.jsx +3 -0
  70. package/client/components/text-editor/text-editor.jsx +38 -53
  71. package/client/components/theme/theme-form.jsx +0 -2
  72. package/client/components/tree-list/bookmark-toolbar.jsx +23 -47
  73. package/client/components/tree-list/bookmark-transport.jsx +2 -90
  74. package/client/components/tree-list/move-item-modal.jsx +101 -0
  75. package/client/components/tree-list/tree-expander.jsx +2 -3
  76. package/client/components/tree-list/tree-list-item.jsx +8 -11
  77. package/client/components/tree-list/tree-list.jsx +75 -296
  78. package/client/components/vnc/vnc-session.jsx +5 -3
  79. package/client/store/app-upgrade.js +2 -5
  80. package/client/store/bookmark-group.js +116 -51
  81. package/client/store/common.js +36 -54
  82. package/client/store/event.js +4 -37
  83. package/client/store/init-state.js +9 -12
  84. package/client/store/item.js +34 -39
  85. package/client/store/load-data.js +5 -1
  86. package/client/store/quick-command.js +2 -12
  87. package/client/store/session.js +6 -7
  88. package/client/store/setting.js +3 -7
  89. package/client/store/sidebar.js +2 -8
  90. package/client/store/store.js +0 -20
  91. package/client/store/system-menu.js +1 -2
  92. package/client/store/tab.js +29 -1
  93. package/client/store/terminal-theme.js +0 -4
  94. package/client/store/watch.js +26 -4
  95. package/package.json +1 -1
  96. package/client/common/post-msg.js +0 -3
  97. package/client/components/common/native-input.jsx +0 -30
  98. package/client/components/context-menu/context-menu.jsx +0 -339
  99. package/client/components/sftp/file-props-modal.jsx +0 -210
  100. package/client/store/context-menu.js +0 -23
  101. /package/client/components/{context-menu → sys-menu}/boomarks.jsx +0 -0
  102. /package/client/components/{context-menu → sys-menu}/history.jsx +0 -0
  103. /package/client/components/{context-menu → sys-menu}/icon-holder.jsx +0 -0
  104. /package/client/components/{context-menu → sys-menu}/sub-tab-menu.jsx +0 -0
  105. /package/client/components/{context-menu → sys-menu}/tabs.jsx +0 -0
  106. /package/client/components/{context-menu → sys-menu}/zoom.jsx +0 -0
@@ -37,8 +37,7 @@ export default Store => {
37
37
  Store.prototype.openBookmarkEdit = function (item) {
38
38
  const { store } = window
39
39
  store.storeAssign({
40
- settingTab: settingMap.bookmarks,
41
- autofocustrigger: Date.now()
40
+ settingTab: settingMap.bookmarks
42
41
  })
43
42
  store.setSettingItem(item)
44
43
  store.openSettingModal()
@@ -47,8 +46,7 @@ export default Store => {
47
46
  Store.prototype.handleOpenQuickCommandsSetting = function () {
48
47
  const { store } = window
49
48
  store.storeAssign({
50
- settingTab: settingMap.quickCommands,
51
- autofocustrigger: Date.now()
49
+ settingTab: settingMap.quickCommands
52
50
  })
53
51
  store.setSettingItem(getInitItem([], settingMap.quickCommands))
54
52
  store.openSettingModal()
@@ -125,8 +123,7 @@ export default Store => {
125
123
  return store.hideSettingModal()
126
124
  }
127
125
  store.storeAssign({
128
- settingTab: settingMap.terminalThemes,
129
- autofocustrigger: Date.now()
126
+ settingTab: settingMap.terminalThemes
130
127
  })
131
128
  store.setSettingItem(buildNewTheme())
132
129
  store.openSettingModal()
@@ -162,7 +159,6 @@ export default Store => {
162
159
  const arr = store.getItems(settingTab)
163
160
  const item = getInitItem(arr, settingTab)
164
161
  store.storeAssign({
165
- autofocustrigger: Date.now(),
166
162
  settingTab
167
163
  })
168
164
  store.setSettingItem(item)
@@ -11,18 +11,12 @@ import * as ls from '../common/safe-local-storage'
11
11
  export default Store => {
12
12
  Store.prototype.expandBookmarks = function () {
13
13
  const { store } = window
14
- window.store.setState(
15
- 'expandedKeys',
16
- store.getBookmarkGroupsTotal().map(g => g.id)
17
- )
14
+ window.store.expandedKeys = store.getBookmarkGroupsTotal().map(g => g.id)
18
15
  }
19
16
 
20
17
  Store.prototype.collapseBookmarks = function () {
21
18
  const { store } = window
22
- store.setState(
23
- 'expandedKeys',
24
- []
25
- )
19
+ store.expandedKeys = []
26
20
  }
27
21
 
28
22
  Store.prototype.handlePin = function (pinned) {
@@ -11,7 +11,6 @@ import appUpgradeExtend from './app-upgrade'
11
11
  import bookmarkGroupExtend from './bookmark-group'
12
12
  import bookmarkExtend from './bookmark'
13
13
  import commonExtend from './common'
14
- import contextMenuExtend from './context-menu'
15
14
  import itemExtend from './item'
16
15
  import quickCommandExtend from './quick-command'
17
16
  import sessionExtend from './session'
@@ -269,24 +268,6 @@ class Store {
269
268
  }
270
269
  }
271
270
 
272
- const arrGetterProps = [
273
- 'addressBookmarks',
274
- 'addressBookmarksLocal',
275
- 'bookmarks',
276
- 'bookmarkGroups',
277
- 'profiles',
278
- 'quickCommands',
279
- 'terminalThemes'
280
- ]
281
-
282
- for (const prop of arrGetterProps) {
283
- Object.defineProperty(Store.prototype, prop, {
284
- get: function () {
285
- return JSON.parse(window.store[`_${prop}`] || '[]').filter(d => d)
286
- }
287
- })
288
- }
289
-
290
271
  loadDataExtend(Store)
291
272
  eventExtend(Store)
292
273
  dbUpgradeExtend(Store)
@@ -295,7 +276,6 @@ appUpgradeExtend(Store)
295
276
  bookmarkGroupExtend(Store)
296
277
  bookmarkExtend(Store)
297
278
  commonExtend(Store)
298
- contextMenuExtend(Store)
299
279
  itemExtend(Store)
300
280
  quickCommandExtend(Store)
301
281
  sessionExtend(Store)
@@ -55,8 +55,7 @@ export default Store => {
55
55
  Store.prototype.onNewSsh = function () {
56
56
  const { store } = window
57
57
  store.storeAssign({
58
- settingTab: settingMap.bookmarks,
59
- autofocustrigger: Date.now()
58
+ settingTab: settingMap.bookmarks
60
59
  })
61
60
  store.setSettingItem(getInitItem([], settingMap.bookmarks))
62
61
  store.openSettingModal()
@@ -9,6 +9,7 @@ import {
9
9
  paneMap,
10
10
  maxHistory
11
11
  } from '../common/constants'
12
+ import { refs } from '../components/common/ref'
12
13
  import * as ls from '../common/safe-local-storage'
13
14
  import deepCopy from 'json-deep-copy'
14
15
  import generate from '../common/id-with-stamp'
@@ -449,10 +450,16 @@ export default Store => {
449
450
  }
450
451
 
451
452
  Store.prototype.updateHistory = function (tab) {
452
- if (!tab.type && !tab.host) {
453
+ if (
454
+ !tab.type &&
455
+ !tab.host
456
+ ) {
453
457
  return
454
458
  }
455
459
  const { store } = window
460
+ if (store.config.disableConnectionHistory) {
461
+ return
462
+ }
456
463
  const tabPropertiesExcludes = [
457
464
  'id',
458
465
  'from',
@@ -546,4 +553,25 @@ export default Store => {
546
553
  // Ensure at least the active tab is selected
547
554
  store._batchInputSelectedTabIds.add(store.activeTabId)
548
555
  })
556
+
557
+ Store.prototype.notifyTabOnData = function (tabId) {
558
+ const tab = refs.get('tab-' + tabId)
559
+ if (tab) {
560
+ tab.notifyOnData()
561
+ }
562
+ }
563
+
564
+ Store.prototype.remoteList = function (sessionId) {
565
+ const sftp = refs.get('sftp-' + sessionId)
566
+ if (sftp) {
567
+ sftp.remoteListDebounce()
568
+ }
569
+ }
570
+
571
+ Store.prototype.localList = function (sessionId) {
572
+ const sftp = refs.get('sftp-' + sessionId)
573
+ if (sftp) {
574
+ sftp.localListDebounce()
575
+ }
576
+ }
549
577
  }
@@ -19,10 +19,6 @@ export default Store => {
19
19
  return window.store.getItems(settingMap.terminalThemes)
20
20
  }
21
21
 
22
- Store.prototype.setTerminalThemes = function (arr) {
23
- return window.store.setItems(settingMap.terminalThemes, arr)
24
- }
25
-
26
22
  Store.prototype.setTheme = function (id) {
27
23
  window.store.updateConfig({
28
24
  theme: id
@@ -4,7 +4,7 @@
4
4
 
5
5
  import createTitle from '../common/create-title'
6
6
  import { autoRun } from 'manate'
7
- import { update, dbNamesForWatch } from '../common/db'
7
+ import { update, remove, dbNamesForWatch } from '../common/db'
8
8
  import {
9
9
  sftpDefaultSortSettingKey,
10
10
  checkedKeysLsKey,
@@ -15,6 +15,9 @@ import {
15
15
  } from '../common/constants'
16
16
  import * as ls from '../common/safe-local-storage'
17
17
  import { debounce, isEmpty } from 'lodash-es'
18
+ import deepCopy from 'json-deep-copy'
19
+ import { refsStatic } from '../components/common/ref'
20
+ import dataCompare from '../common/data-compare'
18
21
 
19
22
  export default store => {
20
23
  // autoRun(() => {
@@ -35,15 +38,34 @@ export default store => {
35
38
 
36
39
  for (const name of dbNamesForWatch) {
37
40
  autoRun(async () => {
41
+ const old = refsStatic.get('oldState-' + name)
42
+ const n = store.getItems(name)
43
+ const { updated, added, removed } = dataCompare(
44
+ old,
45
+ n
46
+ )
47
+ for (const item of removed) {
48
+ await remove(name, item.id)
49
+ }
50
+ for (const item of updated) {
51
+ await update(item.id, item, name, false)
52
+ }
53
+ store.batchDbAdd(added.map(d => {
54
+ return {
55
+ db: name,
56
+ obj: d
57
+ }
58
+ }))
38
59
  await update(
39
60
  `${name}:order`,
40
- store.getItems(name).map(d => d.id)
61
+ (n || []).map(d => d.id)
41
62
  )
63
+ refsStatic.add('oldState-' + name, deepCopy(n) || [])
42
64
  await store.updateLastDataUpdateTime()
43
65
  if (store.config.autoSync) {
44
66
  await store.uploadSettingAll()
45
67
  }
46
- return store['_' + name]
68
+ return store[name]
47
69
  }).start()
48
70
  }
49
71
 
@@ -90,7 +112,7 @@ export default store => {
90
112
 
91
113
  autoRun(() => {
92
114
  ls.setItemJSON(localAddrBookmarkLsKey, store.addressBookmarksLocal)
93
- return store._addressBookmarksLocal
115
+ return store.addressBookmarksLocal
94
116
  }).start()
95
117
 
96
118
  autoRun(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "1.60.18",
3
+ "version": "1.60.32",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",
@@ -1,3 +0,0 @@
1
- export default (msg) => {
2
- window.postMessage(msg, '*')
3
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * input with auto focus
3
- */
4
-
5
- import React from 'react'
6
- import './native-input.styl'
7
-
8
- export default function InputNative (props) {
9
- const { value, type, onChange, onPressEnter, addonAfter = null, ...rest } = props
10
- return (
11
- <span
12
- className='ant-input-group-wrapper'
13
- data-id={props['data-id']}
14
- >
15
- <span className='ant-input-wrapper ant-input-group'>
16
- <input
17
- class='ant-input native-input'
18
- type='text'
19
- value={value}
20
- onChange={onChange}
21
- onPressEnter={onPressEnter}
22
- {...rest}
23
- />
24
- </span>
25
- <span class='ant-input-group-addon'>
26
- {addonAfter}
27
- </span>
28
- </span>
29
- )
30
- }
@@ -1,339 +0,0 @@
1
- /**
2
- * context menu
3
- */
4
- import { PureComponent } from 'react'
5
- import './context-menu.styl'
6
- import classnames from 'classnames'
7
- import {
8
- contextMenuHeight,
9
- contextMenuPaddingTop,
10
- contextMenuWidth,
11
- commonActions
12
- } from '../../common/constants'
13
- import {
14
- Popconfirm
15
- } from 'antd'
16
- import postMessage from '../../common/post-msg'
17
- import { noop } from 'lodash-es'
18
- import History from './history'
19
- import Bookmark from './boomarks'
20
- import Tabs from './tabs'
21
- import Zoom from './zoom'
22
- import IconHolder from './icon-holder'
23
- import {
24
- CodeOutlined,
25
- BorderHorizontalOutlined,
26
- SearchOutlined,
27
- SelectOutlined,
28
- SwitcherOutlined,
29
- CheckOutlined,
30
- CloudDownloadOutlined,
31
- CloudUploadOutlined,
32
- ArrowRightOutlined,
33
- CheckSquareOutlined,
34
- CloseCircleOutlined,
35
- ContainerOutlined,
36
- CopyOutlined,
37
- EditOutlined,
38
- EnterOutlined,
39
- FileAddOutlined,
40
- FileExcelOutlined,
41
- FolderAddOutlined,
42
- InfoCircleOutlined,
43
- LockOutlined,
44
- ReloadOutlined
45
- } from '@ant-design/icons'
46
-
47
- const e = window.translate
48
-
49
- export default class ContextMenu extends PureComponent {
50
- state = {
51
- items: [],
52
- id: '',
53
- pos: {
54
- left: 0,
55
- top: 0
56
- },
57
- className: 'context-menu'
58
- }
59
-
60
- componentDidMount () {
61
- window.addEventListener('message', e => {
62
- const {
63
- type,
64
- data
65
- } = e.data || {}
66
- if (
67
- type === commonActions.closeContextMenu
68
- ) {
69
- this.closeContextMenu()
70
- } else if (type === commonActions.openContextMenu) {
71
- this.setOnCloseEvent()
72
- this.setState(data)
73
- }
74
- })
75
- }
76
-
77
- setOnCloseEvent = () => {
78
- const dom = document
79
- .querySelector('.ant-drawer')
80
- if (dom) {
81
- dom.addEventListener('click', this.onTriggerClose)
82
- }
83
- document
84
- .getElementById('outside-context')
85
- .addEventListener('click', this.onTriggerClose)
86
- }
87
-
88
- onTriggerClose = () => {
89
- this.closeContextMenu()
90
- const dom = document
91
- .querySelector('.ant-drawer')
92
- if (dom) {
93
- dom.removeEventListener('click', this.onTriggerClose)
94
- }
95
- document
96
- .getElementById('outside-context')
97
- .removeEventListener('click', this.onTriggerClose)
98
- }
99
-
100
- icons = {
101
- CodeOutlined,
102
- BorderHorizontalOutlined,
103
- SearchOutlined,
104
- SelectOutlined,
105
- SwitcherOutlined,
106
- IconHolder,
107
- CheckOutlined,
108
- CloudDownloadOutlined,
109
- CloudUploadOutlined,
110
- ArrowRightOutlined,
111
- CheckSquareOutlined,
112
- CloseCircleOutlined,
113
- ContainerOutlined,
114
- CopyOutlined,
115
- EditOutlined,
116
- EnterOutlined,
117
- FileAddOutlined,
118
- FileExcelOutlined,
119
- FolderAddOutlined,
120
- InfoCircleOutlined,
121
- LockOutlined,
122
- ReloadOutlined
123
- }
124
-
125
- modules = {
126
- History,
127
- Bookmark,
128
- Tabs,
129
- Zoom
130
- }
131
-
132
- closeContextMenu = () => {
133
- this.setState({
134
- id: '',
135
- items: []
136
- })
137
- postMessage({
138
- action: commonActions.closeContextMenuAfter
139
- })
140
- }
141
-
142
- computePos = () => {
143
- const {
144
- pos,
145
- items
146
- } = this.state
147
- const { length } = items
148
- const count = length
149
- ? items.filter(c => c.type !== 'hr').length
150
- : 3
151
- const countHr = length
152
- ? items.filter(c => c.type === 'hr').length
153
- : 3
154
- let {
155
- left,
156
- top
157
- } = pos
158
- const height = count * contextMenuHeight + contextMenuPaddingTop * 2 + countHr * 1
159
- const maxHeight = Math.max(
160
- window.innerHeight - top,
161
- top
162
- )
163
- const shouldScroll = maxHeight < height
164
- const startTop = top > window.innerHeight / 2
165
- const realHeight = Math.min(maxHeight, height)
166
- if (startTop) {
167
- top = top - realHeight
168
- }
169
- if (window.innerWidth < left + contextMenuWidth + 10) {
170
- left = left - contextMenuWidth
171
- }
172
- return {
173
- pos: {
174
- left: left + 'px',
175
- top: top + 'px',
176
- height: realHeight + 'px'
177
- },
178
- realHeight,
179
- shouldScroll
180
- }
181
- }
182
-
183
- onClick = (e, item) => {
184
- const {
185
- disabled,
186
- func,
187
- args,
188
- noCloseMenu
189
- } = item
190
- if (disabled) {
191
- return
192
- }
193
- postMessage({
194
- action: commonActions.clickContextMenu,
195
- id: this.state.id,
196
- args,
197
- func
198
- })
199
- if (!noCloseMenu) {
200
- this.closeContextMenu()
201
- }
202
- }
203
-
204
- renderSubText = (subText) => {
205
- return subText
206
- ? (<span className='context-sub-text'>{subText}</span>)
207
- : null
208
- }
209
-
210
- renderSubMenu = (submenu) => {
211
- if (!submenu) {
212
- return
213
- }
214
- const Mod = this.modules[submenu]
215
- return (
216
- <Mod {...this.props} />
217
- )
218
- }
219
-
220
- renderItem = (item, i) => {
221
- const {
222
- disabled,
223
- icon,
224
- text,
225
- noAutoClose,
226
- requireConfirm,
227
- confirmTitle,
228
- subText,
229
- className,
230
- type,
231
- module,
232
- submenu
233
- } = item
234
- if (type === 'hr') {
235
- return <hr />
236
- }
237
- const baseCls = 'context-item'
238
- if (module && this.modules[module]) {
239
- const Mod = this.modules[module]
240
- return (
241
- <div className={baseCls}>
242
- <Mod {...this.props} />
243
- </div>
244
- )
245
- }
246
- let iconElem = null
247
- if (icon && this.icons[icon]) {
248
- const Icon = this.icons[icon]
249
- iconElem = <Icon />
250
- }
251
- const cls = classnames(
252
- baseCls,
253
- {
254
- disabled
255
- },
256
- {
257
- 'no-auto-close-context': noAutoClose
258
- },
259
- className,
260
- {
261
- 'with-sub-menu': submenu
262
- }
263
- )
264
- const act = requireConfirm || submenu
265
- ? noop
266
- : (e) => this.onClick(e, item)
267
- const unit = (
268
- <div
269
- key={`context-item-${i}-${text}`}
270
- className={cls}
271
- onClick={act}
272
- >
273
- {iconElem}{iconElem ? ' ' : ''}{text}
274
- {
275
- this.renderSubText(subText)
276
- }
277
- {
278
- this.renderSubMenu(submenu)
279
- }
280
- </div>
281
- )
282
- if (!requireConfirm) {
283
- return unit
284
- }
285
- const title = (
286
- <div className='wordbreak'>{confirmTitle}</div>
287
- )
288
- return (
289
- <Popconfirm
290
- cancelText={e('cancel')}
291
- key={`context-item-${i}-${text}`}
292
- okText={e('ok')}
293
- title={title}
294
- onConfirm={(e) => this.onClick(e, item)}
295
- >
296
- {unit}
297
- </Popconfirm>
298
- )
299
- }
300
-
301
- renderItems = () => {
302
- return this.state.items.map(this.renderItem)
303
- }
304
-
305
- render () {
306
- const { id, className } = this.state
307
- if (!id) {
308
- return null
309
- }
310
- const {
311
- pos,
312
- shouldScroll,
313
- realHeight
314
- } = this.computePos()
315
- const cls = classnames(
316
- className,
317
- id ? 'show' : 'hide',
318
- shouldScroll ? 'scroll' : ''
319
- )
320
- const innerProps = {
321
- className: 'context-menu-inner',
322
- style: {
323
- height: (realHeight - contextMenuPaddingTop * 2) + 'px'
324
- }
325
- }
326
- return (
327
- <div
328
- className={cls}
329
- style={pos}
330
- >
331
- <div
332
- {...innerProps}
333
- >
334
- {this.renderItems()}
335
- </div>
336
- </div>
337
- )
338
- }
339
- }