merge: with v3 (#2250)

* perf: 增加celery输出

* fix: 修复网域列表资产选中后更新时不显示选中问题

* fix: 选择资产时会根据接口返回状态设置disabled

* feat: 资产选择form 匹配正确的字段

* feat: 资产选择form 匹配正确的字段

* perf: 优化仪表盘环形图数据显示

* feat: 修改资产选择组件支持我的资产选择

* fix: 改密计划选择资产组件添加disabled状态

* fix: 修复资产账号点击资产树接口500问题

* fix: 更新网域选择资产组件添加disabled状态

* perf: 优化显示

* perf: 修改 Domain 列表页面

* perf: 修改网域列表网关字段跳转

* perf: 修改 GatewayList 页面

* perf: 选择资产组件弹窗显示资产详情

* perf: 修改资产详情账号列表页面

* perf: 修改资产账号详情

* fix: 修复改密详情页面报错误提示问题

* fix: 修复资产树点击资产接口报错问题

Co-authored-by: Aaron3S <chenyang@fit2cloud.com>
Co-authored-by: “huailei000” <2280131253@qq.com>
Co-authored-by: Bai <baijiangjie@gmail.com>
This commit is contained in:
fit2bot
2022-12-06 17:04:53 +08:00
committed by GitHub
parent a272fbb542
commit 791f173cea
26 changed files with 225 additions and 129 deletions

View File

@@ -98,11 +98,24 @@ export default {
columnsShow: { columnsShow: {
min: ['name', 'username', 'actions'], min: ['name', 'username', 'actions'],
default: [ default: [
'name', 'hostname', 'ip', 'username', 'name', 'username', 'version', 'privileged', 'actions', 'secret_type', 'actions'
'version', 'privileged', 'actions'
] ]
}, },
columnsMeta: { columnsMeta: {
name: {
showOverflowTooltip: true,
formatter: function(row) {
const to = {
name: 'AssetAccountDetail',
params: { id: row.id }
}
if (vm.$hasPerm('assets.view_account')) {
return <router-link to={ to } >{ row.name }</router-link>
} else {
return <span>{ row.name }</span>
}
}
},
asset: { asset: {
label: this.$t('assets.Asset'), label: this.$t('assets.Asset'),
showOverflowTooltip: true, showOverflowTooltip: true,

View File

@@ -31,7 +31,7 @@
<script> <script>
import TreeTable from '@/components/TreeTable' import TreeTable from '@/components/TreeTable'
import { DetailFormatter } from '@/components/TableFormatters' import { DialogDetailFormatter } from '@/components/TableFormatters'
import Select2 from '@/components/FormFields/Select2' import Select2 from '@/components/FormFields/Select2'
import Dialog from '@/components/Dialog' import Dialog from '@/components/Dialog'
@@ -39,6 +39,14 @@ export default {
componentName: 'AssetSelect', componentName: 'AssetSelect',
components: { TreeTable, Select2, Dialog }, components: { TreeTable, Select2, Dialog },
props: { props: {
baseUrl: {
type: String,
default: '/api/v1/assets/assets/'
},
baseNodeUrl: {
type: String,
default: '/api/v1/assets/nodes/'
},
value: { value: {
type: Array, type: Array,
default: () => [] default: () => []
@@ -55,12 +63,20 @@ export default {
} }
}, },
data() { data() {
const iValue = []
for (const item of this.value) {
if (typeof item === 'object') {
iValue.push(item.id)
} else {
iValue.push(item)
}
}
const select2Config = { const select2Config = {
value: this.value, value: iValue,
multiple: true, multiple: true,
clearable: true, clearable: true,
ajax: { ajax: {
url: '/api/v1/assets/assets/?fields_size=mini', url: this.baseUrl,
transformOption: (item) => { transformOption: (item) => {
return { label: item.name + '(' + item.address + ')', value: item.id } return { label: item.name + '(' + item.address + ')', value: item.id }
} }
@@ -69,24 +85,22 @@ export default {
const vm = this const vm = this
return { return {
dialogVisible: false, dialogVisible: false,
initialValue: _.cloneDeep(this.value), initialValue: _.cloneDeep(iValue),
rowSelected: [], rowSelected: [],
initSelection: null, initSelection: null,
treeSetting: { treeSetting: {
showMenu: false, showMenu: false,
showRefresh: true, showRefresh: true,
showAssets: false, showAssets: false,
showSearch: true, url: this.baseUrl,
customTreeHeader: true, nodeUrl: this.baseNodeUrl,
url: '/api/v1/assets/assets/?fields_size=mini',
nodeUrl: '/api/v1/assets/nodes/',
// ?assets=0不显示资产. =1显示资产 // ?assets=0不显示资产. =1显示资产
treeUrl: '/api/v1/assets/nodes/children/tree/?assets=0' treeUrl: `${this.baseNodeUrl}/children/tree/?assets=0`
}, },
select2Config: select2Config, select2Config: select2Config,
dialogSelect2Config: select2Config, dialogSelect2Config: select2Config,
tableConfig: { tableConfig: {
url: '/api/v1/assets/assets/?fields_size=mini', url: this.baseUrl,
hasTree: true, hasTree: true,
canSelect: this.canSelect, canSelect: this.canSelect,
columns: [ columns: [
@@ -95,25 +109,65 @@ export default {
label: this.$t('assets.Name'), label: this.$t('assets.Name'),
sortable: true, sortable: true,
showOverflowTooltip: true, showOverflowTooltip: true,
formatter: DetailFormatter, formatter: DialogDetailFormatter,
formatterArgs: { formatterArgs: {
route: 'AssetDetail' getDialogTitle: function({ col, row }) { this.$t('assets.AssetDetail') }.bind(this),
getDetailItems: function({ col, row }) {
return [
{
key: this.$t('assets.Name'),
value: row.name
},
{
key: this.$t('assets.AssetAddress'),
value: row.address
},
{
key: this.$t('assets.Protocols'),
value: row.protocols.map(item => item.name).join(', ')
},
{
key: this.$t('assets.Category'),
value: row.category.label
},
{
key: this.$t('assets.Type'),
value: row.type.label
},
{
key: this.$t('assets.Platform'),
value: row.platform?.name || ''
},
{
key: this.$t('common.Active'),
value: row.is_active
},
{
key: this.$t('assets.Comment'),
value: row.comment
}
]
}.bind(this)
} }
}, },
{ {
prop: 'ip', prop: 'address',
label: this.$t('assets.ipDomain'), label: this.$t('assets.ipDomain'),
sortable: 'custom' sortable: 'custom'
}, },
{ {
prop: 'platform', prop: 'platform',
label: this.$t('assets.Platform'), label: this.$t('assets.Platform'),
sortable: true sortable: true,
formatter: function(row) {
return row.platform.name
}
}, },
{ {
prop: 'protocols', prop: 'protocols',
formatter: function(row) { formatter: function(row) {
return <span> {row.protocols?.toString()} </span> const data = row.protocols.map(p => <el-tag size='mini'>{p.name}/{p.port} </el-tag>)
return <span> {data} </span>
}, },
label: this.$t('assets.Protocols') label: this.$t('assets.Protocols')
} }
@@ -128,7 +182,7 @@ export default {
} }
}, },
theRowDefaultIsSelected: (row) => { theRowDefaultIsSelected: (row) => {
return this.value.indexOf(row.id) > -1 return iValue.indexOf(row.id) > -1
} }
}, },
headerActions: { headerActions: {
@@ -215,5 +269,4 @@ export default {
.page ::v-deep .treebox { .page ::v-deep .treebox {
height: inherit !important; height: inherit !important;
} }
</style> </style>

View File

@@ -128,9 +128,9 @@ export default {
query['asset'] = '' query['asset'] = ''
url = `${this.setting.url}${combinator}node_id=${objectId}&show_current_asset=${show_current_asset}` url = `${this.setting.url}${combinator}node_id=${objectId}&show_current_asset=${show_current_asset}`
} else if (treeNode.meta.type === 'asset') { } else if (treeNode.meta.type === 'asset') {
query['asset'] = treeNode.meta.data.id query['asset'] = treeNode.meta.data?.id || treeNode.id
query['node'] = '' query['node'] = ''
url = `${this.setting.url}${combinator}asset_id=${objectId}&show_current_asset=${show_current_asset}` url = `${this.setting.url}${combinator}asset_id=${query.asset}&show_current_asset=${show_current_asset}`
} }
this.$router.push({ query }) this.$router.push({ query })
this.$emit('urlChange', url) this.$emit('urlChange', url)

View File

@@ -68,7 +68,9 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.card >>> .el-card__body { .card >>> .el-card__body {
padding: 0 padding: 0;
}
.el-card {
border: 0!important;
} }
</style> </style>

View File

@@ -104,6 +104,7 @@
}, },
"assets": { "assets": {
"UserSwitchFrom": "User switch from", "UserSwitchFrom": "User switch from",
"AssetAddress": "IP/Host",
"sshkeyAccount": "ssh key account", "sshkeyAccount": "ssh key account",
"passwordAccount": "Password account", "passwordAccount": "Password account",
"SelectTemplate": "Select template", "SelectTemplate": "Select template",
@@ -180,6 +181,7 @@
"DomainHelpMessage": "The domain function is added to address the fact that some environments (such as the hybrid cloud) cannot be connected directly by jumping on the gateway server.\nJMS => Domain gateway => Target assets", "DomainHelpMessage": "The domain function is added to address the fact that some environments (such as the hybrid cloud) cannot be connected directly by jumping on the gateway server.\nJMS => Domain gateway => Target assets",
"FullName": "Full name", "FullName": "Full name",
"Gateway": "Gateway", "Gateway": "Gateway",
"GatewayList": "Gateway",
"GatewayProtocolHelpText": "SSH protocol gateway, support proxy SSH, RDP, VNC", "GatewayProtocolHelpText": "SSH protocol gateway, support proxy SSH, RDP, VNC",
"Hostname": "Hostname", "Hostname": "Hostname",
"IP": "IP", "IP": "IP",
@@ -412,7 +414,6 @@
"Push": "Push", "Push": "Push",
"Receivers": "Receivers", "Receivers": "Receivers",
"QuickUpdate": "Quick update", "QuickUpdate": "Quick update",
"QuickSelect": "Quick select",
"RemoveSuccessMsg": "Remove success", "RemoveSuccessMsg": "Remove success",
"Reset": "Reset", "Reset": "Reset",
"Search": "Search", "Search": "Search",

View File

@@ -109,6 +109,7 @@
"NoSQLProtocol": "非リレーショナルデータベース" "NoSQLProtocol": "非リレーショナルデータベース"
}, },
"assets": { "assets": {
"AssetAddress": "IP/ホスト名",
"UserSwitchFrom": "ユーザーは", "UserSwitchFrom": "ユーザーは",
"sshkeyAccount": "SSHキー", "sshkeyAccount": "SSHキー",
"passwordAccount": "パスワード", "passwordAccount": "パスワード",

View File

@@ -419,6 +419,7 @@
"DateLast3Months": "最近三月", "DateLast3Months": "最近三月",
"DateLastMonth": "最近一月", "DateLastMonth": "最近一月",
"DateLastWeek": "最近一周", "DateLastWeek": "最近一周",
"DateStart": "开始日期",
"Delete": "删除", "Delete": "删除",
"Disable": "禁用", "Disable": "禁用",
"Download": "下载", "Download": "下载",
@@ -493,7 +494,6 @@
"dateCreated": "创建日期", "dateCreated": "创建日期",
"dateExpired": "失效日期", "dateExpired": "失效日期",
"dateFinished": "完成日期", "dateFinished": "完成日期",
"DateStart": "开始日期",
"deleteErrorMsg": "删除失败", "deleteErrorMsg": "删除失败",
"deleteFailedMsg": "删除失败", "deleteFailedMsg": "删除失败",
"deleteSelected": "删除所选", "deleteSelected": "删除所选",
@@ -1675,7 +1675,6 @@
"OpenStack": "OpenStack", "OpenStack": "OpenStack",
"GCP": "谷歌云", "GCP": "谷歌云",
"FC": "Fusion Compute", "FC": "Fusion Compute",
"LAN": "局域网",
"AWS_China": "AWS(中国)", "AWS_China": "AWS(中国)",
"AWS_Int": "AWS(国际)", "AWS_Int": "AWS(国际)",
"HuaweiCloud": "华为云", "HuaweiCloud": "华为云",

View File

@@ -33,7 +33,7 @@ export default {
return { return {
quickActions: [ quickActions: [
{ {
title: this.$t('assets.PrivilegedTemplate'), title: this.$t('assets.Privileged'),
type: 'switcher', type: 'switcher',
attrs: { attrs: {
model: vm.object.privileged, model: vm.object.privileged,

View File

@@ -45,7 +45,7 @@ export default {
url = setUrlParam(url, 'asset', '') url = setUrlParam(url, 'asset', '')
url = setUrlParam(url, 'node', nodeId) url = setUrlParam(url, 'node', nodeId)
} else if (treeNode.meta.type === 'asset') { } else if (treeNode.meta.type === 'asset') {
const assetId = treeNode.meta.data.id const assetId = treeNode.meta.data?.id || treeNode?.id
url = setUrlParam(url, 'node', '') url = setUrlParam(url, 'node', '')
url = setUrlParam(url, 'asset', assetId) url = setUrlParam(url, 'asset', assetId)
} }

View File

@@ -23,8 +23,8 @@ export default {
return { return {
plan: { name: '', username: '', comment: '' }, plan: { name: '', username: '', comment: '' },
config: { config: {
activeMenu: 'ChangeAuthPlanInfo', activeMenu: 'ChangeSecreAtutomationInfo',
url: '/api/v1/assets/change-secret-automations/', url: '/api/v1/assets/change-secret-automations',
submenu: [ submenu: [
{ {
title: this.$t('common.BasicInfo'), title: this.$t('common.BasicInfo'),

View File

@@ -52,6 +52,11 @@ export const getFields = () => {
rules: [ rules: [
{ required: false } { required: false }
], ],
el: {
canSelect: (row) => {
return row.enabled_info.change_secret_enabled
}
},
label: i18n.t('xpack.Asset') label: i18n.t('xpack.Asset')
}, },
passphrase: { passphrase: {

View File

@@ -98,7 +98,7 @@ export default {
url = setUrlParam(url, 'asset', '') url = setUrlParam(url, 'asset', '')
url = setUrlParam(url, 'node', nodeId) url = setUrlParam(url, 'node', nodeId)
} else if (treeNode.meta.type === 'asset') { } else if (treeNode.meta.type === 'asset') {
const assetId = treeNode.meta.data.id const assetId = treeNode.meta.data?.id || treeNode.id
url = setUrlParam(url, 'node', '') url = setUrlParam(url, 'node', '')
url = setUrlParam(url, 'asset', assetId) url = setUrlParam(url, 'asset', assetId)
} }

View File

@@ -23,7 +23,10 @@ export default {
component: AssetSelect, component: AssetSelect,
label: this.$t('assets.Assets'), label: this.$t('assets.Assets'),
el: { el: {
value: [] value: [],
canSelect: (row) => {
return row.enabled_info.domain_enabled
}
} }
} }
}, },

View File

@@ -55,8 +55,7 @@ export default {
tableConfig: { tableConfig: {
url: `/api/v1/assets/gateways/?domain=${this.$route.params.id}`, url: `/api/v1/assets/gateways/?domain=${this.$route.params.id}`,
columns: [ columns: [
'name', 'address', 'platform', 'password_account', 'name', 'address', 'platform', 'connectivity', 'is_active', 'actions'
'ssh_key_account', 'connectivity', 'is_active', 'actions'
], ],
columnsMeta: { columnsMeta: {
name: { name: {
@@ -72,34 +71,6 @@ export default {
address: { address: {
width: '140px' width: '140px'
}, },
password_account: {
label: this.$t('assets.passwordAccount'),
formatter: function(row) {
const [accountInfo] = row.effective_accounts.filter(
item => item.secret_type === 'password'
)
if (!accountInfo) return <span>-</span>
const to = {
name: 'AssetAccountDetail',
params: { id: accountInfo.id }
}
return <router-link to={ to } >{ accountInfo.username }</router-link>
}
},
ssh_key_account: {
label: this.$t('assets.sshkeyAccount'),
formatter: function(row) {
const [accountInfo] = row.effective_accounts.filter(
item => item.secret_type === 'ssh_key'
)
if (!accountInfo) return <span>-</span>
const to = {
name: 'AssetAccountDetail',
params: { id: accountInfo.id }
}
return <router-link to={ to } >{ accountInfo.username }</router-link>
}
},
actions: { actions: {
formatterArgs: { formatterArgs: {
updateRoute: 'GatewayUpdate', updateRoute: 'GatewayUpdate',

View File

@@ -28,7 +28,7 @@ export default {
name: 'Detail' name: 'Detail'
}, },
{ {
title: this.$t('assets.Gateway'), title: this.$t('assets.GatewayList'),
name: 'GatewayList', name: 'GatewayList',
hidden: () => !this.$hasPerm('assets.view_gateway') hidden: () => !this.$hasPerm('assets.view_gateway')
} }

View File

@@ -15,27 +15,32 @@ export default {
tableConfig: { tableConfig: {
url: '/api/v1/assets/domains/', url: '/api/v1/assets/domains/',
columns: [ columns: [
'name', 'asset_count', 'application_count', 'gateway_count', 'date_created', 'name', 'asset_count', 'gateway_count', 'comment',
'comment', 'org_name', 'actions' 'date_created', 'org_name', 'actions'
], ],
columnsShow: { columnsShow: {
min: ['name', 'actions'], min: ['name', 'actions'],
default: ['name', 'asset_count', 'application_count', 'gateway_count', 'comment', 'actions'] default: ['name', 'asset_count', 'gateway_count', 'comment', 'actions']
}, },
columnsMeta: { columnsMeta: {
asset_count: { asset_count: {
label: this.$t('assets.Assets') prop: 'assets',
}, label: this.$t('assets.Assets'),
application_count: { formatter: function(row) {
label: this.$t('assets.Applications') return <span> { row.assets.length } </span>
}
}, },
gateway_count: { gateway_count: {
prop: 'gateways',
label: this.$t('assets.Gateway'), label: this.$t('assets.Gateway'),
formatter: DetailFormatter, formatter: DetailFormatter,
formatterArgs: { formatterArgs: {
permissions: 'assets.view_gateway', permissions: 'assets.view_gateway',
routeQuery: { routeQuery: {
activeTab: 'GatewayList' activeTab: 'GatewayList'
},
getTitle: function({ cellValue }) {
return cellValue.length
} }
} }
} }

View File

@@ -1,10 +1,24 @@
<template> <template>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :lg="12" :sm="12" class="margin-top-16"> <el-col :lg="12" :sm="12" class="margin-top-16">
<DataCard :config="logConfig" /> <DataCard :config="logConfig">
<div class="custom">
<span>{{ logConfig.total }}</span>
<span>
<svg-icon :icon-class="logConfig.icon" class="font" />
</span>
</div>
</DataCard>
</el-col> </el-col>
<el-col :lg="12" :sm="12" class="margin-top-16"> <el-col :lg="12" :sm="12" class="margin-top-16">
<DataCard :config="assetConfig" /> <DataCard :config="assetConfig">
<div class="custom">
<span>{{ assetConfig.total }}</span>
<span>
<svg-icon :icon-class="assetConfig.icon" class="font" />
</span>
</div>
</DataCard>
</el-col> </el-col>
</el-row> </el-row>
</template> </template>
@@ -62,17 +76,22 @@ export default {
&total_count_commands=1 &total_count_commands=1
&total_count_commands_danger=1 &total_count_commands_danger=1
`) `)
const logActive = data.total_count_user_login_success_logs === 0 ? 0 : ((data.total_count_user_login_success_logs / data.total_count_user_login_logs) * 100).toFixed(0)
const logTotal = logActive === 100 ? 0 : 100 - logActive
const logs = [ const logs = [
{ name: this.$t('dashboard.ActiveUser'), value: data.total_count_user_login_logs }, { name: this.$t('dashboard.ActiveUser'), value: logActive },
{ name: this.$t('dashboard.InActiveUser'), value: data.total_count_user_login_success_logs } { name: this.$t('dashboard.InActiveUser'), value: logTotal }
] ]
this.$set(this.logConfig, 'data', logs) this.$set(this.logConfig, 'data', logs)
this.$set(this.logConfig, 'total', data.total_count_user_login_logs) this.$set(this.logConfig, 'total', data.total_count_user_login_logs)
this.$set(this.logConfig, 'active', data.total_count_user_login_success_logs) this.$set(this.logConfig, 'active', data.total_count_user_login_success_logs)
this.$set(this.logConfig, 'weekAdd', data.total_count_user_login_success_logs) this.$set(this.logConfig, 'weekAdd', data.total_count_user_login_success_logs)
const assetActive = data.total_count_commands_danger === 0 ? 0 : ((data.total_count_commands_danger / data.total_count_commands) * 100).toFixed(0)
const assetTotal = assetActive === 100 ? 0 : 100 - assetActive
const assets = [ const assets = [
{ name: this.$t('dashboard.ActiveAsset'), value: data.total_count_commands }, { name: this.$t('dashboard.ActiveAsset'), value: assetActive },
{ name: this.$t('dashboard.InActiveAsset'), value: data.total_count_commands_danger } { name: this.$t('dashboard.InActiveAsset'), value: assetTotal }
] ]
this.$set(this.assetConfig, 'data', assets) this.$set(this.assetConfig, 'data', assets)
this.$set(this.assetConfig, 'total', data.total_count_commands) this.$set(this.assetConfig, 'total', data.total_count_commands)

View File

@@ -6,7 +6,7 @@
</div> </div>
<LineChart v-bind="chartConfig" /> <LineChart v-bind="chartConfig" />
</div> </div>
<SummaryCountCard :config="config" :items="summaryItems" class="margin-top-16" /> <SummaryCountCard :config="chartTitleConfig" :items="summaryItems" class="margin-top-16" />
</div> </div>
</template> </template>
@@ -33,6 +33,10 @@ export default {
title: this.$t('dashboard.SessionTrend'), title: this.$t('dashboard.SessionTrend'),
tip: this.$t('dashboard.SessionTrend') tip: this.$t('dashboard.SessionTrend')
}, },
chartTitleConfig: {
title: this.$t('route.BatchCommand'),
tip: this.$t('route.BatchCommand')
},
chartConfig: { chartConfig: {
datesMetrics: [], datesMetrics: [],
secondaryName: this.$t('dashboard.IndexName'), secondaryName: this.$t('dashboard.IndexName'),

View File

@@ -51,22 +51,27 @@ export default {
async init() { async init() {
const data = await this.$axios.get(`/api/v1/index/?total_count_users=1 const data = await this.$axios.get(`/api/v1/index/?total_count_users=1
&total_count_users_this_week=1 &total_count_users_this_week=1
&total_count_today_login_users=1 &total_count_login_users=1
&total_count_assets=1 &total_count_assets=1
&total_count_assets_this_week=1 &total_count_assets_this_week=1
&total_count_today_active_assets=1 &total_count_today_active_assets=1
`) `)
const userActive = data.total_count_login_users === 0 ? 0 : ((data.total_count_login_users / data.total_count_users) * 100).toFixed(0)
const userTotal = userActive === 100 ? 0 : 100 - userActive
const users = [ const users = [
{ name: this.$t('dashboard.ActiveUser'), value: data.total_count_users }, { name: this.$t('dashboard.ActiveUser'), value: userActive },
{ name: this.$t('dashboard.InActiveUser'), value: data.total_count_today_login_users } { name: this.$t('dashboard.InActiveUser'), value: userTotal }
] ]
this.$set(this.userConfig, 'data', users) this.$set(this.userConfig, 'data', users)
this.$set(this.userConfig, 'total', data.total_count_users) this.$set(this.userConfig, 'total', data.total_count_users)
this.$set(this.userConfig, 'active', data.total_count_today_login_users) this.$set(this.userConfig, 'active', data.total_count_login_users)
this.$set(this.userConfig, 'weekAdd', data.total_count_users_this_week) this.$set(this.userConfig, 'weekAdd', data.total_count_users_this_week)
const assetActive = data.total_count_today_active_assets === 0 ? 0 : ((data.total_count_today_active_assets / data.total_count_assets) * 100).toFixed(0)
const assetTotal = assetActive === 100 ? 0 : 100 - assetActive
const assets = [ const assets = [
{ name: this.$t('dashboard.ActiveAsset'), value: data.total_count_assets }, { name: this.$t('dashboard.ActiveAsset'), value: assetActive },
{ name: this.$t('dashboard.InActiveAsset'), value: data.total_count_today_active_assets } { name: this.$t('dashboard.InActiveAsset'), value: assetTotal }
] ]
this.$set(this.assetConfig, 'data', assets) this.$set(this.assetConfig, 'data', assets)
this.$set(this.assetConfig, 'total', data.total_count_assets) this.$set(this.assetConfig, 'total', data.total_count_assets)

View File

@@ -1,10 +1,11 @@
<template> <template>
<div class="card"> <div class="card">
<div> <div class="card-content">
<div class="title"> <div class="title">
<Title :config="config" /> <Title :config="config" />
</div> </div>
<div class="sub">{{ config.subTitle }}</div> <div class="sub">{{ config.subTitle }}</div>
<slot class="custom">
<div class="num">{{ config.total }}</div> <div class="num">{{ config.total }}</div>
<div class="add"> <div class="add">
<span class="add-num"> <span class="add-num">
@@ -15,6 +16,7 @@
<svg-icon v-if="config.icon" :icon-class="config.icon" class="font" /> <svg-icon v-if="config.icon" :icon-class="config.icon" class="font" />
</span> </span>
</div> </div>
</slot>
</div> </div>
<div class="ring"> <div class="ring">
<RingChart :config="config" /> <RingChart :config="config" />
@@ -48,6 +50,10 @@ export default {
width: 100%; width: 100%;
padding: 20px; padding: 20px;
background-color: #FFF; background-color: #FFF;
.card-content {
padding-bottom: 16px;
border-bottom: 1px solid #EFF0F1;
}
.title { .title {
margin-bottom: 12px; margin-bottom: 12px;
} }
@@ -67,8 +73,13 @@ export default {
.add { .add {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding-bottom: 16px; }
border-bottom: 1px solid #EFF0F1; .custom {
display: flex;
justify-content: space-between;
font-weight: 500;
font-size: 32px;
padding-bottom: 18px;
} }
.ring { .ring {
padding: 26px 0 10px; padding: 26px 0 10px;

View File

@@ -64,7 +64,7 @@ export default {
color: [color, 'rgba(43, 147, 124, 0.05)'], color: [color, 'rgba(43, 147, 124, 0.05)'],
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)' formatter: '{a} <br/>{b}: {d}%'
}, },
series: [ series: [
{ {

View File

@@ -59,7 +59,7 @@ export default {
value: row.name value: row.name
}, },
{ {
key: this.$t('assets.Address'), key: this.$t('assets.AssetAddress'),
value: row.address value: row.address
}, },
{ {
@@ -76,7 +76,7 @@ export default {
}, },
{ {
key: this.$t('assets.Platform'), key: this.$t('assets.Platform'),
value: row.platform value: row.platform?.name || ''
}, },
{ {
key: this.$t('common.Active'), key: this.$t('common.Active'),

View File

@@ -31,8 +31,9 @@ export default {
visible: false, visible: false,
width: '60%', width: '60%',
tableConfig: { tableConfig: {
hasSelection: false,
url: `/api/v1/ops/adhocs/`, url: `/api/v1/ops/adhocs/`,
columns: ['name', 'module', 'args', 'actions'], columns: ['name', 'module', 'args', 'comment', 'actions'],
columnsMeta: { columnsMeta: {
actions: { actions: {
formatter: ActionsFormatter, formatter: ActionsFormatter,
@@ -42,7 +43,7 @@ export default {
hasDelete: false, hasDelete: false,
extraActions: [ extraActions: [
{ {
title: '选择', title: this.$tc('common.Select'),
name: 'select', name: 'select',
can: true, can: true,
callback: ({ row }) => { callback: ({ row }) => {

View File

@@ -65,6 +65,10 @@ export default {
this.showOpenAdhocDialog = true this.showOpenAdhocDialog = true
}, },
openAdhocSaveDialog() { openAdhocSaveDialog() {
if (!this.iValue.length > 0) {
this.$message.error(this.$tc('ops.CommandNotBeNone'))
return
}
this.showOpenAdhocSaveDialog = true this.showOpenAdhocSaveDialog = true
}, },
onSelectAdhoc(adhoc) { onSelectAdhoc(adhoc) {

View File

@@ -86,6 +86,8 @@ export default {
required: false required: false
}], }],
el: { el: {
baseUrl: '/api/v1/perms/users/self/assets/',
baseNodeUrl: '/api/v1/perms/users/self/nodes/',
value: [] value: []
} }
}, },

View File

@@ -4,6 +4,7 @@
<script type="text/jsx"> <script type="text/jsx">
import ListTable from '@/components/ListTable' import ListTable from '@/components/ListTable'
import { openTaskPage } from '@/utils/jms'
export default { export default {
name: 'TaskHistory', name: 'TaskHistory',
@@ -21,13 +22,9 @@ export default {
tableConfig: { tableConfig: {
url: `/api/v1/ops/task-executions/?task_id=${this.object.id}`, url: `/api/v1/ops/task-executions/?task_id=${this.object.id}`,
columns: [ columns: [
'date_start', 'date_finished', 'state', 'is_finished', 'actions' 'date_start', 'date_finished', 'is_success', 'is_finished', 'actions'
], ],
columnsMeta: { columnsMeta: {
state: {
formatter: (row) => {
}
},
actions: { actions: {
prop: 'id', prop: 'id',
formatterArgs: { formatterArgs: {
@@ -38,10 +35,10 @@ export default {
extraActions: [ extraActions: [
{ {
name: 'detail', name: 'detail',
title: this.$t('ops.detail'), title: this.$t('ops.output'),
type: 'primary', type: 'primary',
callback: function({ row, tableData }) { callback: function({ row, tableData }) {
return this.$router.push({ name: 'HistoryExecutionDetail', params: { id: row.id }}) openTaskPage(row.id)
} }
} }
] ]