@electerm/electerm-react 1.100.18 → 1.100.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.
@@ -68,5 +68,6 @@ export default {
68
68
  sshSftpSplitView: false,
69
69
  showCmdSuggestions: false,
70
70
  startDirectoryLocal: '',
71
- allowMultiInstance: false
71
+ allowMultiInstance: false,
72
+ disableDeveloperTool: false
72
73
  }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Get default color from current category or random color
3
+ */
4
+
5
+ import { getRandomDefaultColor } from './rand-hex-color.js'
6
+
7
+ export function getColorFromCategory (bookmarkGroups, currentBookmarkGroupId) {
8
+ if (!currentBookmarkGroupId || !bookmarkGroups) {
9
+ return getRandomDefaultColor()
10
+ }
11
+
12
+ const currentGroup = bookmarkGroups.find(group => group.id === currentBookmarkGroupId)
13
+
14
+ if (currentGroup && currentGroup.color) {
15
+ return currentGroup.color
16
+ }
17
+
18
+ return getRandomDefaultColor()
19
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Common bookmark category select component that automatically updates color when category changes
3
+ */
4
+
5
+ import { useEffect } from 'react'
6
+ import { TreeSelect, Form } from 'antd'
7
+ import formatBookmarkGroups from './bookmark-group-tree-format'
8
+
9
+ const FormItem = Form.Item
10
+ const e = window.translate
11
+
12
+ export default function BookmarkCategorySelect ({
13
+ bookmarkGroups = [],
14
+ form,
15
+ formItemLayout,
16
+ name = 'category',
17
+ onChange
18
+ }) {
19
+ const tree = formatBookmarkGroups(bookmarkGroups)
20
+
21
+ // Watch for category field changes using Form.useWatch
22
+ const categoryId = Form.useWatch(name, form)
23
+
24
+ // Find the selected category
25
+ const findCategory = (groups, id) => {
26
+ for (const group of groups) {
27
+ if (group.id === id) {
28
+ return group
29
+ }
30
+ if (group.bookmarkGroupTree && group.bookmarkGroupTree.length > 0) {
31
+ const found = findCategory(group.bookmarkGroupTree, id)
32
+ if (found) return found
33
+ }
34
+ }
35
+ return null
36
+ }
37
+
38
+ // Watch for category field changes and update color accordingly
39
+ useEffect(() => {
40
+ if (categoryId) {
41
+ const category = findCategory(bookmarkGroups, categoryId)
42
+ if (category && category.color) {
43
+ form.setFieldsValue({
44
+ color: category.color
45
+ })
46
+ }
47
+ }
48
+ }, [categoryId, bookmarkGroups, form])
49
+
50
+ const handleCategoryChange = (categoryId) => {
51
+ const category = findCategory(bookmarkGroups, categoryId)
52
+
53
+ // Only update the color field if the category has a color
54
+ if (category && category.color) {
55
+ form.setFieldsValue({
56
+ color: category.color
57
+ })
58
+ }
59
+
60
+ // Call the original onChange if provided
61
+ if (onChange) {
62
+ onChange(categoryId)
63
+ }
64
+ }
65
+
66
+ return (
67
+ <FormItem
68
+ {...formItemLayout}
69
+ label={e('bookmarkCategory')}
70
+ name={name}
71
+ >
72
+ <TreeSelect
73
+ treeData={tree}
74
+ treeDefaultExpandAll
75
+ showSearch
76
+ onChange={handleCategoryChange}
77
+ />
78
+ </FormItem>
79
+ )
80
+ }
@@ -5,7 +5,6 @@ import {
5
5
  Input,
6
6
  InputNumber,
7
7
  Radio,
8
- TreeSelect,
9
8
  Select,
10
9
  Form
11
10
  } from 'antd'
@@ -15,9 +14,9 @@ import {
15
14
  import { formItemLayout, tailFormItemLayout } from '../../common/form-layout'
16
15
  import InputAutoFocus from '../common/input-auto-focus'
17
16
  import encodes from './encodes'
18
- import formatBookmarkGroups from './bookmark-group-tree-format'
19
17
  import renderRunScripts from './render-delayed-scripts.jsx'
20
18
  import { ColorPickerItem } from './color-picker-item.jsx'
19
+ import BookmarkCategorySelect from './bookmark-category-select.jsx'
21
20
 
22
21
  import './bookmark-form.styl'
23
22
 
@@ -38,7 +37,6 @@ export default function renderCommon (props) {
38
37
  onChangeAuthType,
39
38
  filterAuthType = a => a
40
39
  } = props
41
- const tree = formatBookmarkGroups(bookmarkGroups)
42
40
  const authTypesFiltered = authTypes.filter(filterAuthType)
43
41
 
44
42
  // ips is ipaddress string[]
@@ -140,17 +138,11 @@ export default function renderCommon (props) {
140
138
  step={1}
141
139
  />
142
140
  </FormItem>
143
- <FormItem
144
- {...formItemLayout}
145
- label={e('bookmarkCategory')}
146
- name='category'
147
- >
148
- <TreeSelect
149
- treeData={tree}
150
- treeDefaultExpandAll
151
- showSearch
152
- />
153
- </FormItem>
141
+ <BookmarkCategorySelect
142
+ bookmarkGroups={bookmarkGroups}
143
+ form={form}
144
+ formItemLayout={formItemLayout}
145
+ />
154
146
  <FormItem
155
147
  {...formItemLayout}
156
148
  label={e('title')}
@@ -7,7 +7,6 @@ import {
7
7
  Input,
8
8
  Form,
9
9
  InputNumber,
10
- TreeSelect,
11
10
  Switch
12
11
  } from 'antd'
13
12
  import { formItemLayout } from '../../common/form-layout'
@@ -19,10 +18,10 @@ import useSubmit from './use-submit'
19
18
  import copy from 'json-deep-copy'
20
19
  import { defaults, isEmpty } from 'lodash-es'
21
20
  import { ColorPickerItem } from './color-picker-item.jsx'
22
- import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
23
- import formatBookmarkGroups from './bookmark-group-tree-format'
21
+ import { getColorFromCategory } from '../../common/get-category-color.js'
24
22
  import findBookmarkGroupId from '../../common/find-bookmark-group-id'
25
23
  import ProfileItem from './profile-form-item'
24
+ import BookmarkCategorySelect from './bookmark-category-select.jsx'
26
25
 
27
26
  const FormItem = Form.Item
28
27
  const e = window.translate
@@ -55,7 +54,7 @@ export default function FtpFormUi (props) {
55
54
  type: terminalFtpType,
56
55
  port: 21,
57
56
  category: initBookmarkGroupId,
58
- color: getRandomDefaultColor(),
57
+ color: getColorFromCategory(bookmarkGroups, currentBookmarkGroupId),
59
58
  user: '',
60
59
  password: '',
61
60
  secure: false
@@ -66,7 +65,6 @@ export default function FtpFormUi (props) {
66
65
  const {
67
66
  bookmarkGroups = []
68
67
  } = props
69
- const tree = formatBookmarkGroups(bookmarkGroups)
70
68
  return (
71
69
  <div className='pd1x'>
72
70
  <FormItem
@@ -131,17 +129,10 @@ export default function FtpFormUi (props) {
131
129
  >
132
130
  <Switch />
133
131
  </FormItem>
134
- <FormItem
135
- {...formItemLayout}
136
- label={e('bookmarkCategory')}
137
- name='category'
138
- >
139
- <TreeSelect
140
- treeData={tree}
141
- treeDefaultExpandAll
142
- showSearch
143
- />
144
- </FormItem>
132
+ <BookmarkCategorySelect
133
+ bookmarkGroups={bookmarkGroups}
134
+ form={form}
135
+ />
145
136
  <FormItem
146
137
  {...formItemLayout}
147
138
  label='type'
@@ -6,7 +6,6 @@ import { useEffect } from 'react'
6
6
  import {
7
7
  Tabs,
8
8
  Input,
9
- TreeSelect,
10
9
  Form
11
10
  } from 'antd'
12
11
  import { formItemLayout } from '../../common/form-layout'
@@ -14,7 +13,6 @@ import {
14
13
  newBookmarkIdPrefix,
15
14
  terminalLocalType
16
15
  } from '../../common/constants'
17
- import formatBookmarkGroups from './bookmark-group-tree-format'
18
16
  import findBookmarkGroupId from '../../common/find-bookmark-group-id'
19
17
  import useSubmit from './use-submit'
20
18
  import useUI from './use-ui'
@@ -24,7 +22,8 @@ import renderTermBg from './render-bg'
24
22
  import { defaults } from 'lodash-es'
25
23
  import renderRunScripts from './render-delayed-scripts.jsx'
26
24
  import { ColorPickerItem } from './color-picker-item.jsx'
27
- import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
25
+ import { getColorFromCategory } from '../../common/get-category-color.js'
26
+ import BookmarkCategorySelect from './bookmark-category-select.jsx'
28
27
 
29
28
  const FormItem = Form.Item
30
29
  const e = window.translate
@@ -60,7 +59,7 @@ export default function LocalFormUi (props) {
60
59
  term: props.store.config.terminalType,
61
60
  displayRaw: false,
62
61
  type: terminalLocalType,
63
- color: getRandomDefaultColor(),
62
+ color: getColorFromCategory(bookmarkGroups, currentBookmarkGroupId),
64
63
  runScripts: [{}],
65
64
  enableSsh: true
66
65
  }
@@ -69,7 +68,6 @@ export default function LocalFormUi (props) {
69
68
  const {
70
69
  bookmarkGroups = []
71
70
  } = props
72
- const tree = formatBookmarkGroups(bookmarkGroups)
73
71
  return (
74
72
  <div className='pd1x'>
75
73
  {renderRunScripts()}
@@ -90,17 +88,10 @@ export default function LocalFormUi (props) {
90
88
  >
91
89
  <Input.TextArea autoSize={{ minRows: 1 }} />
92
90
  </FormItem>
93
- <FormItem
94
- {...formItemLayout}
95
- label={e('bookmarkCategory')}
96
- name='category'
97
- >
98
- <TreeSelect
99
- treeData={tree}
100
- treeDefaultExpandAll
101
- showSearch
102
- />
103
- </FormItem>
91
+ <BookmarkCategorySelect
92
+ bookmarkGroups={bookmarkGroups}
93
+ form={form}
94
+ />
104
95
  <FormItem
105
96
  {...formItemLayout}
106
97
  label='type'
@@ -7,7 +7,6 @@ import {
7
7
  Input,
8
8
  Form,
9
9
  InputNumber,
10
- TreeSelect,
11
10
  Alert
12
11
  } from 'antd'
13
12
  import { formItemLayout } from '../../common/form-layout'
@@ -20,11 +19,11 @@ import useSubmit from './use-submit'
20
19
  import copy from 'json-deep-copy'
21
20
  import { defaults, isEmpty } from 'lodash-es'
22
21
  import { ColorPickerItem } from './color-picker-item.jsx'
23
- import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
24
- import formatBookmarkGroups from './bookmark-group-tree-format'
22
+ import { getColorFromCategory } from '../../common/get-category-color.js'
25
23
  import findBookmarkGroupId from '../../common/find-bookmark-group-id'
26
24
  import ProfileItem from './profile-form-item'
27
25
  import Link from '../common/external-link'
26
+ import BookmarkCategorySelect from './bookmark-category-select.jsx'
28
27
 
29
28
  const FormItem = Form.Item
30
29
  const e = window.translate
@@ -57,7 +56,7 @@ export default function RdpFormUi (props) {
57
56
  type: terminalRdpType,
58
57
  port: 3389,
59
58
  category: initBookmarkGroupId,
60
- color: getRandomDefaultColor()
59
+ color: getColorFromCategory(bookmarkGroups, currentBookmarkGroupId)
61
60
 
62
61
  }
63
62
  initialValues = defaults(initialValues, defaultValues)
@@ -65,7 +64,6 @@ export default function RdpFormUi (props) {
65
64
  const {
66
65
  bookmarkGroups = []
67
66
  } = props
68
- const tree = formatBookmarkGroups(bookmarkGroups)
69
67
  const alertProps = {
70
68
  message: (
71
69
  <Link to={rdpWikiLink}>WIKI: {rdpWikiLink}</Link>
@@ -150,17 +148,10 @@ export default function RdpFormUi (props) {
150
148
  >
151
149
  <Input />
152
150
  </FormItem>
153
- <FormItem
154
- {...formItemLayout}
155
- label={e('bookmarkCategory')}
156
- name='category'
157
- >
158
- <TreeSelect
159
- treeData={tree}
160
- treeDefaultExpandAll
161
- showSearch
162
- />
163
- </FormItem>
151
+ <BookmarkCategorySelect
152
+ bookmarkGroups={bookmarkGroups}
153
+ form={form}
154
+ />
164
155
  <FormItem
165
156
  {...formItemLayout}
166
157
  label='type'
@@ -11,8 +11,7 @@ import {
11
11
  Select,
12
12
  Switch,
13
13
  AutoComplete,
14
- Form,
15
- TreeSelect
14
+ Form
16
15
  } from 'antd'
17
16
  import { formItemLayout } from '../../common/form-layout'
18
17
  import parseInt10 from '../../common/parse-int10'
@@ -24,7 +23,6 @@ import {
24
23
  terminalSerialType,
25
24
  newBookmarkIdPrefix
26
25
  } from '../../common/constants'
27
- import formatBookmarkGroups from './bookmark-group-tree-format'
28
26
  import defaultSettings from '../../common/default-setting'
29
27
  import findBookmarkGroupId from '../../common/find-bookmark-group-id'
30
28
  import useSubmit from './use-submit'
@@ -33,8 +31,9 @@ import useQm from './use-quick-commands'
33
31
  import copy from 'json-deep-copy'
34
32
  import renderTermBg from './render-bg'
35
33
  import { defaults } from 'lodash-es'
36
- import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
34
+ import { getColorFromCategory } from '../../common/get-category-color.js'
37
35
  import { ColorPickerItem } from './color-picker-item.jsx'
36
+ import BookmarkCategorySelect from './bookmark-category-select.jsx'
38
37
 
39
38
  const FormItem = Form.Item
40
39
  const { Option } = Select
@@ -67,7 +66,7 @@ export default function SerialFormUi (props) {
67
66
  : currentBookmarkGroupId
68
67
  let initialValues = copy(props.formData)
69
68
  const defaultValues = {
70
- color: getRandomDefaultColor(),
69
+ color: getColorFromCategory(bookmarkGroups, currentBookmarkGroupId),
71
70
  baudRate: 9600,
72
71
  dataBits: 8,
73
72
  lock: true,
@@ -91,7 +90,6 @@ export default function SerialFormUi (props) {
91
90
  serials = [],
92
91
  loaddingSerials
93
92
  } = props
94
- const tree = formatBookmarkGroups(bookmarkGroups)
95
93
  return (
96
94
  <div className='pd1x'>
97
95
  <FormItem
@@ -257,17 +255,11 @@ export default function SerialFormUi (props) {
257
255
  >
258
256
  <Input />
259
257
  </FormItem>
260
- <FormItem
261
- {...formItemLayout}
262
- label={e('bookmarkCategory')}
263
- name='category'
264
- >
265
- <TreeSelect
266
- treeData={tree}
267
- treeDefaultExpandAll
268
- showSearch
269
- />
270
- </FormItem>
258
+ <BookmarkCategorySelect
259
+ bookmarkGroups={bookmarkGroups}
260
+ form={form}
261
+ formItemLayout={formItemLayout}
262
+ />
271
263
  </div>
272
264
  )
273
265
  }
@@ -26,7 +26,7 @@ import renderAuth from './render-auth-ssh'
26
26
  import renderTermBg from './render-bg'
27
27
  import renderSshTunnel from './render-ssh-tunnel'
28
28
  import renderConnectionHopping from './render-connection-hopping'
29
- import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
29
+ import { getColorFromCategory } from '../../common/get-category-color.js'
30
30
  import defaultSetting from '../../common/default-setting'
31
31
  import './bookmark-form.styl'
32
32
 
@@ -61,7 +61,7 @@ export default function BookmarkFormUI (props) {
61
61
  port: 22,
62
62
  authType: authTypeMap.password,
63
63
  id: '',
64
- color: getRandomDefaultColor(),
64
+ color: getColorFromCategory(bookmarkGroups, currentBookmarkGroupId),
65
65
  term: props.store.config.terminalType,
66
66
  displayRaw: false,
67
67
  encode: encodes[0],
@@ -21,7 +21,7 @@ import useUI from './use-ui'
21
21
  import useQm from './use-quick-commands'
22
22
  import renderCommon from './form-ssh-common'
23
23
  import renderTermBg from './render-bg'
24
- import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
24
+ import { getColorFromCategory } from '../../common/get-category-color.js'
25
25
  import copy from 'json-deep-copy'
26
26
  import { defaultsDeep, isEmpty } from 'lodash-es'
27
27
  import renderAuth from './render-auth-ssh'
@@ -65,7 +65,7 @@ export default function TelnetFormUI (props) {
65
65
  id: '',
66
66
  username: 'root',
67
67
  password: 'guest',
68
- color: getRandomDefaultColor(),
68
+ color: getColorFromCategory(bookmarkGroups, currentBookmarkGroupId),
69
69
  runScripts: [{}],
70
70
  term: defaultSettings.terminalType,
71
71
  displayRaw: false,
@@ -7,7 +7,6 @@ import {
7
7
  Input,
8
8
  Form,
9
9
  InputNumber,
10
- TreeSelect,
11
10
  Switch,
12
11
  Tabs
13
12
  } from 'antd'
@@ -20,12 +19,12 @@ import useSubmit from './use-submit'
20
19
  import copy from 'json-deep-copy'
21
20
  import { defaults, isEmpty } from 'lodash-es'
22
21
  import { ColorPickerItem } from './color-picker-item.jsx'
23
- import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
24
- import formatBookmarkGroups from './bookmark-group-tree-format'
22
+ import { getColorFromCategory } from '../../common/get-category-color.js'
25
23
  import findBookmarkGroupId from '../../common/find-bookmark-group-id'
26
24
  import renderProxy from './proxy'
27
25
  import ConnectionHopping from './render-connection-hopping.jsx'
28
26
  import ProfileItem from './profile-form-item'
27
+ import BookmarkCategorySelect from './bookmark-category-select.jsx'
29
28
 
30
29
  const FormItem = Form.Item
31
30
  const e = window.translate
@@ -58,7 +57,7 @@ export default function VncFormUi (props) {
58
57
  type: terminalVncType,
59
58
  port: 5900,
60
59
  category: initBookmarkGroupId,
61
- color: getRandomDefaultColor(),
60
+ color: getColorFromCategory(bookmarkGroups, currentBookmarkGroupId),
62
61
  viewOnly: false,
63
62
  scaleViewport: true,
64
63
  connectionHoppings: []
@@ -100,7 +99,6 @@ export default function VncFormUi (props) {
100
99
  const {
101
100
  bookmarkGroups = []
102
101
  } = props
103
- const tree = formatBookmarkGroups(bookmarkGroups)
104
102
  return (
105
103
  <div className='pd1x'>
106
104
  <FormItem
@@ -181,17 +179,10 @@ export default function VncFormUi (props) {
181
179
  >
182
180
  <Input.TextArea autoSize={{ minRows: 1 }} />
183
181
  </FormItem>
184
- <FormItem
185
- {...formItemLayout}
186
- label={e('bookmarkCategory')}
187
- name='category'
188
- >
189
- <TreeSelect
190
- treeData={tree}
191
- treeDefaultExpandAll
192
- showSearch
193
- />
194
- </FormItem>
182
+ <BookmarkCategorySelect
183
+ bookmarkGroups={bookmarkGroups}
184
+ form={form}
185
+ />
195
186
  {
196
187
  renderProxy(props)
197
188
  }
@@ -6,7 +6,6 @@ import { useEffect } from 'react'
6
6
  import {
7
7
  Input,
8
8
  Form,
9
- TreeSelect,
10
9
  Switch
11
10
  } from 'antd'
12
11
  import { formItemLayout } from '../../common/form-layout'
@@ -18,9 +17,9 @@ import useSubmit from './use-submit'
18
17
  import copy from 'json-deep-copy'
19
18
  import { defaults } from 'lodash-es'
20
19
  import { ColorPickerItem } from './color-picker-item.jsx'
21
- import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
22
- import formatBookmarkGroups from './bookmark-group-tree-format'
20
+ import { getColorFromCategory } from '../../common/get-category-color.js'
23
21
  import findBookmarkGroupId from '../../common/find-bookmark-group-id'
22
+ import BookmarkCategorySelect from './bookmark-category-select.jsx'
24
23
 
25
24
  const FormItem = Form.Item
26
25
  const e = window.translate
@@ -52,14 +51,13 @@ export default function LocalFormUi (props) {
52
51
  const defaultValues = {
53
52
  type: terminalWebType,
54
53
  category: initBookmarkGroupId,
55
- color: getRandomDefaultColor()
54
+ color: getColorFromCategory(bookmarkGroups, currentBookmarkGroupId)
56
55
  }
57
56
  initialValues = defaults(initialValues, defaultValues)
58
57
  function renderCommon () {
59
58
  const {
60
59
  bookmarkGroups = []
61
60
  } = props
62
- const tree = formatBookmarkGroups(bookmarkGroups)
63
61
  return (
64
62
  <div className='pd1x'>
65
63
  <FormItem
@@ -100,17 +98,10 @@ export default function LocalFormUi (props) {
100
98
  >
101
99
  <Input.TextArea autoSize={{ minRows: 1 }} />
102
100
  </FormItem>
103
- <FormItem
104
- {...formItemLayout}
105
- label={e('bookmarkCategory')}
106
- name='category'
107
- >
108
- <TreeSelect
109
- treeData={tree}
110
- treeDefaultExpandAll
111
- showSearch
112
- />
113
- </FormItem>
101
+ <BookmarkCategorySelect
102
+ bookmarkGroups={bookmarkGroups}
103
+ form={form}
104
+ />
114
105
  <FormItem
115
106
  {...formItemLayout}
116
107
  label={e('useragent')}
@@ -145,9 +145,19 @@ export default class QuickCommandsList extends List {
145
145
  const f = keyword
146
146
  ? list.filter((item) => {
147
147
  const n = (item.name || '').toLowerCase()
148
- const c = (item.command || '').toLowerCase()
149
148
  const k = keyword.toLowerCase()
150
- return n.includes(k) || c.includes(k)
149
+
150
+ // Check if item has commands array
151
+ if (item.commands && Array.isArray(item.commands)) {
152
+ // Search in each command in the commands array
153
+ return n.includes(k) || item.commands.some(cmd =>
154
+ (cmd.command || '').toLowerCase().includes(k)
155
+ )
156
+ } else {
157
+ // Fallback to the old behavior for backward compatibility
158
+ const c = (item.command || '').toLowerCase()
159
+ return n.includes(k) || c.includes(k)
160
+ }
151
161
  })
152
162
  : list
153
163
  return labels.length
@@ -670,6 +670,7 @@ export default class SettingCommon extends Component {
670
670
  'confirmBeforeExit',
671
671
  'hideIP',
672
672
  'allowMultiInstance',
673
+ 'disableDeveloperTool',
673
674
  'debug'
674
675
  ].map(this.renderToggle)
675
676
  }
@@ -46,8 +46,8 @@ export const getLocalFileInfo = async (filePath) => {
46
46
  const stat = await fs.lstatAsync(filePath)
47
47
  return {
48
48
  size: stat.size,
49
- accessTime: stat.atime,
50
- modifyTime: stat.mtime,
49
+ accessTime: stat.atime || stat.atimeMs,
50
+ modifyTime: stat.mtime || stat.mtimeMs,
51
51
  mode: stat.mode,
52
52
  owner: stat.uid,
53
53
  group: stat.gid,
@@ -526,9 +526,14 @@ export default class Sftp extends Component {
526
526
  if (updates.remotePath !== undefined) {
527
527
  updates.remoteKeyword = ''
528
528
  }
529
+
530
+ // For selectedFiles updates, call setState immediately for better responsiveness
531
+ if (updates.selectedFiles !== undefined) {
532
+ return this.setState(...args)
533
+ }
529
534
  }
530
535
 
531
- // Call setState with the modified arguments
536
+ // For other updates, use runIdle to avoid blocking the UI
532
537
  runIdle(() => this.setState(...args))
533
538
  }
534
539
 
@@ -151,7 +151,7 @@ class Term extends Component {
151
151
  this.attachAddon._sendData(PS1_SETUP_CMD)
152
152
  this.term.cwdId = cwdId
153
153
  } else {
154
- log.warn('Term or attachAddon not ready for PS1_SETUP_CMD in componentDidUpdate')
154
+ console.warn('Term or attachAddon not ready for PS1_SETUP_CMD in componentDidUpdate')
155
155
  }
156
156
  } else {
157
157
  if (this.attachAddon) {
@@ -895,7 +895,7 @@ class Term extends Component {
895
895
  if (this.attachAddon) {
896
896
  this.attachAddon._sendData(PS1_SETUP_CMD)
897
897
  } else {
898
- log.warn('attachAddon not ready for PS1_SETUP_CMD in getCwd fallback')
898
+ console.warn('attachAddon not ready for PS1_SETUP_CMD in getCwd fallback')
899
899
  }
900
900
  }
901
901
  }
@@ -1065,7 +1065,7 @@ class Term extends Component {
1065
1065
  const cmd = `cd "${startFolder}"\r`
1066
1066
  this.attachAddon._sendData(cmd)
1067
1067
  } else {
1068
- log.warn('attachAddon not ready for cd command in runInitScript')
1068
+ console.warn('attachAddon not ready for cd command in runInitScript')
1069
1069
  }
1070
1070
  }
1071
1071
 
@@ -1074,7 +1074,7 @@ class Term extends Component {
1074
1074
  this.attachAddon._sendData(PS1_SETUP_CMD)
1075
1075
  this.term.cwdId = cwdId
1076
1076
  } else {
1077
- log.warn('Term or attachAddon not ready for PS1_SETUP_CMD in runInitScript')
1077
+ console.warn('Term or attachAddon not ready for PS1_SETUP_CMD in runInitScript')
1078
1078
  }
1079
1079
  }
1080
1080
 
@@ -0,0 +1,11 @@
1
+ import React from 'react'
2
+ import { ColorPicker } from '../bookmark-form/color-picker.jsx'
3
+
4
+ export function CategoryColorPicker ({ value, onChange }) {
5
+ return (
6
+ <ColorPicker
7
+ value={value}
8
+ onChange={onChange}
9
+ />
10
+ )
11
+ }
@@ -195,6 +195,16 @@ export default function TreeListItem (props) {
195
195
  }
196
196
  )
197
197
  const tag = isGroup ? '' : createTitleTag(item)
198
+ const colorTag = isGroup && item.color
199
+ ? (
200
+ <span
201
+ className='category-color-tag'
202
+ style={{
203
+ backgroundColor: item.color
204
+ }}
205
+ />
206
+ )
207
+ : null
198
208
  const title = isGroup
199
209
  ? item.title
200
210
  : createName(item)
@@ -236,7 +246,7 @@ export default function TreeListItem (props) {
236
246
  <div
237
247
  {...titleProps}
238
248
  >
239
- {tag}{titleHighlight}
249
+ {colorTag}{tag}{titleHighlight}
240
250
  </div>
241
251
  {
242
252
  isGroup
@@ -28,6 +28,8 @@ import TreeExpander from './tree-expander'
28
28
  import TreeListItem from './tree-list-item'
29
29
  import TreeSearch from './tree-search'
30
30
  import MoveItemModal from './move-item-modal'
31
+ import { CategoryColorPicker } from './category-color-picker.jsx'
32
+ import { getRandomDefaultColor } from '../../common/rand-hex-color.js'
31
33
 
32
34
  export default class ItemListTree extends Component {
33
35
  constructor (props) {
@@ -41,7 +43,9 @@ export default class ItemListTree extends Component {
41
43
  moveItem: null,
42
44
  moveItemIsGroup: false,
43
45
  bookmarkGroupTitle: '',
46
+ bookmarkGroupColor: '',
44
47
  categoryTitle: '',
48
+ categoryColor: '',
45
49
  categoryId: ''
46
50
  }
47
51
  }
@@ -110,7 +114,8 @@ export default class ItemListTree extends Component {
110
114
  handleCancelNew = () => {
111
115
  this.setState({
112
116
  showNewBookmarkGroupForm: false,
113
- bookmarkGroupTitle: ''
117
+ bookmarkGroupTitle: '',
118
+ bookmarkGroupColor: ''
114
119
  })
115
120
  }
116
121
 
@@ -123,7 +128,8 @@ export default class ItemListTree extends Component {
123
128
  handleCancelEdit = () => {
124
129
  this.setState({
125
130
  categoryId: '',
126
- categoryTitle: ''
131
+ categoryTitle: '',
132
+ categoryColor: ''
127
133
  })
128
134
  }
129
135
 
@@ -140,6 +146,7 @@ export default class ItemListTree extends Component {
140
146
  handleSubmitEdit = () => {
141
147
  const {
142
148
  categoryTitle,
149
+ categoryColor,
143
150
  categoryId
144
151
  } = this.state
145
152
  if (!categoryTitle) {
@@ -153,6 +160,9 @@ export default class ItemListTree extends Component {
153
160
  return this.handleCancelEdit()
154
161
  }
155
162
  obj.title = categoryTitle
163
+ if (categoryColor) {
164
+ obj.color = categoryColor
165
+ }
156
166
  this.setState({
157
167
  categoryId: ''
158
168
  })
@@ -181,6 +191,18 @@ export default class ItemListTree extends Component {
181
191
  })
182
192
  }
183
193
 
194
+ handleChangeBookmarkGroupColor = color => {
195
+ this.setState({
196
+ bookmarkGroupColor: color
197
+ })
198
+ }
199
+
200
+ handleChangeCategoryColor = color => {
201
+ this.setState({
202
+ categoryColor: color
203
+ })
204
+ }
205
+
184
206
  handleNewBookmark = () => {
185
207
  this.props.onClickItem(getInitItem([], settingMap.bookmarks))
186
208
  }
@@ -197,11 +219,15 @@ export default class ItemListTree extends Component {
197
219
  showNewBookmarkGroupForm: false
198
220
  }, () => {
199
221
  this.onSubmit = false
200
- window.store.addBookmarkGroup({
222
+ const newGroup = {
201
223
  id: uid(),
202
224
  title: this.state.bookmarkGroupTitle,
203
225
  bookmarkIds: []
204
- })
226
+ }
227
+ if (this.state.bookmarkGroupColor) {
228
+ newGroup.color = this.state.bookmarkGroupColor
229
+ }
230
+ window.store.addBookmarkGroup(newGroup)
205
231
  })
206
232
  }
207
233
 
@@ -227,6 +253,9 @@ export default class ItemListTree extends Component {
227
253
  level: 2,
228
254
  bookmarkIds: []
229
255
  }
256
+ if (this.state.bookmarkGroupColor) {
257
+ newCat.color = this.state.bookmarkGroupColor
258
+ }
230
259
  bookmarkGroups.unshift(newCat)
231
260
  const cat = bookmarkGroups.find(
232
261
  d => d.id === id
@@ -244,6 +273,7 @@ export default class ItemListTree extends Component {
244
273
  this.setState({
245
274
  showNewBookmarkGroupForm: true,
246
275
  bookmarkGroupTitle: '',
276
+ bookmarkGroupColor: getRandomDefaultColor(),
247
277
  parentId: ''
248
278
  })
249
279
  }
@@ -309,6 +339,7 @@ export default class ItemListTree extends Component {
309
339
  if (isGroup) {
310
340
  this.setState({
311
341
  categoryTitle: '' + item.title,
342
+ categoryColor: item.color || '',
312
343
  categoryId: item.id,
313
344
  bookmarkGroupSubParentId: ''
314
345
  })
@@ -322,7 +353,8 @@ export default class ItemListTree extends Component {
322
353
  return {
323
354
  showNewBookmarkGroupForm: true,
324
355
  parentId: item.id,
325
- bookmarkGroupTitle: ''
356
+ bookmarkGroupTitle: '',
357
+ bookmarkGroupColor: ''
326
358
  }
327
359
  })
328
360
  window.store.expandedKeys.push(item.id)
@@ -519,7 +551,8 @@ export default class ItemListTree extends Component {
519
551
 
520
552
  editCategory = () => {
521
553
  const {
522
- categoryTitle
554
+ categoryTitle,
555
+ categoryColor
523
556
  } = this.state
524
557
  const confirm = (
525
558
  <span>
@@ -527,11 +560,18 @@ export default class ItemListTree extends Component {
527
560
  <CloseOutlined className='mg1l pointer' onClick={this.handleCancelEdit} />
528
561
  </span>
529
562
  )
563
+ const colorPicker = (
564
+ <CategoryColorPicker
565
+ value={categoryColor || getRandomDefaultColor()}
566
+ onChange={this.handleChangeCategoryColor}
567
+ />
568
+ )
530
569
  return (
531
570
  <InputAutoFocus
532
571
  value={categoryTitle}
533
572
  onChange={this.handleChangeEdit}
534
573
  onPressEnter={this.handleSubmitEdit}
574
+ addonBefore={colorPicker}
535
575
  addonAfter={confirm}
536
576
  />
537
577
  )
@@ -693,6 +733,7 @@ export default class ItemListTree extends Component {
693
733
  renderNewCat = (group) => {
694
734
  const {
695
735
  bookmarkGroupTitle,
736
+ bookmarkGroupColor,
696
737
  parentId,
697
738
  showNewBookmarkGroupForm
698
739
  } = this.state
@@ -705,12 +746,19 @@ export default class ItemListTree extends Component {
705
746
  <CloseOutlined className='mg1l pointer' onClick={this.handleCancelNew} />
706
747
  </span>
707
748
  )
749
+ const colorPicker = (
750
+ <CategoryColorPicker
751
+ value={bookmarkGroupColor || getRandomDefaultColor()}
752
+ onChange={this.handleChangeBookmarkGroupColor}
753
+ />
754
+ )
708
755
  return (
709
756
  <div className='pd1y'>
710
757
  <InputAutoFocus
711
758
  value={bookmarkGroupTitle}
712
759
  onPressEnter={this.handleSubmit}
713
760
  onChange={this.handleChangeBookmarkGroupTitle}
761
+ addonBefore={colorPicker}
714
762
  addonAfter={confirm}
715
763
  onBlur={this.handleBlurBookmarkGroupTitle}
716
764
  />
@@ -67,4 +67,13 @@
67
67
  top 0
68
68
  width 12px
69
69
  font-size 11px
70
- line-height 30px
70
+ line-height 30px
71
+
72
+ .category-color-tag
73
+ display inline-block
74
+ width 12px
75
+ height 12px
76
+ margin-right 6px
77
+ border-radius 2px
78
+ border 1px solid rgba(0,0,0,0.1)
79
+ vertical-align middle
@@ -81,17 +81,22 @@ export async function addTabFromCommandLine (store, opts) {
81
81
  const opts = safeParse(options.opts)
82
82
  if (opts !== options.opts) {
83
83
  Object.assign(update, opts)
84
+ update.fromCmdLine = true
84
85
  }
85
86
  }
86
- if (options.type) {
87
- update.type = options.type
87
+ if (options.tp) {
88
+ update.type = options.tp
89
+ update.fromCmdLine = true
88
90
  }
89
91
  Object.assign(conf, update)
90
92
  if (options.privateKeyPath) {
91
93
  conf.privateKey = await fs.readFile(options.privateKeyPath)
92
94
  }
93
95
  log.debug('command line opts', conf)
94
- if (conf.username && conf.host) {
96
+ if (
97
+ (conf.username && conf.host) ||
98
+ conf.fromCmdLine
99
+ ) {
95
100
  store.addTab(conf)
96
101
  } else if (
97
102
  options.initFolder &&
@@ -514,7 +514,8 @@ export default (Store) => {
514
514
  'modelAI',
515
515
  'roleAI',
516
516
  'languageAI',
517
- 'proxyAI'
517
+ 'proxyAI',
518
+ 'disableDeveloperTool'
518
519
  ]
519
520
  return pick(store.config, configSyncKeys)
520
521
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "1.100.18",
3
+ "version": "1.100.30",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",