Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
2ad17ab996 build(deps): bump axios from 0.28.0 to 0.30.2
Bumps [axios](https://github.com/axios/axios) from 0.28.0 to 0.30.2.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.28.0...v0.30.2)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 0.30.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-30 07:25:15 +00:00
50 changed files with 250 additions and 456 deletions

View File

@@ -1,4 +1,4 @@
FROM jumpserver/lina-base:20251201_095403 AS stage-build
FROM jumpserver/lina-base:20251030_071727 AS stage-build
ARG VERSION
ENV VERSION=$VERSION

View File

@@ -29,7 +29,7 @@
"@kangc/v-md-editor": "^1.7.12",
"@traptitech/markdown-it-katex": "^3.6.0",
"@ztree/ztree_v3": "3.5.44",
"axios": "0.28.0",
"axios": "0.30.2",
"axios-retry": "^3.1.9",
"babel-loader": "^10.0.0",
"cache-loader": "^4.1.0",
@@ -61,7 +61,7 @@
"path-to-regexp": "3.3.0",
"sortablejs": "^1.15.6",
"v-sanitize": "^0.0.13",
"vue": "2.7.16",
"vue": "2.6.10",
"vue-codemirror": "4.0.6",
"vue-cookie": "^1.1.4",
"vue-echarts": "^5.0.0-beta.0",
@@ -119,11 +119,11 @@
"svg-sprite-loader": "4.1.3",
"svgo": "1.2.2",
"vue-i18n-extract": "^1.1.1",
"vue-template-compiler": "2.7.16",
"vue-template-compiler": "2.6.10",
"webpack": "^4.28.4"
},
"engines": {
"node": ">=12",
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"browserslist": [
@@ -140,6 +140,5 @@
"src/**/*.{js,vue}": [
"eslint --fix"
]
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 584 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -15,25 +15,10 @@ export const accountFieldsMeta = (vm) => {
}
return {
nodes: {
component: Select2,
label: vm.$t('Node'),
el: {
value: [],
ajax: {
url: '/api/v1/assets/nodes/',
transformOption: (item) => {
return { label: item.full_value, value: item.id }
}
}
},
hidden: () => {
return !vm.addTemplate
}
},
assets: {
component: AssetSelect,
label: vm.$t('Asset'),
rules: [Required],
el: {
multiple: false
},
@@ -48,7 +33,7 @@ export const accountFieldsMeta = (vm) => {
get disabled() {
return vm.isDisabled
},
multiple: vm.addTemplate,
multiple: false,
ajax: {
url: '/api/v1/accounts/account-templates/',
transformOption: (item) => {

View File

@@ -63,7 +63,7 @@ export default {
encryptedFields: ['secret'],
fields: [
[this.$t('Basic'), ['name', 'username', 'privileged', 'su_from', 'su_from_username', 'template']],
[this.$t('Asset'), ['nodes', 'assets']],
[this.$t('Asset'), ['assets']],
[this.$t('Secret'), [
'secret_type', 'password', 'ssh_key', 'token',
'access_key', 'passphrase', 'api_key',

View File

@@ -93,8 +93,8 @@ export default {
iVisible = true
data = formValue
url = `/api/v1/accounts/accounts/bulk/`
if ((!data.assets || data.assets.length === 0) && (!data.nodes || data.nodes.length === 0)) {
this.$message.error(this.$tc('PleaseSelectAssetOrNode'))
if (data.assets.length === 0) {
this.$message.error(this.$tc('PleaseSelectAsset'))
return
}
}
@@ -107,10 +107,6 @@ export default {
this.$emit('add', true)
}
}).catch(error => {
if (error?.response?.data?.code === 'no_valid_assets') {
this.$message.error(error?.response?.data?.detail)
return
}
this.iVisible = true
this.handleResult(null, error)
})

View File

@@ -49,10 +49,6 @@ export default {
prop: 'asset',
label: this.$t('Asset')
},
{
prop: 'account',
label: this.$t('Account')
},
{
prop: 'state',
label: this.$t('Status'),

View File

@@ -37,12 +37,8 @@ export default {
},
headerActions: {
hasExport: true,
hasImport: true,
importOptions: {
encryptFields: [''], // 这里不加密 password''只是为了保证数组有值
canImportUpdate: false
},
hasExport: false,
hasImport: false,
hasCreate: true,
hasSearch: true,
hasRefresh: true,

View File

@@ -73,28 +73,28 @@ export default {
}
</script>
<style lang="scss" scoped>
::v-deep .help-dialog.dialog .el-dialog__footer {
<style>
.help-dialog.dialog .el-dialog__footer {
border-top: none;
padding: 8px;
}
</style>
<style lang="scss" scoped>
.help-table {
width: 100%;
border-collapse: collapse;
border: 1px solid #dee2e6;
}
::v-deep .help-table th,
::v-deep .help-table td {
height: 40px;
padding: 0 8px;
text-align: left;
}
&::v-deep th, td {
height: 40px;
padding: 0 8px;
text-align: left;
}
::v-deep .help-table .item-td,
::v-deep .help-table .item-label {
cursor: pointer;
color: var(--color-primary);
&::v-deep .item-td, .item-label {
cursor: pointer;
color: var(--color-primary);
}
}
</style>

View File

@@ -223,21 +223,8 @@ export default {
const mapped = {}
Object.entries(errors || {}).forEach(([k, v]) => {
let msg = v
console.log(k, v)
// v是数组并且数组都是字符串则拼接为字符串
if (Array.isArray(v) && v.every(item => typeof item === 'string')) msg = v.join('; ')
// 处理 [{"port":["请确保该值小于或者等于 65535。"]},{},{}] 这种情况
else if (Array.isArray(v) && v.every(item => _.isPlainObject(item))) {
const subMsg = []
v.forEach((subItem) => {
Object.values(subItem).forEach((subMsgArr) => {
if (Array.isArray(subMsgArr)) {
subMsg.push(...subMsgArr)
}
})
})
msg = subMsg.join(' ')
} else if (typeof v === 'object' && v !== null) msg = JSON.stringify(v)
if (Array.isArray(v)) msg = v.join('; ')
else if (typeof v === 'object' && v !== null) msg = JSON.stringify(v)
mapped[k] = String(msg || '')
})
this.serverErrors = mapped

View File

@@ -58,7 +58,6 @@
:import-option="importOption"
:json-data="jsonData"
:url="url"
v-bind="$attrs"
@cancel="cancelUpload"
@finish="closeDialog"
/>
@@ -248,46 +247,46 @@ export default {
</script>
<style lang='scss' scoped>
@import "~@/styles/variables";
@import "~@/styles/variables";
.error-msg {
color: $--color-danger;
}
.error-msg.error-results {
background-color: #f3f3f4;
max-height: 200px;
overflow: auto
}
.file-uploader ::v-deep .el-upload {
width: 100%;
//padding-right: 150px;
}
.file-uploader ::v-deep .el-upload-dragger {
width: 100%;
}
.importTableZone {
padding: 0 20px;
.importTable {
overflow: auto;
.error-msg {
color: $--color-danger;
}
.tableFilter {
padding-bottom: 10px;
.error-msg.error-results {
background-color: #f3f3f4;
max-height: 200px;
overflow: auto
}
}
.importTable ::v-deep .el-dialog__body {
padding-bottom: 20px;
}
.file-uploader ::v-deep .el-upload {
width: 100%;
//padding-right: 150px;
}
.export-item {
margin-left: 80px;
}
.file-uploader ::v-deep .el-upload-dragger {
width: 100%;
}
.importTableZone {
padding: 0 20px;
.importTable {
overflow: auto;
}
.tableFilter {
padding-bottom: 10px;
}
}
.importTable ::v-deep .el-dialog__body {
padding-bottom: 20px;
}
.export-item {
margin-left: 80px;
}
.export-item:first-child {
margin-left: 0;

View File

@@ -97,10 +97,6 @@ export default {
origin: {
type: String,
default: ''
},
encryptFields: {
type: Array,
default: () => []
}
},
data() {
@@ -277,15 +273,11 @@ export default {
}
return columns
},
getEncryptFields() {
const fromProp = Array.isArray(this.encryptFields) && this.encryptFields.length ? this.encryptFields : null
return fromProp || ['password', 'secret', 'private_key']
},
generateTableData(tableTitles, tableData) {
const totalData = []
tableData.forEach(item => {
this.$set(item, '@status', 'pending')
const encryptFields = this.getEncryptFields()
const encryptFields = ['password', 'secret', 'private_key']
for (const field of encryptFields) {
if (item[field]) {
item[field] = encryptPassword(item[field])

View File

@@ -88,7 +88,7 @@ export default {
},
filterMaps() {
const data = {}
const keyword = 'search'
const keyword = 'q'
for (let key in this.filterTags) {
const value = this.filterTags[key]['value']
if (key === '') {

View File

@@ -421,8 +421,12 @@ export default {
display: inline-block;
}
.data-z-tree ::v-deep .icon {
width: 10px;
margin-right: 3px;
.data-z-tree {
::v-deep {
.icon {
width: 10px;
margin-right: 3px;
}
}
}
</style>

View File

@@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 691 B

View File

@@ -78,3 +78,6 @@ export default {
}
}
</style>
<style lang="scss">
</style>

View File

@@ -65,17 +65,6 @@ export default {
'usingOrgs',
'currentViewRoute'
]),
currentOrgDisplayName() {
const currentOrgId = this.currentOrg?.id
if (!currentOrgId) {
return this.$tc('Select')
}
const matchedOrg = this.usingOrgs.find(item => item.id === currentOrgId)
if (matchedOrg?.name) {
return matchedOrg.name
}
return this.currentOrg.name || this.$tc('Select')
},
orgActionsGroup() {
const orgActions = {
label: this.$t('OrganizationList'),
@@ -121,8 +110,11 @@ export default {
}
},
watch: {
currentOrgDisplayName() {
this.updateWidth()
currentOrg: {
handler() {
this.updateWidth()
},
deep: true
}
},
mounted() {
@@ -141,9 +133,8 @@ export default {
tempSpan.style.fontWeight = 'normal'
tempSpan.style.letterSpacing = 'normal'
// 获取当前组织显示名称
const orgName = this.currentOrgDisplayName
// 获取当前组织名称
const orgName = this.currentOrg.name || this.$tc('Select')
tempSpan.textContent = orgName
document.body.appendChild(tempSpan)

View File

@@ -369,7 +369,7 @@ export default {
}
}
.el-input__prefix .el-input__icon {
.el-input__prefix .el-input__icon{
font-size: 15px;
line-height: 32px;
}
@@ -402,9 +402,11 @@ export default {
}
}
}
</style>
<style lang="scss">
/* 搜索模态框全局样式 */
::v-deep .search-modal {
.search-modal {
&.el-dialog {
position: fixed;
top: 5px;
@@ -425,17 +427,17 @@ export default {
}
}
::v-deep body .v-modal {
body .v-modal {
opacity: 0.3;
}
::v-deep .search-modal-content {
.search-modal-content {
height: 70vh;
display: flex;
flex-direction: column;
}
::v-deep .search-input-wrapper {
.search-input-wrapper {
padding: 20px;
border-bottom: 1px solid #f0f0f0;
// background: #fff;
@@ -449,7 +451,7 @@ export default {
}
}
::v-deep .search-results {
.search-results {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
@@ -474,7 +476,7 @@ export default {
}
}
::v-deep .section-title {
.section-title {
padding: 12px 24px 6px;
font-size: 12px;
line-height: 1.5;
@@ -503,12 +505,12 @@ export default {
.clear-icon {
font-size: 14px;
color: red;
color: red;
}
}
}
::v-deep .list {
.list {
list-style: none;
margin: 0;
padding: 0;
@@ -579,15 +581,15 @@ export default {
}
}
::v-deep .loading,
::v-deep .empty {
.loading,
.empty {
padding: 32px 24px;
color: #909399;
text-align: center;
font-size: 14px;
}
::v-deep .section.placeholder {
.section.placeholder {
padding: 32px 24px;
.placeholder-content {
@@ -635,3 +637,4 @@ export default {
}
}
</style>

View File

@@ -167,7 +167,8 @@ export default {
}
</script>
<style lang="scss" scoped>
<style lang='scss' scoped>
.page.no-title {
::v-deep {
.page-submenu .el-tabs__header {
@@ -198,14 +199,6 @@ export default {
opacity: 1;
}
}
&.is-disabled {
cursor: not-allowed;
&:hover {
color: #c0c4cc;
}
}
}
.el-tabs__nav-next {

View File

@@ -276,8 +276,10 @@ export default {
}
}
}
</style>
// reset element css of el-icon-close
<style lang="scss">
//reset element css of el-icon-close
.tags-view-wrapper {
.tags-view-item {
.el-icon-close {

View File

@@ -123,16 +123,6 @@ 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

@@ -149,11 +149,6 @@ export function getErrorResponseMsg(error) {
.join('; ')
} else if (typeof data === 'string') {
return data
} else if (_.isPlainObject(data)) {
return Object.values(data)
.map(item => getErrorResponseMsg(item))
.filter(i => i)
.join('; ')
} else {
msg = error.toString()
}

View File

@@ -144,6 +144,11 @@ export default {
deep: true
}
},
mounted() {
if (!this.$store.getters.hasValidLicense) {
delete this.fields[3]
}
},
methods: {
handleAfterGetRemoteMeta(meta) {
const needSetOptionFields = [

View File

@@ -43,9 +43,7 @@ export default {
asset: ''
},
treeSetting: {
showMenu: (node) => {
return node?.meta?.type === 'asset'
},
showMenu: true,
showRefresh: true,
showSearch: true,
showAssets: true,
@@ -57,7 +55,7 @@ export default {
menu: [
{
id: 'check',
name: this.$t('RiskDetection'),
name: this.$t('Check'),
icon: 'scan',
callback: (node) => {
vm.detectDialog.asset = node.id

View File

@@ -6,6 +6,7 @@
class="risk-review-drawer"
destroy-on-close
direction="rtl"
style="z-index: 999"
>
<div class="drawer-container">
<div class="drawer-body">

View File

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

View File

@@ -17,8 +17,6 @@ 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'
@@ -48,8 +46,7 @@ export const publicHostProviders = [
gcp,
ucloud,
volcengine,
smartx,
ctyun
smartx
]
export const publicDBProviders = [aliyun]
@@ -144,12 +141,6 @@ 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

@@ -143,20 +143,7 @@ export default {
disabled: !this.canEdit
},
callbacks: Object.freeze({
click: async () => {
try {
await this.$confirm(
this.$t('overwriteProtocolsAndPortsMsg'),
this.$t('Confirm'),
{
confirmButtonText: this.$t('Confirm'),
cancelButtonText: this.$t('Cancel'),
type: 'warning'
}
)
} catch (e) {
return
}
click: () => {
const data = { platform_id: this.object.id }
this.$axios.post(
'/api/v1/assets/assets/sync-platform-protocols/', data).then(res => {

View File

@@ -125,21 +125,17 @@ export default {
}
</script>
<style lang="scss" scoped>
<style lang="scss">
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$input-bg: #283443;
$input-light-gray: #fff;
$input-cursor: #fff;
$bg:#283443;
$light_gray:#fff;
$cursor: #fff;
$login-bg: #2d3a4b;
$login-dark-gray: #889aa4;
$login-light-gray: #eee;
@supports (-webkit-mask: none) and (not (cater-color: $input-cursor)) {
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $input-cursor;
color: $cursor;
}
}
@@ -151,17 +147,17 @@ $login-light-gray: #eee;
input {
background: transparent;
border: 0;
border: 0px;
-webkit-appearance: none;
border-radius: 0;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: $input-light-gray;
color: $light_gray;
height: 47px;
caret-color: $input-cursor;
caret-color: $cursor;
&:-webkit-autofill {
box-shadow: 0 0 0 1000px $input-bg inset !important;
-webkit-text-fill-color: $input-cursor !important;
box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: $cursor !important;
}
}
}
@@ -173,11 +169,17 @@ $login-light-gray: #eee;
color: #454545;
}
}
</style>
<style lang="scss" scoped>
$bg:#2d3a4b;
$dark_gray:#889aa4;
$light_gray:#eee;
.login-container {
min-height: 100%;
width: 100%;
background-color: $login-bg;
background-color: $bg;
overflow: hidden;
.login-form {
@@ -203,7 +205,7 @@ $login-light-gray: #eee;
.svg-container {
padding: 6px 5px 6px 15px;
color: $login-dark-gray;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
@@ -214,7 +216,7 @@ $login-light-gray: #eee;
.title {
font-size: 26px;
color: $login-light-gray;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
@@ -226,7 +228,7 @@ $login-light-gray: #eee;
right: 10px;
top: 7px;
font-size: 16px;
color: $login-dark-gray;
color: $dark_gray;
cursor: pointer;
user-select: none;
}

View File

@@ -515,8 +515,6 @@ export default {
this.setBtn()
this.selectAssets = assets
this.selectNodes = nodes
}).catch(() => {
this.lastRequestPayload = null
})
},
viewConfirmRunAssets() {
@@ -527,8 +525,8 @@ export default {
.then(() => {
this.xterm.write(
'\x1b[31m' +
this.$tc('StopLogOutput').replace('currentTaskId', this.currentTaskId) +
'\x1b[0m'
this.$tc('StopLogOutput').replace('currentTaskId', this.currentTaskId) +
'\x1b[0m'
)
this.xterm.write(this.wrapperError(''))
this.getTaskStatus()

View File

@@ -67,28 +67,28 @@ export default {
}
</script>
<style lang="scss" scoped>
::v-deep .help-dialog.dialog .el-dialog__footer {
<style>
.help-dialog.dialog .el-dialog__footer {
border-top: none;
padding: 8px;
}
</style>
<style lang="scss" scoped>
.help-table {
width: 100%;
border-collapse: collapse;
border: 1px solid #dee2e6;
}
::v-deep .help-table th,
::v-deep .help-table td {
height: 40px;
padding: 0 8px;
text-align: left;
}
&::v-deep th, td {
height: 40px;
padding: 0 8px;
text-align: left;
}
::v-deep .help-table .item-td,
::v-deep .help-table .item-label {
cursor: pointer;
color: var(--color-primary);
&::v-deep .item-td, .item-label {
cursor: pointer;
color: var(--color-primary);
}
}
</style>

View File

@@ -2,14 +2,14 @@
<div class="asset-select">
<el-card>
<div slot="header" class="clearfix">
<span>{{ $t('selectedAssets') }}({{ selectAssets.length }})</span>
<span>已选资产({{ selectAssets.length }})</span>
<el-button
v-if="selectAssets.length > 0"
style="float: right; padding: 3px 0"
type="text"
@click="handleClick"
>
{{ $t('pleaseSelectAssets') }}
请选择资产
</el-button>
</div>
<div
@@ -21,8 +21,8 @@
@click=" handleClick()"
>
<i class="icon el-icon-plus" />
<span class="title">{{ $t('pleaseSelectAssets') }}</span>
<span class="subtitle">{{ $t('clickToAdd') }}</span>
<span class="title">请选择资产</span>
<span class="subtitle">点击添加</span>
</div>
<div v-else class="asset-list">
<div
@@ -62,7 +62,7 @@
>{{ item.name }}</span>
<i
class="el-icon-minus asset-remove-icon"
:title="$tc('Remove')"
title="移除"
@click.stop="removeAsset(item)"
/>
</el-checkbox>

View File

@@ -1,72 +1,66 @@
<template>
<TwoCol>
<template>
<AutoDetailCard :excludes="excludes" :fields="detailFields" :object="object" :url="url" />
<AutoDetailCard
:excludes="excludes"
:fields="detailFields"
:object="object"
:url="url"
/>
</template>
<template v-if="hasSummary" #right class="detail-right-quick-actions">
<IBox
v-if="object.summary.ok"
:title="`${$tc('SuccessAsset')} (${object.summary.ok.length})`"
:title="`${$tc('SuccessAsset')} (${object.summary.ok.length})` "
type="success"
>
<el-collapse>
<el-collapse-item
v-for="(item, index) in object.summary.ok"
v-for="(item,index) in object.summary.ok"
:key="index"
:name="index"
:title="item"
disabled
>
<template #title>
<el-tooltip :content="item" placement="top" class="text-overflow">
<span>{{ item }}</span>
</el-tooltip>
</template>
</el-collapse-item>
/>
</el-collapse>
</IBox>
<IBox
v-if="object.summary.excludes"
:title="`${$tc('ExcludeAsset')} (${Object.keys(object.summary.excludes).length})`"
:title="`${$tc('ExcludeAsset')} (${Object.keys(object.summary.excludes).length})` "
type="warning"
>
<el-collapse>
<el-collapse-item
v-for="(val, key, index) in object.summary.excludes"
v-for="(val,key,index) in object.summary.excludes"
:key="index"
:name="index"
:title="key"
>
<template #title>
<el-tooltip :content="key" placement="top" class="text-overflow">
<span>{{ key }}</span>
</el-tooltip>
</template>
<div>{{ $tc('Reason') }}: {{ val }}</div>
</el-collapse-item>
</el-collapse>
</IBox>
<IBox
v-if="object.summary.failures"
:title="`${$tc('FailedAsset')} (${Object.keys(Object.assign(object.summary.failures, object.summary.dark)).length})`"
:title="`${$tc('FailedAsset')} (${Object.keys(Object.assign(object.summary.failures,object.summary.dark)).length})` "
type="danger"
>
<el-collapse>
<el-collapse-item
v-for="(val, key, index) in Object.assign(object.summary.failures, object.summary.dark)"
v-for="(val,key,index) in Object.assign(object.summary.failures,object.summary.dark)"
:key="index"
:name="index"
:title="key"
>
<template #title>
<el-tooltip :content="key" placement="top" class="text-overflow">
<span>{{ key }}</span>
</el-tooltip>
</template>
<div>{{ $tc('Reason') }}: {{ val }}</div>
</el-collapse-item>
</el-collapse>
</IBox>
<IBox v-if="object.summary.error" :title="$tc('SystemError')" type="danger">
<IBox
v-if="object.summary.error"
:title="$tc('SystemError') "
type="danger"
>
{{ object.summary.error }}
</IBox>
</template>
@@ -92,10 +86,11 @@ export default {
},
data() {
return {
excludes: ['job', 'parameters', 'summary', 'task_id', 'timedelta'],
excludes: [
'job', 'parameters', 'summary', 'task_id', 'timedelta'
],
detailFields: [
'task_id',
'time_cost',
'task_id', 'time_cost',
{
key: this.$t('IsFinished'),
value: this.object.is_finished ? this.$t('Yes') : this.$t('No')
@@ -104,12 +99,8 @@ export default {
key: this.$t('IsSuccess'),
value: this.object.is_success ? this.$t('Yes') : this.$t('No')
},
'job_type',
'material',
'org_name',
'date_start',
'date_finished',
'date_created'
'job_type', 'material', 'org_name',
'date_start', 'date_finished', 'date_created'
],
url: `/api/v1/ops/job-executions/${this.object.id}/`
}

View File

@@ -408,6 +408,7 @@ export default {
createJob(data).then(res => {
this.progressLength = 0
this.executionInfo.timeCost = 0
this.showProgress = true
this.speedText = ''
const form = new FormData()
const start = Date.now()
@@ -435,13 +436,13 @@ export default {
}
}
}).then(res => {
this.showProgress = true
this.executionInfo.status = 'running'
this.currentTaskId = res.task_id
this.xtermConfig = { taskId: this.currentTaskId, type: 'shortcut_cmd' }
this.setCostTimeInterval()
this.writeExecutionOutput()
}).catch(() => {
}).catch((error) => {
this.$message.error(this.$tc('Error'), error)
this.execute_stop()
})
})

View File

@@ -224,12 +224,11 @@ export default {
title: this.$t('ExecuteAfterSaving'),
callback: (value, form, btn) => {
form.value.run_after_save = true
if (form.value?.variable) {
form.value['parameters'] = form.value.variable.reduce((acc, item) => {
acc[item.var_name] = item.default_value || ''
return acc
}, {})
}
const parameters = form.value.variable.reduce((acc, item) => {
acc[item.var_name] = item.default_value || ''
return acc
}, {})
form.value['parameters'] = parameters
this.submitForm(form, btn)
}
}

View File

@@ -110,8 +110,6 @@ export default {
type: 'input',
component: AccountFormatter,
el: {
enableExcludeAccounts: true,
enableNoneAccount: true,
assets: [],
nodes: []
},

View File

@@ -3,7 +3,7 @@
<el-form-item>
<el-radio-group v-model="realRadioSelected" @input="handleRadioChanged">
<el-radio
v-for="(i) in iRealChoices"
v-for="(i) in realChoices"
:key="i.label"
:disabled="i.disabled"
:label="i.value"
@@ -125,14 +125,6 @@ export default {
type: Boolean,
default: true
},
enableNoneAccount: {
type: Boolean,
default: false
},
enableExcludeAccounts: {
type: Boolean,
default: false
},
addTemplateHelpText: {
type: String,
default() {
@@ -193,18 +185,6 @@ export default {
computed: {
virtualAccount() {
return virtualAccount
},
iRealChoices: {
get() {
let choices = this.realChoices.slice()
if (!this.enableNoneAccount) {
choices = choices.filter(i => i.value !== NoneAccount)
}
if (!this.enableExcludeAccounts) {
choices = choices.filter(i => i.value !== ExcludeAccount)
}
return choices
}
}
},
watch: {

View File

@@ -1,77 +0,0 @@
<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

@@ -32,22 +32,6 @@ export default {
}
}
},
computed: {
passwordMenuDisabled() {
return this.$store.state.users.profile.source.value !== 'local'
}
},
watch: {
passwordMenuDisabled: {
immediate: true,
handler(disabled) {
this.config.submenu = this.getSubmenu()
if (disabled && this.config.activeMenu === 'Password') {
this.config.activeMenu = 'SSHKeyList'
}
}
}
},
methods: {
getSubmenu() {
return [

View File

@@ -222,11 +222,13 @@ export default {
}
</script>
<style lang="scss" scoped>
::v-deep .el-select-dropdown.select-org-dropdown {
<style>
.el-select-dropdown.select-org-dropdown {
max-width: 300px !important;
}
</style>
<style lang="scss" scoped>
.org-select {
float: left;
width: 300px;
@@ -243,4 +245,5 @@ export default {
width: 180px !important;
}
}
</style>

View File

@@ -73,28 +73,28 @@ export default {
}
</script>
<style lang="scss" scoped>
::v-deep .help-dialog.dialog .el-dialog__footer {
<style>
.help-dialog.dialog .el-dialog__footer {
border-top: none;
padding: 8px;
}
</style>
<style lang="scss" scoped>
.help-table {
width: 100%;
border-collapse: collapse;
border: 1px solid #dee2e6;
}
::v-deep .help-table th,
::v-deep .help-table td {
height: 40px;
padding: 0 8px;
text-align: left;
}
&::v-deep th, td {
height: 40px;
padding: 0 8px;
text-align: left;
}
::v-deep .help-table .item-td,
::v-deep .help-table .item-label {
cursor: pointer;
color: var(--color-primary);
&::v-deep .item-td, .item-label {
cursor: pointer;
color: var(--color-primary);
}
}
</style>

View File

@@ -219,12 +219,11 @@ export default {
}
</script>
<style lang="scss" scoped>
:global(.el-popover.el-popper.monitor-popover) {
<style lang="scss">
.el-popover.el-popper.monitor-popover {
ul {
padding-left: 15px;
margin: 0;
li {
line-height: 24px;
color: var(--color-primary);
@@ -232,19 +231,19 @@ export default {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&:hover {
filter: opacity(65%) !important;
filter: opacity(65%)!important;
}
}
}
}
</style>
<style lang="less" scoped>
.echarts {
width: 100%;
height: 150px;
}
.name {
display: inline-block;
margin-bottom: 8px;
@@ -257,7 +256,6 @@ export default {
justify-content: space-between;
font-size: 14px;
margin-bottom: 8px;
.num {
margin-left: 2px;
cursor: pointer;
@@ -281,9 +279,9 @@ export default {
line-height: 20px;
padding: 2px 0;
color: #fff;
-webkit-transition: width 0.6s ease;
-o-transition: width 0.6s ease;
transition: width 0.6s ease;
-webkit-transition: width .6s ease;
-o-transition: width .6s ease;
transition: width .6s ease;
overflow: hidden;
}
@@ -294,11 +292,9 @@ export default {
margin-right: 5px;
border-radius: 4px;
background-color: currentColor;
&:hover {
transform: scale(1.2);
}
&:last-child {
margin-right: 0;
}
@@ -307,7 +303,6 @@ export default {
.session {
margin-top: 13px;
border-left: 1px solid #f3f3f3;
.session-title {
margin-bottom: 8px;
color: #a3a3a4;

View File

@@ -147,7 +147,7 @@ export default {
this.loading = true
const url = `/api/v1/tickets/comments/?ticket_id=${this.object.id}`
this.$axios.get(url).then(res => {
this.comments = res
this.comments = res.results
}).catch(err => {
this.$message.error(err)
}).finally(() => {

View File

@@ -115,12 +115,14 @@ export default {
}
</script>
<style lang="scss" scoped>
::v-deep .acceptance .el-message-box__content {
<style>
.acceptance .el-message-box__content {
overflow-y: auto;
max-height: 400px;
}
</style>
<style lang='scss' scoped>
.box {
margin-bottom: 15px;
}

View File

@@ -161,7 +161,8 @@ module.exports = {
target: process.env.VUE_APP_CORE_HOST || 'http://127.0.0.1:8080',
changeOrigin: true
}
}
},
after: require('./mock/mock-server.js')
},
css: {},
configureWebpack: {

View File

@@ -2340,13 +2340,13 @@ axios-retry@^3.1.9:
"@babel/runtime" "^7.15.4"
is-retry-allowed "^2.2.0"
axios@0.28.0:
version "0.28.0"
resolved "https://registry.npmmirror.com/axios/-/axios-0.28.0.tgz#801a4d991d0404961bccef46800e1170f8278c89"
integrity sha512-Tu7NYoGY4Yoc7I+Npf9HhUMtEEpV7ZiLH9yndTCoNhcpBH0kwcvFbzYN9/u5QKI5A6uefjsNNWaz5olJVYS62Q==
axios@0.30.2:
version "0.30.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.30.2.tgz#256d3a8ee765cc27188d08b8b545a5f5a0c77dad"
integrity sha512-0pE4RQ4UQi1jKY6p7u6i1Tkzqmu+d+/tHS7Q7rKunWLB9WyilBTpHHpXzPNMDj5hTbK0B0PTLSz07yqMBiF6xg==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
follow-redirects "^1.15.4"
form-data "^4.0.4"
proxy-from-env "^1.1.0"
babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
@@ -6302,7 +6302,7 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
follow-redirects@^1.0.0, follow-redirects@^1.15.0:
follow-redirects@^1.0.0, follow-redirects@^1.15.4:
version "1.15.11"
resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340"
integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==
@@ -6339,9 +6339,9 @@ forever-agent@~0.6.1:
resolved "https://registry.npmmirror.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
form-data@^4.0.0:
form-data@^4.0.4:
version "4.0.4"
resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
dependencies:
asynckit "^0.4.0"
@@ -6916,7 +6916,7 @@ hasown@^2.0.0, hasown@^2.0.2:
dependencies:
function-bind "^1.1.2"
he@1.2.x, he@^1.1.1, he@^1.2.0:
he@1.2.x, he@^1.1.0, he@^1.1.1:
version "1.2.0"
resolved "https://registry.npmmirror.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
@@ -14423,27 +14423,32 @@ vue-style-loader@^4.1.0:
hash-sum "^1.0.2"
loader-utils "^1.0.2"
vue-template-compiler@2.7.16:
version "2.7.16"
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz#c81b2d47753264c77ac03b9966a46637482bb03b"
integrity sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==
vue-template-compiler@2.6.10:
version "2.6.10"
resolved "https://registry.npmmirror.com/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz#323b4f3495f04faa3503337a82f5d6507799c9cc"
integrity sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==
dependencies:
de-indent "^1.0.2"
he "^1.2.0"
he "^1.1.0"
vue-template-es2015-compiler@^1.6.0, vue-template-es2015-compiler@^1.9.0:
version "1.9.1"
resolved "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
vue@2.6.10:
version "2.6.10"
resolved "https://registry.npmmirror.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==
vue@2.6.11:
version "2.6.11"
resolved "https://registry.npmmirror.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
vue@2.7.16, vue@^2.2.6:
vue@^2.2.6:
version "2.7.16"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.7.16.tgz#98c60de9def99c0e3da8dae59b304ead43b967c9"
resolved "https://registry.npmmirror.com/vue/-/vue-2.7.16.tgz#98c60de9def99c0e3da8dae59b304ead43b967c9"
integrity sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==
dependencies:
"@vue/compiler-sfc" "2.7.16"