mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-20 10:46:35 +00:00
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:
@@ -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,
|
||||||
|
@@ -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>
|
||||||
|
@@ -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)
|
||||||
|
@@ -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>
|
||||||
|
@@ -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",
|
||||||
|
@@ -109,6 +109,7 @@
|
|||||||
"NoSQLProtocol": "非リレーショナルデータベース"
|
"NoSQLProtocol": "非リレーショナルデータベース"
|
||||||
},
|
},
|
||||||
"assets": {
|
"assets": {
|
||||||
|
"AssetAddress": "IP/ホスト名",
|
||||||
"UserSwitchFrom": "ユーザーは",
|
"UserSwitchFrom": "ユーザーは",
|
||||||
"sshkeyAccount": "SSHキー",
|
"sshkeyAccount": "SSHキー",
|
||||||
"passwordAccount": "パスワード",
|
"passwordAccount": "パスワード",
|
||||||
|
@@ -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": "华为云",
|
||||||
|
@@ -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,
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
|
@@ -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'),
|
||||||
|
@@ -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: {
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -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',
|
||||||
|
@@ -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')
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
|
@@ -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'),
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
@@ -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: [
|
||||||
{
|
{
|
||||||
|
@@ -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'),
|
||||||
|
@@ -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 }) => {
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Reference in New Issue
Block a user