Compare commits

..

116 Commits
v5 ... v4.10.14

Author SHA1 Message Date
Jiangjie Bai
0fbdb3d94e Merge pull request #5293 from jumpserver/dev
v4.10.14
2025-12-18 17:23:42 +08:00
w940853815
65706509b1 fix:Disabled assets have no audit records 2025-12-18 11:48:17 +08:00
feng
3d668502e1 perf: chat ai custom model 2025-12-12 15:18:16 +08:00
w940853815
56e07c8568 fix: Remove 'Account' option from const.js 2025-12-11 17:01:08 +08:00
w940853815
c2f7a9e8e2 feat: Implement secret readability control based on system settings 2025-12-11 16:42:43 +08:00
w940853815
f0949f0e54 feat: Add permission check for reading account secrets based on system settings 2025-12-11 16:42:43 +08:00
w940853815
a165e45937 perf: Include 'id' in search and filter fields for AutomationExecution 2025-12-11 14:47:58 +08:00
zhaojisen
6350bdb42d Fixed: Fix the issue where the remote application details page is lost and the account needs to be regenerated 2025-12-10 17:31:49 +08:00
w940853815
4ecaee36f9 fix: Remove unused relevant_system_user option from BaseTicketList 2025-12-09 14:41:52 +08:00
w940853815
43e7e5cd74 fix: Remove unused CAS_CREATE_USER attribute from options 2025-12-04 17:40:54 +08:00
Bai
4332dbcc1c feat: add access token page 2025-12-01 17:54:55 +08:00
jiangweidong
a755b2ffa0 perf: increase joint camp areas 2025-12-01 10:56:32 +08:00
jiangweidong
d391592778 feat: Host cloud sync supports state cloud 2025-12-01 10:56:32 +08:00
Jiangjie Bai
88e10b34cd Merge pull request #5279 from jumpserver/dev
v4.10.13-lts
2025-11-20 20:20:44 +08:00
feng
3dd199ef01 fix: Ticket comment not display 2025-11-20 14:39:32 +08:00
w940853815
20e1c833a6 perf: Update asset detection logic in AccountRiskList for improved menu display 2025-11-20 10:32:05 +08:00
feng
f2c7a6bc71 perf: Account bulk error prompt 2025-11-19 17:38:52 +08:00
w940853815
6063e03d89 perf: Enhance error message handling for nested plain objects in getErrorResponseMsg 2025-11-19 15:42:26 +08:00
zhaojisen
e2d9eb5bae Fixed: Fix the issue where the global organization text is not displayed completely in the organization dropdown. 2025-11-19 15:31:10 +08:00
w940853815
84caf35f67 fix: Ensure progress display is shown correctly during job execution 2025-11-19 15:10:57 +08:00
zhaojisen
1d7a1bfff1 Fixed: Fix the issue where creating an SSH public key for a third-party user redirects to the login password tab. 2025-11-18 18:34:04 +08:00
w940853815
9039f572ac fix: Click Review to enter comments, and the page will be dimmed 2025-11-18 16:43:50 +08:00
w940853815
7798324a4b perf: Add support for error message extraction from plain objects in getErrorResponseMsg 2025-11-18 15:45:40 +08:00
feng
8e69206cfb fix: Account push show params 2025-11-17 17:29:44 +08:00
w940853815
338706247a perf: Add condition to check node type in AccountRiskList for asset detection 2025-11-17 11:15:53 +08:00
w940853815
2ae3e06484 perf: Refactor error handling and improve parameter assignment in job forms 2025-11-17 10:55:47 +08:00
w940853815
c1dcea1b29 perf: Improve error message formatting for array of strings 2025-11-12 16:22:44 +08:00
w940853815
59adc54f2d perf: Enhance AccountFormatter with options to exclude accounts 2025-11-11 18:55:34 +08:00
w940853815
afeafcbf49 perf: Job execution detail content add text-overflow class 2025-11-10 16:54:45 +08:00
w940853815
4e23107a21 perf: Support batch import of leak passwords 2025-11-06 18:36:40 +08:00
ibuler
3e267d07c1 perf: small size some png 2025-11-05 18:19:09 +08:00
fit2bot
7df6854a65 perf: upgrade vue version (#5260)
* perf: upgrade vue version

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: zhaojisen <1301338853@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-05 17:36:47 +08:00
w940853815
4db8edce98 perf: Add confirmation dialog before syncing platform protocols 2025-11-04 15:09:30 +08:00
Jiangjie Bai
f7830e9b85 Merge pull request #5239 from jumpserver/dev
v4.10.10
2025-10-16 17:29:18 +08:00
Bryan
16a92d10bc Merge pull request #5212 from jumpserver/dev
v4.10.8-lts
2025-09-18 16:49:05 +08:00
Bryan
7b568ec84f 1 2025-08-21 18:59:54 +08:00
Bryan
73d6bda8c3 Merge pull request #5092 from jumpserver/dev
merge: v4.10.4-lts
2025-07-17 15:04:47 +08:00
Bryan
3934b45367 Merge pull request #5064 from jumpserver/dev
v4.10.2
2025-06-19 20:13:12 +08:00
Bryan
0c5e84d1e3 Merge pull request #5010 from jumpserver/dev
v4.10.0
2025-05-15 17:12:07 +08:00
Bryan
18a3f42717 Merge pull request #4972 from jumpserver/dev
v4.9.0
2025-04-17 20:18:08 +08:00
Bryan
68030d98b2 Merge pull request #4890 from jumpserver/dev
v4.8.0
2025-03-20 18:44:31 +08:00
Bryan
a861f77609 Merge pull request #4659 from jumpserver/dev
v4.7.0
2025-02-20 10:20:32 +08:00
Bryan
e58ec6057c Merge pull request #4600 from jumpserver/dev
v4.6.0
2025-01-15 14:39:21 +08:00
Bryan
7ab20c5885 Merge pull request #4537 from jumpserver/dev
v4.5.0
2024-12-19 15:57:44 +08:00
Bryan
e47ddb5355 Merge pull request #4451 from jumpserver/dev
v4.4.0
2024-11-21 19:01:11 +08:00
Bryan
56aa3caa83 Merge pull request #4410 from jumpserver/dev
v4.3.0
2024-10-17 14:56:18 +08:00
Bryan
19b1dc0dbc Merge pull request #4367 from jumpserver/dev
merge: from dev to master
2024-09-19 19:36:42 +08:00
Bryan
77ef172a23 Merge pull request #4320 from jumpserver/dev
v4.1.0
2024-08-15 21:42:42 +08:00
Bryan
4596887bf1 Merge pull request #4178 from jumpserver/dev
v4.0.0
2024-07-03 19:06:07 +08:00
Bryan
0a3dc30c85 Merge pull request #4072 from jumpserver/dev
v3.10.11-lts
2024-06-19 16:04:12 +08:00
Bryan
51d24bc8e5 Merge pull request #3941 from jumpserver/dev
v3.10.10-lts
2024-05-16 16:05:04 +08:00
Bryan
1b15a4d043 Merge pull request #3871 from jumpserver/dev
v3.10.9 (dev to master)
2024-04-22 19:44:33 +08:00
Bryan
7d3f818242 Merge pull request #3864 from jumpserver/v3.10
v3.10.8
2024-04-18 17:58:05 +08:00
Bryan
4e26f18d77 Merge pull request #3862 from jumpserver/dev
v3.10.8
2024-04-18 17:17:36 +08:00
Bryan
b22613617a Revert "build(deps): bump follow-redirects from 1.15.3 to 1.15.4"
This reverts commit e971cbf4a8.
2024-03-27 16:16:07 +08:00
dependabot[bot]
e971cbf4a8 build(deps): bump follow-redirects from 1.15.3 to 1.15.4
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-27 16:11:26 +08:00
wangruidong
4672abae35 fix: 刷新页面根据搜索条件过滤出对应的资源 2024-03-04 19:17:05 +08:00
Bryan
ba36d72602 Merge pull request #3761 from jumpserver/master
v3.10.4 (branch-v3.10)
2024-02-29 16:26:13 +08:00
Bryan
4bfbbba4c5 Merge pull request #3760 from jumpserver/dev
v3.10.4
2024-02-29 16:15:33 +08:00
Bryan
ea038ce43a Merge pull request #3697 from jumpserver/master
v3.10.2
2024-01-17 13:34:12 +00:00
Bryan
e16b19666c Merge pull request #3696 from jumpserver/dev
v3.10.2
2024-01-17 13:33:22 +00:00
Bryan
c7f5409eb6 Merge pull request #3694 from jumpserver/master
v3.10.2
2024-01-17 07:35:33 -04:00
Bryan
fdbd7d2222 Merge pull request #3693 from jumpserver/dev
v3.10.2
2024-01-17 07:24:50 -04:00
Bryan
ddbaeeafea Merge pull request #3668 from jumpserver/master
v3.10.1
2023-12-29 11:34:04 +05:00
Bryan
efb0e9dacb Merge pull request #3665 from jumpserver/dev
v3.10.1
2023-12-29 11:14:54 +05:00
huailei
f6f8301ad5 Revert "perf: 账号收集翻译"
This reverts commit 9a63ae63d4.
2023-12-22 15:25:31 +08:00
“huailei000”
9a63ae63d4 perf: 账号收集翻译 2023-12-22 11:31:45 +08:00
Bryan
1e007ccda3 Merge pull request #3642 from jumpserver/dev
v3.10
2023-12-21 15:15:52 +05:00
老广
d1d0b06b53 Merge pull request #3546 from jumpserver/dev
v3.9.0
2023-11-16 18:25:10 +08:00
Bryan
5fb70d2f24 Merge pull request #3450 from jumpserver/dev
v3.8.0
2023-10-19 03:33:53 -05:00
Bryan
b54a95430f Merge pull request #3404 from jumpserver/dev
v3.7.0
2023-09-21 17:04:42 +08:00
Bryan
4d8b4c45af Merge pull request #3355 from jumpserver/dev
v3.6.0
2023-08-17 14:00:33 +05:00
Bryan
a6d642df60 Merge pull request #3283 from jumpserver/dev
v3.5.0
2023-07-20 19:04:29 +08:00
Jiangjie.Bai
2e74f1522f Merge pull request #3222 from jumpserver/dev
v3.4.0
2023-06-15 14:51:36 +08:00
Jiangjie.Bai
fe615e0314 Merge pull request #3219 from jumpserver/dev
v3.4.0
2023-06-15 14:17:46 +08:00
Jiangjie.Bai
09f734e6fc Merge pull request #3135 from jumpserver/dev
v3.3.0
2023-05-18 19:18:11 +08:00
Jiangjie.Bai
3117046342 Merge pull request #3061 from jumpserver/dev
v3.2.0
2023-04-20 18:40:08 +08:00
Bai
b68aecb5cc fix: 批量更新资产平台help-text 2023-04-20 18:39:22 +08:00
Jiangjie.Bai
1c9b155d97 Merge pull request #3057 from jumpserver/dev
v3.2.0
2023-04-20 18:22:46 +08:00
Jiangjie.Bai
75b1be9864 Merge pull request #3019 from jumpserver/dev
v3.2.0 rc2
2023-04-14 19:01:37 +08:00
Jiangjie.Bai
615c3c1cf4 Merge pull request #3014 from jumpserver/dev
v3.2.0 rc1
2023-04-13 20:02:38 +08:00
Jiangjie.Bai
4d82231af4 Merge pull request #3012 from jumpserver/dev
v3.2.0 rc1
2023-04-13 19:22:38 +08:00
“huailei000”
c6cf6571b6 perf: ldap导入用户列表-组织下拉框设置最大宽度 2023-03-16 16:44:36 +08:00
Bai
8ea990d070 fix: 修复创建资产添加账号模版报错问题 2023-03-16 16:44:36 +08:00
“huailei000”
f4a32170d5 perf: message 2023-03-16 16:44:36 +08:00
ibuler
073508675e perf: 添加默认的信息 2023-03-16 16:44:36 +08:00
Jiangjie.Bai
1d6ca0a93a Merge pull request #2924 from jumpserver/dev
v3.1.0 rc4
2023-03-15 19:46:31 +08:00
Jiangjie.Bai
36aea652d6 Merge pull request #2788 from jumpserver/dev
v3.0.0
2023-02-23 20:16:41 +08:00
Jiangjie.Bai
1a42ce90ab Merge pull request #2760 from jumpserver/dev
v3.0.0-rc-latest
2023-02-22 22:21:54 +08:00
Jiangjie.Bai
31a401b55d Merge pull request #2463 from jumpserver/dev
v3.0.0-rc4
2023-01-31 18:55:34 +08:00
Jiangjie.Bai
582a84178d Merge pull request #2187 from jumpserver/dev
v2.28.0
2022-11-17 17:44:19 +08:00
Jiangjie.Bai
9b9f7c936c Merge pull request #2184 from jumpserver/dev
v2.28.0-rc5
2022-11-17 14:18:15 +08:00
Jiangjie.Bai
2a6100957f Merge pull request #2182 from jumpserver/dev
v2.28.0-rc4
2022-11-16 21:08:55 +08:00
Jiangjie.Bai
16606d6a27 Merge pull request #2176 from jumpserver/dev
v2.28.0-rc2
2022-11-14 10:01:05 +08:00
Jiangjie.Bai
0a612f50e6 Merge pull request #2164 from jumpserver/dev
v2.28.0-rc1
2022-11-10 17:45:47 +08:00
Jiangjie.Bai
fe36fa9390 Merge pull request #2117 from jumpserver/dev
v2.27.0-rc4
2022-10-18 21:02:10 +08:00
Jiangjie.Bai
ba109900ec Merge pull request #2113 from jumpserver/dev
v2.27.0-rc3
2022-10-18 11:20:57 +08:00
Jiangjie.Bai
ec7768267f Merge pull request #2105 from jumpserver/dev
v2.27.0-rc2
2022-10-14 11:01:32 +08:00
Jiangjie.Bai
cc58b374ab Merge pull request #2101 from jumpserver/dev
v2.27.0-rc1
2022-10-13 17:44:53 +08:00
Jiangjie.Bai
04ffbb8fd6 Merge pull request #2097 from jumpserver/dev
v2.27.0-rc1
2022-10-13 15:14:40 +08:00
Jiangjie.Bai
49880f6739 Merge pull request #2059 from jumpserver/dev
v2.26.0
2022-09-15 17:49:44 +08:00
Jiangjie.Bai
e6f98d58c4 Merge pull request #2057 from jumpserver/dev
v2.26.0-rc4
2022-09-15 16:18:03 +08:00
Jiangjie.Bai
fd1f16d43c Merge pull request #2050 from jumpserver/dev
v2.26.0-rc2
2022-09-13 17:41:39 +08:00
Jiangjie.Bai
968b2415b1 Merge pull request #2043 from jumpserver/dev
v2.26.0-rc1
2022-09-08 15:46:44 +08:00
Jiangjie.Bai
776090d6ba Merge pull request #2001 from jumpserver/dev
v2.25.0
2022-08-18 16:12:45 +08:00
Jiangjie.Bai
3a37952288 Merge pull request #1996 from jumpserver/dev
v2.25.0-rc4
2022-08-17 16:53:23 +08:00
Jiangjie.Bai
62b8fc0e3b Merge pull request #1994 from jumpserver/dev
v2.25.0-rc3
2022-08-16 19:08:23 +08:00
Jiangjie.Bai
b2028869cb Merge pull request #1986 from jumpserver/dev
v2.25.0-rc2
2022-08-12 18:06:56 +08:00
Jiangjie.Bai
5277a725f8 Merge pull request #1973 from jumpserver/dev
v2.25.0-rc1
2022-08-11 14:11:59 +08:00
Jiangjie.Bai
f137788c1a Merge pull request #1957 from jumpserver/dev
v2.24.0-rc5
2022-07-20 19:06:03 +08:00
Jiangjie.Bai
f7d17c8de7 Merge pull request #1954 from jumpserver/dev
v2.24.0-rc4
2022-07-19 16:18:13 +08:00
Jiangjie.Bai
feea70b0be Merge pull request #1944 from jumpserver/dev
v2.24.0-rc3
2022-07-18 12:05:42 +08:00
Jiangjie.Bai
04696ef3d6 Merge pull request #1940 from jumpserver/dev
v2.24.0-rc2
2022-07-15 18:07:37 +08:00
Jiangjie.Bai
1731f4f788 Merge pull request #1934 from jumpserver/dev
v2.24.0-rc1
2022-07-14 18:27:51 +08:00
Jiangjie.Bai
6f25d93909 Merge pull request #1931 from jumpserver/dev
v2.24.0-rc1
2022-07-14 17:51:58 +08:00
Jiangjie.Bai
46461ec324 Merge pull request #1925 from jumpserver/dev
v2.24.0-rc1
2022-07-14 15:12:15 +08:00
33 changed files with 457 additions and 2198 deletions

View File

@@ -1,4 +1,4 @@
FROM jumpserver/lina-base:20251204_081759 AS stage-build
FROM jumpserver/lina-base:20251105_092554 AS stage-build
ARG VERSION
ENV VERSION=$VERSION

View File

@@ -59,9 +59,7 @@
"npm": "^7.8.0",
"nprogress": "0.2.0",
"path-to-regexp": "3.3.0",
"socket.io-client": "^4.8.1",
"sortablejs": "^1.15.6",
"uuid": "8.3.2",
"v-sanitize": "^0.0.13",
"vue": "2.7.16",
"vue-codemirror": "4.0.6",
@@ -142,5 +140,6 @@
"src/**/*.{js,vue}": [
"eslint --fix"
]
}
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}

