@electerm/electerm-react 1.60.36 → 1.60.48
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.
- package/client/common/data-compare.js +6 -3
- package/client/common/default-setting.js +3 -2
- package/client/components/ai/ai-chat.jsx +3 -1
- package/client/components/ai/ai-config.jsx +47 -17
- package/client/components/common/input-auto-focus.jsx +7 -3
- package/client/components/setting-panel/setting-terminal.jsx +1 -1
- package/client/store/common.js +1 -1
- package/client/store/load-data.js +7 -3
- package/package.json +1 -1
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* @param {Array} newArr - New array of objects to compare against
|
|
5
5
|
* @returns {Object} Object containing arrays of items to update, add, and remove
|
|
6
6
|
*/
|
|
7
|
+
|
|
8
|
+
import deepCopy from 'json-deep-copy'
|
|
9
|
+
|
|
7
10
|
export default function compare (oldArr, newArr) {
|
|
8
11
|
if (!oldArr || !newArr) {
|
|
9
12
|
return {
|
|
@@ -48,8 +51,8 @@ export default function compare (oldArr, newArr) {
|
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
return {
|
|
51
|
-
updated,
|
|
52
|
-
added,
|
|
53
|
-
removed
|
|
54
|
+
updated: deepCopy(updated),
|
|
55
|
+
added: deepCopy(added),
|
|
56
|
+
removed: deepCopy(removed)
|
|
54
57
|
}
|
|
55
58
|
}
|
|
@@ -31,7 +31,7 @@ export default {
|
|
|
31
31
|
checkUpdateOnStart: true,
|
|
32
32
|
cursorBlink: false,
|
|
33
33
|
cursorStyle: 'block',
|
|
34
|
-
useSystemTitleBar:
|
|
34
|
+
useSystemTitleBar: false,
|
|
35
35
|
opacity: 1,
|
|
36
36
|
defaultEditor: '',
|
|
37
37
|
terminalWordSeparator: './\\()"\'-:,.;<>~!@#$%^&*|+=[]{}`~ ?',
|
|
@@ -61,5 +61,6 @@ export default {
|
|
|
61
61
|
dataSyncSelected: 'all',
|
|
62
62
|
baseURLAI: 'https://api.deepseek.com',
|
|
63
63
|
modelAI: 'deepseek-chat',
|
|
64
|
-
roleAI: '终端专家,提供不同系统下安全命令,解释用法及风险,用markdown格式'
|
|
64
|
+
roleAI: '终端专家,提供不同系统下安全命令,解释用法及风险,用markdown格式',
|
|
65
|
+
apiPathAI: '/chat/completions'
|
|
65
66
|
}
|
|
@@ -24,7 +24,8 @@ const aiConfigsArr = [
|
|
|
24
24
|
'baseURLAI',
|
|
25
25
|
'modelAI',
|
|
26
26
|
'roleAI',
|
|
27
|
-
'apiKeyAI'
|
|
27
|
+
'apiKeyAI',
|
|
28
|
+
'apiPathAI'
|
|
28
29
|
]
|
|
29
30
|
|
|
30
31
|
export default function AIChat (props) {
|
|
@@ -52,6 +53,7 @@ export default function AIChat (props) {
|
|
|
52
53
|
props.config.modelAI,
|
|
53
54
|
buildRole(),
|
|
54
55
|
props.config.baseURLAI,
|
|
56
|
+
props.config.apiPathAI,
|
|
55
57
|
props.config.apiKeyAI
|
|
56
58
|
).catch(
|
|
57
59
|
window.store.onError
|
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
Button,
|
|
5
5
|
AutoComplete,
|
|
6
6
|
Modal,
|
|
7
|
-
Alert
|
|
7
|
+
Alert,
|
|
8
|
+
Space
|
|
8
9
|
} from 'antd'
|
|
9
10
|
import { useEffect, useState } from 'react'
|
|
10
11
|
import Link from '../common/external-link'
|
|
@@ -76,12 +77,14 @@ export default function AIConfigForm ({ initialValues, onSubmit, showAIConfig })
|
|
|
76
77
|
return null
|
|
77
78
|
}
|
|
78
79
|
const title = 'AI ' + e('setting')
|
|
80
|
+
const defaultLangs = window.store.getLangNames().map(l => ({ value: l }))
|
|
79
81
|
return (
|
|
80
82
|
<Modal
|
|
81
83
|
title={title}
|
|
82
84
|
open
|
|
83
85
|
onCancel={handleCancel}
|
|
84
86
|
footer={null}
|
|
87
|
+
width='90%'
|
|
85
88
|
>
|
|
86
89
|
<Alert
|
|
87
90
|
message={
|
|
@@ -96,23 +99,38 @@ export default function AIConfigForm ({ initialValues, onSubmit, showAIConfig })
|
|
|
96
99
|
initialValues={initialValues}
|
|
97
100
|
layout='vertical'
|
|
98
101
|
>
|
|
99
|
-
<Form.Item
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
102
|
+
<Form.Item label='API URL' required>
|
|
103
|
+
<Space.Compact block>
|
|
104
|
+
<Form.Item
|
|
105
|
+
label='API URL'
|
|
106
|
+
name='baseURLAI'
|
|
107
|
+
noStyle
|
|
108
|
+
rules={[
|
|
109
|
+
{ required: true, message: 'Please input or select API provider URL!' },
|
|
110
|
+
{ type: 'url', message: 'Please enter a valid URL!' }
|
|
111
|
+
]}
|
|
112
|
+
>
|
|
113
|
+
<AutoComplete
|
|
114
|
+
options={getBaseURLOptions()}
|
|
115
|
+
placeholder='Enter or select API provider URL'
|
|
116
|
+
filterOption={filter}
|
|
117
|
+
onChange={handleChange}
|
|
118
|
+
allowClear
|
|
119
|
+
style={{ width: '75%' }}
|
|
120
|
+
/>
|
|
121
|
+
</Form.Item>
|
|
122
|
+
<Form.Item
|
|
123
|
+
label='API PATH'
|
|
124
|
+
name='apiPathAI'
|
|
125
|
+
noStyle
|
|
126
|
+
>
|
|
127
|
+
<Input
|
|
128
|
+
placeholder='Enter API path'
|
|
129
|
+
style={{ width: '25%' }}
|
|
130
|
+
/>
|
|
131
|
+
</Form.Item>
|
|
132
|
+
</Space.Compact>
|
|
114
133
|
</Form.Item>
|
|
115
|
-
|
|
116
134
|
<Form.Item
|
|
117
135
|
label={e('modelAi')}
|
|
118
136
|
name='modelAI'
|
|
@@ -145,6 +163,18 @@ export default function AIConfigForm ({ initialValues, onSubmit, showAIConfig })
|
|
|
145
163
|
</AutoComplete>
|
|
146
164
|
</Form.Item>
|
|
147
165
|
|
|
166
|
+
<Form.Item
|
|
167
|
+
label={e('language')}
|
|
168
|
+
name='languageAI'
|
|
169
|
+
rules={[{ required: true, message: 'Please input language' }]}
|
|
170
|
+
>
|
|
171
|
+
<AutoComplete options={defaultLangs} placement='topLeft'>
|
|
172
|
+
<Input
|
|
173
|
+
placeholder={e('language')}
|
|
174
|
+
/>
|
|
175
|
+
</AutoComplete>
|
|
176
|
+
</Form.Item>
|
|
177
|
+
|
|
148
178
|
<Form.Item>
|
|
149
179
|
<Button type='primary' htmlType='submit'>
|
|
150
180
|
{e('save')}
|
|
@@ -6,17 +6,21 @@ import {
|
|
|
6
6
|
export default function InputAutoFocus (props) {
|
|
7
7
|
const { type, selectall = false, ...rest } = props
|
|
8
8
|
const inputRef = useRef(null)
|
|
9
|
+
const isFirstRender = useRef(true)
|
|
9
10
|
|
|
10
11
|
useEffect(() => {
|
|
11
12
|
if (inputRef.current) {
|
|
12
13
|
const { value } = props
|
|
13
|
-
if (value && selectall) {
|
|
14
|
+
if (value && selectall && isFirstRender.current) {
|
|
14
15
|
inputRef.current.focus()
|
|
16
|
+
inputRef.current.setSelectionRange(0, value.length)
|
|
17
|
+
isFirstRender.current = false
|
|
15
18
|
} else {
|
|
16
19
|
inputRef.current.focus()
|
|
17
20
|
}
|
|
18
21
|
}
|
|
19
|
-
}, [props.value, props.selectall])
|
|
22
|
+
}, [props.value, props.selectall])
|
|
23
|
+
|
|
20
24
|
let InputComponent
|
|
21
25
|
switch (type) {
|
|
22
26
|
case 'password':
|
|
@@ -25,11 +29,11 @@ export default function InputAutoFocus (props) {
|
|
|
25
29
|
default:
|
|
26
30
|
InputComponent = Input
|
|
27
31
|
}
|
|
32
|
+
|
|
28
33
|
return (
|
|
29
34
|
<InputComponent
|
|
30
35
|
ref={inputRef}
|
|
31
36
|
{...rest}
|
|
32
37
|
/>
|
|
33
|
-
|
|
34
38
|
)
|
|
35
39
|
}
|
|
@@ -69,7 +69,7 @@ export default class SettingTerminal extends Component {
|
|
|
69
69
|
if (name === 'useSystemTitleBar') {
|
|
70
70
|
message.info(e('useSystemTitleBarTip'), 8)
|
|
71
71
|
} else if (name === 'sftpPathFollowSsh' && value) {
|
|
72
|
-
message.
|
|
72
|
+
message.warning(e('sftpPathFollowSshTip'), 8)
|
|
73
73
|
}
|
|
74
74
|
this.saveConfig({
|
|
75
75
|
[name]: value
|
package/client/store/common.js
CHANGED
|
@@ -193,9 +193,6 @@ export default (Store) => {
|
|
|
193
193
|
})
|
|
194
194
|
ext.lastDataUpdateTime = await getData('lastDataUpdateTime') || 0
|
|
195
195
|
Object.assign(store, ext)
|
|
196
|
-
await store.fixBookmarkGroups()
|
|
197
|
-
await store.fixProfiles()
|
|
198
|
-
|
|
199
196
|
store.checkDefaultTheme()
|
|
200
197
|
store.loadFontList()
|
|
201
198
|
store.fetchItermThemes()
|
|
@@ -203,6 +200,13 @@ export default (Store) => {
|
|
|
203
200
|
store.fetchSshConfigItems()
|
|
204
201
|
store.initCommandLine().catch(store.onError)
|
|
205
202
|
initWatch(store)
|
|
203
|
+
setTimeout(
|
|
204
|
+
() => {
|
|
205
|
+
store.fixProfiles()
|
|
206
|
+
store.fixBookmarkGroups()
|
|
207
|
+
},
|
|
208
|
+
1000
|
|
209
|
+
)
|
|
206
210
|
if (store.config.checkUpdateOnStart) {
|
|
207
211
|
store.onCheckUpdate(false)
|
|
208
212
|
}
|