BIN
src/assets/img/chat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
src/assets/img/deepSeek.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -62,6 +62,7 @@ import Dialog from '@/components/Dialog/index.vue'
import PasswordHistoryDialog from './PasswordHistoryDialog.vue'
import { SecretViewerFormatter } from '@/components/Table/TableFormatters'
import { encryptPassword } from '@/utils/secure'
import { mapGetters } from 'vuex'
export default {
name: 'ShowSecretInfo',
@@ -111,6 +112,9 @@ export default {
}
},
computed: {
...mapGetters({
publicSettings: 'publicSettings'
}),
secretTypeLabel() {
return this.account['secret_type'].label || 'Password'
},
@@ -146,7 +150,11 @@ export default {
})
},
showSecretDialog() {
return this.$axios.get(this.url, { disableFlashErrorMsg: true }).then((res) => {
if (!this.publicSettings.SECURITY_ACCOUNT_SECRET_READ) {
this.$message.warning(this.$tc('AccountSecretReadDisabled'))
return
}
return this.$axios.get(this.url).then((res) => {
this.secretInfo = res
this.sshKeyFingerprint = res?.spec_info?.ssh_key_fingerprint || '-'
this.showSecret = true
@@ -167,54 +175,54 @@ export default {
</script>
<style lang="scss" scoped>
.item-textarea ::v-deep .el-textarea__inner {
height: 110px;
.item-textarea ::v-deep .el-textarea__inner {
height: 110px;
}
.el-form-item {
border-bottom: 1px solid #EBEEF5;
padding: 5px 0;
margin-bottom: 0;
&:last-child {
border-bottom: none;
}
.el-form-item {
border-bottom: 1px solid #EBEEF5;
padding: 5px 0;
margin-bottom: 0;
&:last-child {
border-bottom: none;
}
::v-deep .el-form-item__label {
display: flex;
align-items: center;
justify-content: flex-start;
padding-right: 20px;
line-height: 30px;
word-break: keep-all;
overflow-wrap: break-word;
white-space: normal;
}
::v-deep .el-form-item__content {
line-height: 30px;
pre {
margin: 0;
}
}
::v-deep .el-form-item__label {
display: flex;
align-items: center;
justify-content: flex-start;
padding-right: 20px;
line-height: 30px;
word-break: keep-all;
overflow-wrap: break-word;
white-space: normal;
}
ul {
margin: 0;
}
::v-deep .el-form-item__content {
line-height: 30px;
li {
display: block;
font-size: 13px;
margin-bottom: 8px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.title {
color: #303133;
font-weight: 500;
pre {
margin: 0;
}
}
}
ul {
margin: 0;
}
li {
display: block;
font-size: 13px;
margin-bottom: 8px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.title {
color: #303133;
font-weight: 500;
}
}
</style>

View File

@@ -1,60 +1,12 @@
<template>
<div class="container">
<div class="chat-action">
<div class="model-select">
<Select2
v-model="select.value"
:disabled="isLoading || isSelectDisabled || loading || !options.length"
v-bind="select"
@change="onSelectChange"
/>
</div>
<el-dropdown
:hide-on-click="false"
trigger="click"
>
<span class="el-dropdown-link">
<i class="fa fa-plug" />
</span>
<el-dropdown-menu slot="dropdown">
<div class="menu-section">
<div v-if="toolsLoading">
<i class="el-icon-loading" /> {{ $t('Loading') }}
</div>
<div v-else class="menu-body">
<div>
<div
v-for="item in toolOptions"
:key="item.value"
>
<div style="padding: 0 10px">
<i class="fa fa-wrench item-icon" />
<span class="item-label">{{ item.label }}</span>
&nbsp;&nbsp;&nbsp;
<el-switch
:value="selectedToolsSet.has(item.value)"
@change="() => toggleTool(item.value)"
/>
</div>
</div>
<div
v-for="item in toolServerOptions"
:key="item.value"
>
<div>
<i class="fa fa-server item-icon" />
<span class="item-label">{{ item.label }}</span>
<el-switch
:value="selectedToolServersSet.has(item.value)"
@change="() => toggleToolServer(item.value)"
/>
</div>
</div>
</div>
</div>
</div>
</el-dropdown-menu>
</el-dropdown>
<div v-if="hasPrompt" class="chat-action">
<Select2
v-model="select.value"
:disabled="isLoading || isSelectDisabled"
v-bind="select"
@change="onSelectChange"
/>
</div>
<div class="chat-input">
<el-input
@@ -85,37 +37,9 @@ export default {
type: Boolean,
default: false
},
modelOptions: {
type: Array,
default: () => []
},
selectedModel: {
type: String,
default: ''
},
loading: {
hasPrompt: {
type: Boolean,
default: false
},
toolOptions: {
type: Array,
default: () => []
},
toolServerOptions: {
type: Array,
default: () => []
},
selectedTools: {
type: Array,
default: () => []
},
selectedToolServers: {
type: Array,
default: () => []
},
toolsLoading: {
type: Boolean,
default: false
default: true
}
},
data() {
@@ -123,10 +47,15 @@ export default {
isIM: false,
inputValue: '',
select: {
url: '/api/v1/settings/chatai-prompts/',
value: '',
multiple: false,
placeholder: this.$t('Model'),
options: []
placeholder: this.$t('Role'),
ajax: {
transformOption: (item) => {
return { label: item.name, value: item.content }
}
}
}
}
},
@@ -135,32 +64,7 @@ export default {
isLoading: state => state.chat.loading
}),
isSelectDisabled() {
return false
},
options() {
return (this.modelOptions || []).map(item => {
return { label: item.name || item.id, value: item.id }
})
},
selectedToolsSet() {
return new Set(this.selectedTools || [])
},
selectedToolServersSet() {
return new Set(this.selectedToolServers || [])
}
},
watch: {
modelOptions: {
immediate: true,
handler(val) {
this.select.options = (val || []).map(item => ({ label: item.name || item.id, value: item.id }))
}
},
selectedModel: {
immediate: true,
handler(val) {
this.select.value = val || ''
}
return !!this.select.value
}
},
methods: {
@@ -180,25 +84,7 @@ export default {
this.inputValue = ''
},
onSelectChange(value) {
this.$emit('select-model', value)
},
toggleTool(id) {
const set = new Set(this.selectedTools || [])
if (set.has(id)) {
set.delete(id)
} else {
set.add(id)
}
this.$emit('select-tools', Array.from(set))
},
toggleToolServer(id) {
const set = new Set(this.selectedToolServers || [])
if (set.has(id)) {
set.delete(id)
} else {
set.add(id)
}
this.$emit('select-tool-servers', Array.from(set))
this.$emit('select-prompt', value)
}
}
}
@@ -213,18 +99,9 @@ export default {
.chat-action {
width: 100%;
margin: 6px 0;
display: flex;
align-items: center;
gap: 8px;
.model-select {
flex: 0 0 48%;
max-width: 240px;
min-width: 160px;
}
&::v-deep .el-select {
width: 100%;
width: 50%;
.el-input__inner {
height: 28px;

View File

@@ -3,13 +3,9 @@
<div class="chart-item-container">
<div class="avatar">
<el-avatar
v-if="isUserRole"
:src="userUrl"
:src="isUserRole ? userUrl : chatUrl"
class="header-avatar"
/>
<el-avatar v-else class="header-avatar" :style="{ backgroundColor: 'transparent' }">
<ModelIcon :name="modelIconName" class-name="model-icon" />
</el-avatar>
</div>
<div class="content">
<div class="operational">
@@ -80,7 +76,6 @@
<script>
import MessageText from './MessageText.vue'
import ModelIcon from '../../models/ModelIcon.vue'
import { mapGetters, mapState } from 'vuex'
import { copy } from '@/utils/common/index'
import { useChat } from '../../useChat.js'
@@ -90,8 +85,7 @@ const { setLoading, removeLoadingMessageInChat } = useChat()
export default {
components: {
MessageText,
ModelIcon
MessageText
},
props: {
item: {
@@ -99,10 +93,6 @@ export default {
default: () => {
}
},
selectedModel: {
type: String,
default: ''
},
isTerminal: {
type: Boolean,
default: false
@@ -139,8 +129,10 @@ export default {
? this.$i18n.t('ServerBusyRetry')
: ''
},
modelIconName() {
return (this.item?.message?.model || this.selectedModel || this.publicSettings.CHAT_AI_TYPE || '').toString()
chatUrl() {
return this.publicSettings.CHAT_AI_TYPE === 'gpt'
? require('@/assets/img/chat.png')
: require('@/assets/img/deepSeek.png')
}
},
methods: {
@@ -179,18 +171,11 @@ export default {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: transparent;
&::v-deep img {
background-color: #fff;
}
}
.model-icon {
width: 100%;
height: 100%;
display: block;
}
}
.content {

View File

@@ -40,7 +40,7 @@ export default {
text() {
const value = this.message?.content || ''
if (value && this.markdown) {
return this.renderContentWithDetails(value)
return this.markdown?.render(value)
}
return this.$xss.process(value)
}
@@ -120,77 +120,6 @@ export default {
btn.addEventListener('click', callback)
})
},
renderContentWithDetails(value) {
// Kael responses may wrap reasoning/thinking in <details type="reasoning">; render them with a custom block.
const detailRegex = /<details[^>]*>[\s\S]*?<\/details>/gi
let result = ''
let lastIndex = 0
let match
let hasDetails = false
while ((match = detailRegex.exec(value))) {
hasDetails = true
const preceding = value.slice(lastIndex, match.index)
if (preceding.trim()) {
result += this.markdown.render(preceding)
}
result += this.renderDetailBlock(match[0])
lastIndex = match.index + match[0].length
}
if (!hasDetails) {
return this.markdown.render(value)
}
const remaining = value.slice(lastIndex)
if (remaining.trim()) {
result += this.markdown.render(remaining)
}
return result
},
renderDetailBlock(detailStr) {
const attributes = this.extractAttributes(detailStr)
const inner = detailStr.replace(/^<details[^>]*>/i, '').replace(/<\/details>$/i, '')
const summaryMatch = inner.match(/<summary>([\s\S]*?)<\/summary>/i)
const summary = summaryMatch ? this.decodeHtml(summaryMatch[1]) : ''
const body = summaryMatch ? inner.replace(summaryMatch[0], '') : inner
const bodyHtml = body.trim() ? this.markdown.render(this.decodeHtml(body.trim())) : ''
const baseClass = 'kael-detail'
if (attributes.type === 'reasoning') {
const statusClass = attributes.done === 'true' ? 'is-done' : 'is-pending'
const title = summary || this.$t('DeeplyThoughtAbout')
return `<div class="${baseClass} ${baseClass}--reasoning ${statusClass}">
<div class="${baseClass}__header">
<span class="${baseClass}__status-dot"></span>
<span class="${baseClass}__title">${title}</span>
</div>
${bodyHtml ? `<div class="${baseClass}__body">${bodyHtml}</div>` : ''}
</div>`
}
return `<div class="${baseClass}">
${summary ? `<div class="${baseClass}__header">${summary}</div>` : ''}
${bodyHtml ? `<div class="${baseClass}__body">${bodyHtml}</div>` : ''}
</div>`
},
extractAttributes(detailStr) {
const attrs = {}
const attrMatch = detailStr.match(/^<details([^>]*)>/i)
const attrStr = (attrMatch && attrMatch[1]) || ''
attrStr.replace(/(\w+)="(.*?)"/g, (all, key, val) => {
attrs[key] = val
return all
})
return attrs
},
decodeHtml(str) {
if (!str) return ''
const textArea = document.createElement('textarea')
textArea.innerHTML = str
return textArea.value
},
removeBtnClickEvent(selector) {
const buttons = this.$refs.textRef.querySelectorAll(selector)
buttons.forEach((btn) => {
@@ -329,64 +258,4 @@ export default {
.loading-box span:nth-child(3) {
animation-delay: 0.49s;
}
.kael-detail {
margin: 8px 0;
padding: 8px 10px;
border-radius: 8px;
border: 1px solid #e5e5e5;
background: #f7f8fa;
&__header {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: #6b7280;
}
&__title {
font-weight: 600;
}
&__status-dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: #10b981;
}
&__body {
margin-top: 6px;
padding-left: 8px;
border-left: 2px solid #e5e5e5;
}
&--reasoning.is-pending {
border-color: #f59e0b40;
background: #fff8e6;
.kael-detail__status-dot {
background: #f59e0b;
animation: kael-pulse 1.2s ease-in-out infinite;
}
}
&--reasoning.is-done {
border-color: #dbeafe;
background: #f4f6ff;
}
}
@keyframes kael-pulse {
0% {
opacity: 0.45;
}
50% {
opacity: 1;
}
100% {
opacity: 0.45;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -46,6 +46,7 @@
import Sidebar from './components/Sidebar/index.vue'
import Chat from './components/ChitChat/index.vue'
import { getInputFocus } from './useChat.js'
import { ws } from '@/utils/request'
import DrawerPanel from '@/components/Apps/DrawerPanel/index.vue'
import { ObjectLocalStorage } from '@/utils/common'
import { mapGetters } from 'vuex'
@@ -81,8 +82,7 @@ export default {
height: '400px',
expanded: false,
clientOffset: {},
currentTerminalContent: {},
initialized: false
currentTerminalContent: {}
}
},
computed: {
@@ -123,18 +123,11 @@ export default {
document.body.appendChild(script)
}
},
initAssistant() {
if (this.initialized) return
this.initialized = true
this.$nextTick(() => {
this.$refs.component?.init()
})
},
handlePostMessage() {
window.addEventListener('message', (event) => {
if (event.data === 'show-chat-panel') {
this.$refs.drawer.show = true
this.initAssistant()
this.initWebSocket()
return
}
const msg = event.data
@@ -159,6 +152,11 @@ export default {
}
this.$refs.drawer.handleHeaderMoveUp(event)
},
initWebSocket() {
if (!ws) {
this.$refs.component?.init()
}
},
onClose() {
this.$refs.drawer.show = false
},
@@ -172,6 +170,7 @@ export default {
},
save_pannel_settings() {
aiPannelLocalStorage.set('expanded', this.expanded)
console.log('AI panel settings saved:', this.expanded)
},
updateExpandedState(expanded) {
this.expanded = expanded
@@ -185,8 +184,8 @@ export default {
})
},
onToggle(status) {
this.initWebSocket()
if (status) {
this.initAssistant()
getInputFocus()
}
}

View File

@@ -1,33 +0,0 @@
<template>
<svg
:stroke-width="strokeWidth"
width="20"
height="20"
viewBox="0 0 20 20"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
:class="className"
>
<path
fill="#6b7280"
style="fill: #6b7280 !important"
d="M11.2475 18.25C10.6975 18.25 10.175 18.1455 9.67999 17.9365C9.18499 17.7275 8.74499 17.436 8.35999 17.062C7.94199 17.205 7.50749 17.2765 7.05649 17.2765C6.31949 17.2765 5.63749 17.095 5.01049 16.732C4.38349 16.369 3.87749 15.874 3.49249 15.247C3.11849 14.62 2.93149 13.9215 2.93149 13.1515C2.93149 12.8325 2.97549 12.486 3.06349 12.112C2.62349 11.705 2.28249 11.2375 2.04049 10.7095C1.79849 10.1705 1.67749 9.6095 1.67749 9.0265C1.67749 8.4325 1.80399 7.8605 2.05699 7.3105C2.30999 6.7605 2.66199 6.2875 3.11299 5.8915C3.57499 5.4845 4.10849 5.204 4.71349 5.05C4.83449 4.423 5.08749 3.862 5.47249 3.367C5.86849 2.861 6.35249 2.465 6.92449 2.179C7.49649 1.893 8.10699 1.75 8.75599 1.75C9.30599 1.75 9.82849 1.8545 10.3235 2.0635C10.8185 2.2725 11.2585 2.564 11.6435 2.938C12.0615 2.795 12.496 2.7235 12.947 2.7235C13.684 2.7235 14.366 2.905 14.993 3.268C15.62 3.631 16.1205 4.126 16.4945 4.753C16.8795 5.38 17.072 6.0785 17.072 6.8485C17.072 7.1675 17.028 7.514 16.94 7.888C17.38 8.295 17.721 8.768 17.963 9.307C18.205 9.835 18.326 10.3905 18.326 10.9735C18.326 11.5675 18.1995 12.1395 17.9465 12.6895C17.6935 13.2395 17.336 13.718 16.874 14.125C16.423 14.521 15.895 14.796 15.29 14.95C15.169 15.577 14.9105 16.138 14.5145 16.633C14.1295 17.139 13.651 17.535 13.079 17.821C12.507 18.107 11.8965 18.25 11.2475 18.25ZM7.17199 16.1875C7.72199 16.1875 8.20049 16.072 8.60749 15.841L11.7095 14.059C11.8195 13.982 11.8745 13.8775 11.8745 13.7455V12.3265L7.88149 14.62C7.63949 14.763 7.39749 14.763 7.15549 14.62L4.03699 12.8215C4.03699 12.8545 4.03149 12.893 4.02049 12.937C4.02049 12.981 4.02049 13.047 4.02049 13.135C4.02049 13.696 4.15249 14.213 4.41649 14.686C4.69149 15.148 5.07099 15.511 5.55499 15.775C6.03899 16.05 6.57799 16.1875 7.17199 16.1875ZM7.33699 13.498C7.40299 13.531 7.46349 13.5475 7.51849 13.5475C7.57349 13.5475 7.62849 13.531 7.68349 13.498L8.92099 12.7885L4.94449 10.4785C4.70249 10.3355 4.58149 10.121 4.58149 9.835V6.2545C4.03149 6.4965 3.59149 6.8705 3.26149 7.3765C2.93149 7.8715 2.76649 8.4215 2.76649 9.0265C2.76649 9.5655 2.90399 10.0825 3.17899 10.5775C3.45399 11.0725 3.81149 11.4465 4.25149 11.6995L7.33699 13.498ZM11.2475 17.161C11.8305 17.161 12.3585 17.029 12.8315 16.765C13.3045 16.501 13.6785 16.138 13.9535 15.676C14.2285 15.214 14.366 14.697 14.366 14.125V10.561C14.366 10.429 14.311 10.33 14.201 10.264L12.947 9.538V14.1415C12.947 14.4275 12.826 14.642 12.584 14.785L9.46549 16.5835C10.0045 16.9685 10.5985 17.161 11.2475 17.161ZM11.8745 11.122V8.878L10.01 7.822L8.12899 8.878V11.122L10.01 12.178L11.8745 11.122ZM7.05649 5.8585C7.05649 5.5725 7.17749 5.358 7.41949 5.215L10.538 3.4165C9.99899 3.0315 9.40499 2.839 8.75599 2.839C8.17299 2.839 7.64499 2.971 7.17199 3.235C6.69899 3.499 6.32499 3.862 6.04999 4.324C5.78599 4.786 5.65399 5.303 5.65399 5.875V9.4225C5.65399 9.5545 5.70899 9.659 5.81899 9.736L7.05649 10.462V5.8585ZM15.4385 13.7455C15.9885 13.5035 16.423 13.1295 16.742 12.6235C17.072 12.1175 17.237 11.5675 17.237 10.9735C17.237 10.4345 17.0995 9.9175 16.8245 9.4225C16.5495 8.9275 16.192 8.5535 15.752 8.3005L12.6665 6.5185C12.6005 6.4745 12.54 6.458 12.485 6.469C12.43 6.469 12.375 6.4855 12.32 6.5185L11.0825 7.2115L15.0755 9.538C15.1965 9.604 15.2845 9.692 15.3395 9.802C15.4055 9.901 15.4385 10.022 15.4385 10.165V13.7455ZM12.122 5.3635C12.364 5.2095 12.606 5.2095 12.848 5.3635L15.983 7.195C15.983 7.118 15.983 7.019 15.983 6.898C15.983 6.37 15.851 5.8695 15.587 5.3965C15.334 4.9125 14.9655 4.5275 14.4815 4.2415C14.0085 3.9555 13.4585 3.8125 12.8315 3.8125C12.2815 3.8125 11.803 3.928 11.396 4.159L8.29399 5.941C8.18399 6.018 8.12899 6.1225 8.12899 6.2545V7.6735L12.122 5.3635Z"
/>
</svg>
</template>
<script>
export default {
name: 'ChatGPTIcon',
props: {
className: {
type: String,
default: 'size-8'
},
strokeWidth: {
type: [String, Number],
default: '1.5'
}
}
}
</script>

View File

@@ -1,45 +0,0 @@
<template>
<svg
:stroke-width="strokeWidth"
viewBox="0 0 24 16"
overflow="visible"
width="20"
height="20"
:class="className"
>
<g style="transform: translateX(13px) rotateZ(0deg); transform-origin: 4.775px 7.73501px;">
<path
shape-rendering="geometricPrecision"
fill-opacity="1"
fill="#8c653f"
style="fill: #8c653f !important"
d=" M0,0 C0,0 6.1677093505859375,15.470022201538086 6.1677093505859375,15.470022201538086 C6.1677093505859375,15.470022201538086 9.550004005432129,15.470022201538086 9.550004005432129,15.470022201538086 C9.550004005432129,15.470022201538086 3.382294178009033,0 3.382294178009033,0 C3.382294178009033,0 0,0 0,0 C0,0 0,0 0,0z"
/>
</g>
<g opacity="1" style="transform: none; transform-origin: 7.935px 7.73501px;">
<path
shape-rendering="geometricPrecision"
fill-opacity="1"
fill="#8c653f"
style="fill: #8c653f !important"
d=" M5.824605464935303,9.348296165466309 C5.824605464935303,9.348296165466309 7.93500280380249,3.911694288253784 7.93500280380249,3.911694288253784 C7.93500280380249,3.911694288253784 10.045400619506836,9.348296165466309 10.045400619506836,9.348296165466309 C10.045400619506836,9.348296165466309 5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309 C5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309 5.824605464935303,9.348296165466309z M6.166755199432373,0 C6.166755199432373,0 0,15.470022201538086 0,15.470022201538086 C0,15.470022201538086 3.4480772018432617,15.470022201538086 3.4480772018432617,15.470022201538086 C3.4480772018432617,15.470022201538086 4.709278583526611,12.22130012512207 4.709278583526611,12.22130012512207 C4.709278583526611,12.22130012512207 11.16093635559082,12.22130012512207 11.16093635559082,12.22130012512207 C11.16093635559082,12.22130012512207 12.421928405761719,15.470022201538086 12.421928405761719,15.470022201538086 C12.421928405761719,15.470022201538086 15.87000560760498,15.470022201538086 15.87000560760498,15.470022201538086 C15.87000560760498,15.470022201538086 9.703250885009766,0 9.703250885009766,0 C9.703250885009766,0 6.166755199432373,0 6.166755199432373,0 C6.166755199432373,0 6.166755199432373,0 6.166755199432373,0z"
/>
</g>
</svg>
</template>
<script>
export default {
name: 'ClaudeIcon',
props: {
className: {
type: String,
default: 'size-4'
},
strokeWidth: {
type: [String, Number],
default: '1.5'
}
}
}
</script>

View File

@@ -1,34 +0,0 @@
<template>
<svg
id="图层_1"
xmlns="http://www.w3.org/2000/svg"
data-name="图层 1"
viewBox="0 0 71.69 52.76"
:class="className"
:stroke-width="strokeWidth"
>
<path
id="path"
fill="#4d6bfe"
style="fill: #4d6bfe !important"
d="M523.77,276.34c-.76-.38-1.08.33-1.53.69a4,4,0,0,0-.41.41,5.07,5.07,0,0,1-4.1,1.87,8,8,0,0,0-6.46,2.53,5.82,5.82,0,0,0-3.72-4.62,6.39,6.39,0,0,1-2.85-1.94,7.76,7.76,0,0,1-.92-2.31c-.16-.48-.32-1-.87-1.05s-.83.41-1.07.82a11,11,0,0,0-1.26,5.5,11.9,11.9,0,0,0,5.49,10.14.75.75,0,0,1,.39,1c-.25.84-.54,1.65-.79,2.49-.17.53-.41.65-1,.42a16.63,16.63,0,0,1-5.18-3.52c-2.56-2.48-4.88-5.21-7.76-7.35-.68-.5-1.36-1-2.06-1.41-2.94-2.86.39-5.2,1.16-5.48s.28-1.29-2.33-1.28-5,.88-8,2a8.23,8.23,0,0,1-1.39.41,28.67,28.67,0,0,0-8.61-.3,18.57,18.57,0,0,0-13.44,7.83c-4,5.47-4.91,11.67-3.76,18.15a27.68,27.68,0,0,0,10,16.88,26.8,26.8,0,0,0,19.23,6.39c4.43-.25,9.36-.84,14.92-5.55a13.84,13.84,0,0,0,5.32,1.18,17.24,17.24,0,0,0,5.09-.38c2.2-.46,2.05-2.5,1.25-2.87-6.43-3-5-1.78-6.3-2.77,3.27-3.87,8.2-7.89,10.13-20.92a12.44,12.44,0,0,0,0-2.52c0-.51.1-.71.68-.76a12.55,12.55,0,0,0,4.62-1.42c4.17-2.28,5.85-6,6.25-10.51A1.57,1.57,0,0,0,523.77,276.34Zm-36.34,40.37c-6.24-4.9-9.27-6.52-10.52-6.45s-1,1.41-.7,2.28a8.49,8.49,0,0,0,1.11,2.21,1.14,1.14,0,0,1-.34,1.8c-2,1.24-5.5-.42-5.66-.5a26.08,26.08,0,0,1-9.87-9.88,30.15,30.15,0,0,1-3.87-13.39c-.06-1.15.28-1.56,1.42-1.77a14.31,14.31,0,0,1,4.57-.11,28.56,28.56,0,0,1,16.33,8.29,54.06,54.06,0,0,1,6.58,8.63,41.46,41.46,0,0,0,7.41,8.71,24.36,24.36,0,0,0,2.66,2C494.16,318.82,490.16,318.87,487.43,316.71Zm3-19.23a.92.92,0,0,1,.92-.92.83.83,0,0,1,.32.06.8.8,0,0,1,.34.22.9.9,0,0,1,.25.64.92.92,0,0,1-1.83,0Zm9.29,4.76a5.27,5.27,0,0,1-1.77.48,3.75,3.75,0,0,1-2.38-.76,3.57,3.57,0,0,1-1.65-2.26,5.16,5.16,0,0,1,0-1.76,2,2,0,0,0-.71-2.17,3.1,3.1,0,0,0-2.06-.59,1.63,1.63,0,0,1-.76-.24.75.75,0,0,1-.34-1.07,3.47,3.47,0,0,1,.57-.62,3.9,3.9,0,0,1,3.43,0,10,10,0,0,1,3,2.34,18.62,18.62,0,0,1,2,2.73,10.9,10.9,0,0,1,1.33,2.53C500.65,301.47,500.4,302,499.71,302.24Z"
transform="translate(-452.83 -271.91)"
/>
</svg>
</template>
<script>
export default {
name: 'DeepSeekIcon',
props: {
className: {
type: String,
default: 'size-4'
},
strokeWidth: {
type: [String, Number],
default: '1.5'
}
}
}
</script>

View File

@@ -1,33 +0,0 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
width="800px"
height="800px"
viewBox="0 0 512 512"
:class="className"
:stroke-width="strokeWidth"
>
<path
fill="#4285f4"
style="fill: #4285f4 !important"
d="M473.16,221.48l-2.26-9.59H262.46v88.22H387c-12.93,61.4-72.93,93.72-121.94,93.72-35.66,0-73.25-15-98.13-39.11a140.08,140.08,0,0,1-41.8-98.88c0-37.16,16.7-74.33,41-98.78s61-38.13,97.49-38.13c41.79,0,71.74,22.19,82.94,32.31l62.69-62.36C390.86,72.72,340.34,32,261.6,32h0c-60.75,0-119,23.27-161.58,65.71C58,139.5,36.25,199.93,36.25,256S56.83,369.48,97.55,411.6C141.06,456.52,202.68,480,266.13,480c57.73,0,112.45-22.62,151.45-63.66,38.34-40.4,58.17-96.3,58.17-154.9C475.75,236.77,473.27,222.12,473.16,221.48Z"
/>
</svg>
</template>
<script>
export default {
name: 'GeminiIcon',
props: {
className: {
type: String,
default: 'size-4'
},
strokeWidth: {
type: [String, Number],
default: '1.5'
}
}
}
</script>

View File

@@ -1,33 +0,0 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
fill="currentColor"
:class="className"
:stroke-width="strokeWidth"
>
<path
fill="#000000"
style="fill: #000000 !important"
d="m3.005 8.858 8.783 12.544h3.904L6.908 8.858zM6.905 15.825 3 21.402h3.907l1.951-2.788zM16.585 2l-6.75 9.64 1.953 2.79L20.492 2zM17.292 7.965v13.437h3.2V3.395z"
/>
</svg>
</template>
<script>
export default {
name: 'GrokIcon',
props: {
className: {
type: String,
default: 'size-4'
},
strokeWidth: {
type: [String, Number],
default: '1.5'
}
}
}
</script>

View File

@@ -1,50 +0,0 @@
<template>
<component
:is="resolvedIcon"
v-if="resolvedIcon"
:class-name="className"
:stroke-width="strokeWidth"
/>
</template>
<script>
import ChatGPTIcon from './ChatGPT.vue'
import DeepSeekIcon from './DeepSeek.vue'
import GrokIcon from './Grok.vue'
import ClaudeIcon from './Claude.vue'
import GeminiIcon from './Gemini.vue'
export default {
name: 'ModelIcon',
props: {
name: {
type: String,
default: ''
},
className: {
type: String,
default: 'size-5'
},
strokeWidth: {
type: [String, Number],
default: '1.5'
}
},
computed: {
normalizedName() {
return (this.name || '').toLowerCase()
},
resolvedIcon() {
const name = this.normalizedName
if (!name) return null
if (name.includes('gpt')) return ChatGPTIcon
if (name.includes('deep-seek')) return DeepSeekIcon
if (name.includes('deepseek')) return DeepSeekIcon
if (name.includes('grok')) return GrokIcon
if (name.includes('claude')) return ClaudeIcon
if (name.includes('gemini')) return GeminiIcon
return null
}
}
}
</script>

View File

@@ -149,7 +149,7 @@ export default {
},
labelWidth: {
type: String,
default: '18.2%'
default: '25%'
}
},
data() {

View File

@@ -38,6 +38,7 @@
<script>
import { copy, downloadText } from '@/utils/common/index'
import BaseFormatter from '@/components/Table/TableFormatters/base.vue'
import { mapGetters } from 'vuex'
export default {
name: 'SecretViewerFormatter',
@@ -69,6 +70,9 @@ export default {
}
},
computed: {
...mapGetters({
publicSettings: 'publicSettings'
}),
hasShow: function() {
return this.formatterArgs.hasShow
},
@@ -140,6 +144,10 @@ export default {
},
methods: {
async getAccountSecret() {
if (!this.publicSettings.SECURITY_ACCOUNT_SECRET_READ) {
this.$message.warning(this.$tc('AccountSecretReadDisabled'))
return
}
if (this.formatterArgs.secretFrom === 'cellValue' || this.getIt) {
return
}
@@ -178,48 +186,48 @@ export default {
}
</script>
<style lang="scss" scoped>
.content {
display: inline-block;
width: 100%;
.content {
display: inline-block;
width: 100%;
overflow: hidden;
//white-space: nowrap;
text-overflow: ellipsis;
font-size: 13px;
.text {
flex: 1;
display: inline;
margin: 0;
padding: 0;
overflow: hidden;
//white-space: nowrap;
white-space: nowrap;
text-overflow: ellipsis;
}
.action {
font-size: 13px;
cursor: pointer;
margin-left: 1px;
display: inline;
.text {
flex: 1;
display: inline;
margin: 0;
padding: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&.right {
float: right;
}
.action {
font-size: 13px;
cursor: pointer;
margin-left: 1px;
display: inline;
.fa {
margin-right: 5px;
&.right {
float: right;
}
.fa {
margin-right: 5px;
&:hover {
color: var(--color-primary);
}
&:hover {
color: var(--color-primary);
}
}
}
}
.edit-input ::v-deep input {
border-left: none;
border-right: none;
border-top: none;
height: 30px;
}
.edit-input ::v-deep input {
border-left: none;
border-right: none;
border-top: none;
height: 30px;
}
</style>

View File

@@ -243,10 +243,12 @@ export default {
delete routeFilter.search
}
const asFilterTags = _.cloneDeep(this.filterTags)
this.filterTags = {
...asFilterTags,
...routeFilter
}
setTimeout(() => {
this.filterTags = {
...asFilterTags,
...routeFilter
}
}, 100)
},
getValueLabel(key, value) {
for (const field of this.options) {

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free v5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M512 176.001C512 273.203 433.202 352 336 352c-11.22 0-22.19-1.062-32.827-3.069l-24.012 27.014A23.999 23.999 0 0 1 261.223 384H224v40c0 13.255-10.745 24-24 24h-40v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24v-78.059c0-6.365 2.529-12.47 7.029-16.971l161.802-161.802C163.108 213.814 160 195.271 160 176 160 78.798 238.797.001 335.999 0 433.488-.001 512 78.511 512 176.001zM336 128c0 26.51 21.49 48 48 48s48-21.49 48-48-21.49-48-48-48-48 21.49-48 48z"/></svg>

After

Width:  |  Height:  |  Size: 691 B

View File

@@ -123,6 +123,16 @@ export default {
permissions: ['authentication.view_connectiontoken']
}
},
{
path: '/profile/access-token',
component: () => import('@/views/profile/AccessToken'),
name: 'AccessToken',
meta: {
title: i18n.t('AccessToken'),
icon: 'access-token',
permissions: ['oauth2_provider.view_accesstoken']
}
},
{
path: '/profile/preferences',
name: 'Preferences',

View File

@@ -137,8 +137,8 @@ export default {
getUrlQuery: true,
options: [
{
label: this.$t('TaskID'),
value: 'automation_id'
label: this.$t('ID'),
value: 'id'
},
{
label: this.$t('DisplayName'),

View File

@@ -61,8 +61,11 @@ export default {
},
callbacks: {
change: function(val) {
const category = this.object.category.value
const normalizedCategory =
category === 'ds' ? 'directorie' : category
this.$axios.patch(
`/api/v1/assets/assets/${this.object.id}/`,
`/api/v1/assets/${normalizedCategory}s/${this.object.id}/`,
{ is_active: val }
).then(res => {
this.$message.success(this.$tc('UpdateSuccessMsg'))

View File

@@ -77,7 +77,7 @@ export default {
[this.$tc('Platform'), 'platform'],
[this.$tc('Node'), 'node'],
[this.$tc('Protocol'), 'protocols'],
[this.$tc('Region'), 'region_id']
[this.$tc('Region'), 'region_name']
],
data: []
},
@@ -124,7 +124,7 @@ export default {
this.ws.onmessage = e => {
const data = JSON.parse(e.data)
if (data.action === 'sync_region') {
this.addRegion(data.region_id)
this.addRegion(data.id, data.name)
} else if (data.action === 'import') {
data['@status'] = 'pending'
this.$refs.importTable.addTableItem(data)
@@ -140,10 +140,10 @@ export default {
}
}
},
addRegion(region) {
if (!this.alreadySync.includes(region)) {
this.alreadySync.push(region)
this.tip = `${this.$t('SyncRegion')}: ${this.alreadySync.at(-1)}`
addRegion(regionId, regionName) {
if (!this.alreadySync.includes(regionId)) {
this.alreadySync.push(regionId)
this.tip = `${this.$t('SyncRegion')}: ${regionName}`
}
},
showResult() {

View File

@@ -17,6 +17,8 @@ export const ucloud = 'ucloud'
export const volcengine = 'volcengine'
export const ctyun = 'ctyun'
export const qingcloud_private = 'qingcloud_private'
export const huaweicloud_private = 'huaweicloud_private'
export const ctyun_private = 'ctyun_private'
@@ -46,7 +48,8 @@ export const publicHostProviders = [
gcp,
ucloud,
volcengine,
smartx
smartx,
ctyun
]
export const publicDBProviders = [aliyun]
@@ -141,6 +144,12 @@ export const ACCOUNT_PROVIDER_ATTRS_MAP = {
attrs: ['access_key_id', 'access_key_secret'],
image: require('@/assets/img/cloud/volcengine.svg')
},
[ctyun]: {
name: ctyun,
title: i18n.t('CTYun'),
attrs: ['access_key_id', 'access_key_secret', 'project_id'],
image: require('@/assets/img/cloud/state.svg')
},
[vmware]: {
name: vmware,
title: 'VMware',

View File

@@ -8,7 +8,6 @@ export const UserAssetPermissionListPageSearchConfigOptions = [
{ label: i18n.t('UserGroups'), value: 'user_group' },
{ label: i18n.t('AssetName'), value: 'asset_name' },
{ label: i18n.t('AssetAddress'), value: 'address' },
{ label: i18n.t('Account'), value: 'accounts' },
{
label: i18n.t('Valid'),
value: 'is_valid',

View File

@@ -0,0 +1,77 @@
<template>
<GenericListPage
ref="GenericListTable"
:header-actions="headerActions"
:help-tip="helpMessage"
:table-config="tableConfig"
/>
</template>
<script>
import { GenericListPage } from '@/layout/components'
export default {
components: {
GenericListPage
},
data() {
const ajaxUrl = '/api/v1/authentication/access-tokens/'
return {
helpMessage: this.$t('AccessTokenTip'),
tableConfig: {
hasSelection: false,
url: ajaxUrl,
columns: [
'token_preview', 'scope', 'is_valid', 'expires', 'updated', 'created', 'actions'
],
columnsMeta: {
actions: {
prop: '',
formatterArgs: {
hasUpdate: false,
hasClone: false,
hasDelete: false,
extraActions: [
{
name: 'Revoke',
title: this.$t('Revoke'),
can: ({ row }) => this.$hasPerm('oauth2_provider.delete_accesstoken'),
type: 'info',
callback: function({ row }) {
this.$axios.delete(`${ajaxUrl}${row.id}/revoke/`,
).then(res => {
this.reloadTable()
this.$message.success(this.$tc('UpdateSuccessMsg'))
}).catch(error => {
this.$message.error(this.$tc('UpdateErrorMsg' + ' ' + error))
})
}.bind(this)
}
]
}
}
}
},
headerActions: {
hasLeftActions: false,
hasSearch: false,
hasRightActions: true,
hasRefresh: true,
hasExport: false,
hasImport: false,
hasBulkDelete: false,
hasCreate: false,
extraActions: []
}
}
},
methods: {
reloadTable() {
this.$refs.GenericListTable.reloadTable()
}
}
}
</script>
<style scoped>
</style>

View File

@@ -1,36 +1,41 @@
<template>
<Account
:url="url"
:columns-meta="columnsMeta"
:extra-quick-actions="quickActions"
:object.sync="object"
/>
<TwoCol>
<template>
<Account :url="url" :columns-meta="columnsMeta" :object.sync="object" />
</template>
<template #right>
<QuickActions :actions="quickActions" type="primary" />
</template>
</TwoCol>
</template>
<script>
import { QuickActions } from '@/components'
import Account from '@/views/assets/Asset/AssetDetail/Account'
import TwoCol from '@/layout/components/Page/TwoColPage.vue'
export default {
name: 'Accounts',
components: {
Account
TwoCol,
Account,
QuickActions
},
props: {
object: {
type: Object,
default: () => {
}
default: () => {}
}
},
data() {
return {
columnsMeta: {
name: {
formatter: (row) => <span>{row.name}</span>
formatter: row => <span>{row.name}</span>
},
asset: {
label: this.$t('Asset'),
formatter: (row) => <span>{row.asset.name}</span>
formatter: row => <span>{row.asset.name}</span>
}
},
quickActions: [

View File

@@ -29,7 +29,7 @@ export default {
'CAS_RENAME_ATTRIBUTES'
]],
[this.$t('Other'), [
'CAS_ORG_IDS', 'CAS_CREATE_USER', 'CAS_LOGOUT_COMPLETELY'
'CAS_ORG_IDS', 'CAS_LOGOUT_COMPLETELY'
]]
],
fieldsMeta: {

View File

@@ -10,7 +10,6 @@
import { GenericCreateUpdateForm } from '@/layout/components'
import IBox from '@/components/Common/IBox/index.vue'
import { mapGetters } from 'vuex'
import ChatProvidersField from './components/ChatProvidersField.vue'
export default {
components: {
@@ -18,52 +17,117 @@ export default {
GenericCreateUpdateForm
},
data() {
const hasProviders = (formValue) => {
const providers = formValue?.CHAT_AI_PROVIDERS?.providers || []
return Array.isArray(providers) && providers.length > 0
}
const vm = this
return {
url: '/api/v1/settings/setting/?category=chat',
hasReset: false,
moreButtons: [
{
title: this.$t('Test'),
loading: false,
callback: function(value, form, btn) {
btn.loading = true
vm.$axios.post(
'/api/v1/settings/chatai/testing/',
value
).then(res => {
vm.$message.success(res['msg'])
}).catch(() => {
vm.$log.error('err occur')
}).finally(() => {
btn.loading = false
})
}
}
],
encryptedFields: ['VAULT_HCP_TOKEN'],
fields: [
'CHAT_AI_ENABLED',
'CHAT_AI_METHOD',
'CHAT_AI_PROVIDERS',
'CHAT_AI_EMBED_URL'
'CHAT_AI_EMBED_URL',
'CHAT_AI_TYPE',
'DEEPSEEK_BASE_URL',
'DEEPSEEK_API_KEY',
'DEEPSEEK_PROXY',
'DEEPSEEK_MODEL',
'GPT_BASE_URL',
'GPT_API_KEY',
'GPT_PROXY',
'GPT_MODEL',
'IS_CUSTOM_MODEL',
'CUSTOM_GPT_MODEL',
'CUSTOM_DEEPSEEK_MODEL'
],
fieldsMeta: {
CHAT_AI_TYPE: {
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || hasProviders(formValue)
return formValue.CHAT_AI_METHOD !== 'api'
}
},
CHAT_AI_PROVIDERS: {
component: ChatProvidersField,
hidden: (formValue) => formValue.CHAT_AI_METHOD !== 'api'
GPT_BASE_URL: {
el: {
autocomplete: 'new-password'
},
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'gpt'
}
},
GPT_API_KEY: {
el: {
autocomplete: 'new-password'
},
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'gpt'
}
},
GPT_PROXY: {
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'gpt'
}
},
GPT_MODEL: {
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'gpt'
}
},
DEEPSEEK_BASE_URL: {
el: {
autocomplete: 'new-password'
},
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'deep-seek'
}
},
DEEPSEEK_API_KEY: {
el: {
autocomplete: 'new-password'
},
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'deep-seek'
}
},
DEEPSEEK_PROXY: {
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'deep-seek'
}
},
DEEPSEEK_MODEL: {
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'deep-seek'
}
},
CHAT_AI_EMBED_URL: {
hidden: (formValue) => formValue.CHAT_AI_METHOD !== 'embed'
}
},
afterGetFormValue(formValue) {
const providers = Array.isArray(formValue.CHAT_AI_PROVIDERS) ? formValue.CHAT_AI_PROVIDERS : []
return {
...formValue,
CHAT_AI_PROVIDERS: {
providers: providers
},
CUSTOM_GPT_MODEL: {
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'gpt' || !formValue.IS_CUSTOM_MODEL
}
},
CUSTOM_DEEPSEEK_MODEL: {
hidden: (formValue) => {
return formValue.CHAT_AI_METHOD !== 'api' || formValue.CHAT_AI_TYPE !== 'deep-seek' || !formValue.IS_CUSTOM_MODEL
}
}
},
cleanFormValue(values) {
const config = values.CHAT_AI_PROVIDERS || {}
const providers = Array.isArray(config.providers) ? config.providers : []
return {
...values,
CHAT_AI_PROVIDERS: providers,
CHAT_AI_TYPE: values.CHAT_AI_TYPE || providers[0]?.type || values.CHAT_AI_TYPE
}
},
submitMethod() {

View File

@@ -1,186 +0,0 @@
<template>
<div class="providers-card">
<div class="providers-header">
<el-button size="mini" type="primary" icon="el-icon-plus" @click="addProvider">
{{ $t('Add') }}
</el-button>
</div>
<el-table :data="localProviders" size="mini" border>
<el-table-column :label="$t('Type')" width="140">
<template #default="{ row }">
<el-select v-model="row.type" size="mini" @change="emitChange">
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column :label="$t('Base URL')" min-width="200">
<template #default="{ row }">
<el-input
v-model="row.base_url"
size="mini"
:placeholder="openAIBaseUrl"
@input="emitChange"
/>
</template>
</el-table-column>
<el-table-column :label="$t('API Key')" min-width="180">
<template #default="{ row }">
<el-input
v-model="row.api_key"
size="mini"
show-password
autocomplete="new-password"
@input="emitChange"
/>
</template>
</el-table-column>
<el-table-column :label="$t('Proxy')" min-width="160">
<template #default="{ row }">
<el-input
v-model="row.proxy"
size="mini"
placeholder="http://ip:port"
@input="emitChange"
/>
</template>
</el-table-column>
<el-table-column :label="$t('Actions')" width="100" align="center">
<template #default="{ $index }">
<el-button
size="mini"
type="text"
class="danger-text"
icon="el-icon-delete"
@click="removeProvider($index)"
/>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import cloneDeep from 'lodash/cloneDeep'
export default {
name: 'ChatProvidersField',
props: {
value: {
type: [Object, Array],
default: () => ({ providers: [], defaultProvider: '' })
},
typeOptions: {
type: Array,
default: () => ([
{ label: 'Ollama', value: 'ollama' },
{ label: 'OpenAI', value: 'openai' }
])
}
},
data() {
const { providers, defaultProvider } = this.normalizeValue(this.value)
return {
localProviders: providers,
defaultProvider: this.pickDefault(defaultProvider, providers),
openAIBaseUrl: 'https://api.openai.com/v1'
}
},
watch: {
value: {
handler(v) {
const { providers, defaultProvider } = this.normalizeValue(v)
this.localProviders = providers
this.defaultProvider = this.pickDefault(defaultProvider, providers) || ''
},
deep: true
}
},
methods: {
emptyProvider() {
return {
type: 'openai',
base_url: this.openAIBaseUrl,
api_key: '',
proxy: ''
}
},
normalizeValue(v) {
if (!v) {
return { providers: [], defaultProvider: '' }
}
// allow legacy array value
if (Array.isArray(v)) {
return { providers: cloneDeep(v), defaultProvider: '' }
}
const providers = Array.isArray(v.providers) ? cloneDeep(v.providers) : []
return { providers, defaultProvider: v.defaultProvider || '' }
},
pickDefault(current, providers) {
const enabledProviders = providers.filter(item => item?.enabled !== false)
if (current && providers.some(item => item.name === current)) {
return current
}
return enabledProviders[0]?.name || providers[0]?.name || ''
},
emitChange() {
const providers = cloneDeep(this.localProviders || [])
const defaultProvider = this.pickDefault(this.defaultProvider, providers)
this.defaultProvider = defaultProvider
this.$emit('input', { providers, defaultProvider })
this.$emit('change', { providers, defaultProvider })
},
handleAssistantChange(current) {
this.emitChange()
},
addProvider() {
this.localProviders.push(this.emptyProvider())
this.emitChange()
},
removeProvider(index) {
this.localProviders.splice(index, 1)
this.emitChange()
},
setDefault(name) {
this.defaultProvider = name
this.emitChange()
}
}
}
</script>
<style scoped lang="scss">
.providers-card {
border: 1px solid #ebeef5;
border-radius: 4px;
padding: 12px;
}
.providers-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
.title {
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
}
.tip {
color: #909399;
font-weight: 400;
font-size: 12px;
}
}
.danger-text {
color: #f56c6c;
}
</style>

View File

@@ -189,10 +189,6 @@ export default {
value: 'relevant_asset',
label: this.$t('RelevantAsset')
},
{
value: 'relevant_system_user',
label: this.$t('RelevantCommand')
},
{
value: 'relevant_command',
label: this.$t('ApplyRunCommand')

View File

@@ -1069,11 +1069,6 @@
resolved "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@socket.io/component-emitter@~3.1.0":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2"
integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==
"@soda/friendly-errors-webpack-plugin@^1.7.1":
version "1.8.1"
resolved "https://registry.npmmirror.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz#4d4fbb1108993aaa362116247c3d18188a2c6c85"
@@ -4772,13 +4767,6 @@ debug@^3.1.0, debug@^3.2.7:
dependencies:
ms "^2.1.1"
debug@~4.3.1, debug@~4.3.2:
version "4.3.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
dependencies:
ms "^2.1.3"
debuglog@^1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
@@ -5313,22 +5301,6 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
engine.io-client@~6.6.1:
version "6.6.3"
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.6.3.tgz#815393fa24f30b8e6afa8f77ccca2f28146be6de"
integrity sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
engine.io-parser "~5.2.1"
ws "~8.17.1"
xmlhttprequest-ssl "~2.1.1"
engine.io-parser@~5.2.1:
version "5.2.3"
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz#00dc5b97b1f233a23c9398d0209504cf5f94d92f"
integrity sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==
enhanced-resolve@^4.1.0, enhanced-resolve@^4.5.0:
version "4.5.0"
resolved "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec"
@@ -12912,24 +12884,6 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
socket.io-client@^4.8.1:
version "4.8.1"
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.8.1.tgz#1941eca135a5490b94281d0323fe2a35f6f291cb"
integrity sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.2"
engine.io-client "~6.6.1"
socket.io-parser "~4.2.4"
socket.io-parser@~4.2.4:
version "4.2.4"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83"
integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
sockjs-client@^1.5.0:
version "1.6.1"
resolved "https://registry.npmmirror.com/sockjs-client/-/sockjs-client-1.6.1.tgz#350b8eda42d6d52ddc030c39943364c11dcad806"
@@ -14254,16 +14208,16 @@ utils-merge@1.0.1:
resolved "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
uuid@8.3.2, uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v-sanitize@^0.0.13:
version "0.0.13"
resolved "https://registry.npmmirror.com/v-sanitize/-/v-sanitize-0.0.13.tgz#d98e3eee3277a2b3a632bc2ba119c088967da0c4"
@@ -14986,21 +14940,11 @@ ws@^6.0.0, ws@^6.2.1:
dependencies:
async-limiter "~1.0.0"
ws@~8.17.1:
version "8.17.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
xmlhttprequest-ssl@~2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz#e9e8023b3f29ef34b97a859f584c5e6c61418e23"
integrity sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==
xss@^1.0.14, xss@^1.0.9:
version "1.0.15"
resolved "https://registry.npmmirror.com/xss/-/xss-1.0.15.tgz#96a0e13886f0661063028b410ed1b18670f4e59a"