feat: 平台选择添加最近选择的平台;云同步只在主机中保留;平台选择某种类型时不带类别;

This commit is contained in:
“huailei000”
2022-08-31 10:30:31 +08:00
committed by huailei
parent 09d6f7b82b
commit 4252fb6533
10 changed files with 207 additions and 50 deletions

View File

@@ -91,6 +91,9 @@
"NoSQLProtocol": "NoSQL Protocol" "NoSQLProtocol": "NoSQL Protocol"
}, },
"assets": { "assets": {
"All": "All",
"CloudPlatform": "Cloud platform",
"RecentlyUsed": "Recently used",
"AppList": "Application list", "AppList": "Application list",
"AssociateSystemUsers": "Associate system users", "AssociateSystemUsers": "Associate system users",
"AssociateAssets": "Associate assets", "AssociateAssets": "Associate assets",

View File

@@ -96,6 +96,9 @@
"NoSQLProtocol": "非リレーショナルデータベース" "NoSQLProtocol": "非リレーショナルデータベース"
}, },
"assets": { "assets": {
"All": "すべて",
"CloudPlatform": "クラウドプラットフォーム",
"RecentlyUsed": "最近使われる",
"AppList": "アプリケーションリスト", "AppList": "アプリケーションリスト",
"AssociateSystemUsers": "関連システムユーザー", "AssociateSystemUsers": "関連システムユーザー",
"AssociateAssets": "関連資産", "AssociateAssets": "関連資産",

View File

@@ -98,6 +98,7 @@
"assets": { "assets": {
"All": "所有", "All": "所有",
"CloudPlatform": "云平台", "CloudPlatform": "云平台",
"RecentlyUsed": "最近使用",
"AddAccount": "添加账号", "AddAccount": "添加账号",
"Account": "账号", "Account": "账号",
"Defaults": "默认值", "Defaults": "默认值",

View File

@@ -160,14 +160,6 @@ export default {
{ label: this.$t('assets.Label'), value: 'label' } { label: this.$t('assets.Label'), value: 'label' }
] ]
}, },
extraActions: [
{
name: this.$t('xpack.Cloud.CloudSync'),
title: this.$t('xpack.Cloud.CloudSync'),
has: () => vm.$hasPerm('xpack.view_account') && vm.$hasLicense(),
callback: () => this.$router.push({ name: 'CloudCenter' })
}
],
extraMoreActions: [ extraMoreActions: [
{ {
name: 'DeactiveSelected', name: 'DeactiveSelected',

View File

@@ -8,18 +8,54 @@
<script> <script>
import BaseList from './components/BaseList' import BaseList from './components/BaseList'
import { ActionsFormatter } from '@/components/TableFormatters'
export default { export default {
components: { components: {
BaseList BaseList
}, },
data() { data() {
const vm = this
return { return {
tableConfig: { tableConfig: {
url: '/api/v1/assets/hosts/' url: '/api/v1/assets/hosts/',
columnsMeta: {
actions: {
formatter: ActionsFormatter,
formatterArgs: {
performDelete: ({ row }) => {
const id = row.id
const url = `/api/v1/assets/hosts/${id}/`
return this.$axios.delete(url)
},
extraActions: [
{
name: 'View',
title: this.$t(`common.UpdateAssetDetail`),
type: 'primary',
can: vm.$hasPerm('assets.refresh_assethardwareinfo'),
callback: function({ cellValue, tableData, row }) {
return this.$router.push({
name: 'AssetMoreInformationEdit',
params: { id: row.id }
})
}
}
]
}
}
}
}, },
headerActions: { headerActions: {
createRoute: 'HostCreate' createRoute: 'HostCreate',
extraActions: [
{
name: this.$t('xpack.Cloud.CloudSync'),
title: this.$t('xpack.Cloud.CloudSync'),
has: () => vm.$hasPerm('xpack.view_account') && vm.$hasLicense(),
callback: () => this.$router.push({ name: 'CloudCenter' })
}
]
} }
} }
} }

View File

@@ -16,7 +16,7 @@ export default {
data() { data() {
return { return {
tableConfig: { tableConfig: {
url: '/api/v1/assets/networking/' url: '/api/v1/assets/networks/'
}, },
headerActions: { headerActions: {
createRoute: 'NetworkingCreate' createRoute: 'NetworkingCreate'

View File

@@ -16,7 +16,7 @@ export default {
data() { data() {
return { return {
tableConfig: { tableConfig: {
url: '/api/v1/assets/web/' url: '/api/v1/assets/webs/'
}, },
headerActions: { headerActions: {
createRoute: 'WebCreate' createRoute: 'WebCreate'

View File

@@ -94,32 +94,71 @@ export default {
actions: { actions: {
formatter: ActionsFormatter, formatter: ActionsFormatter,
formatterArgs: { formatterArgs: {
performDelete: ({ row, col }) => { performDelete: ({ row }) => {
const id = row.id const id = row.id
const url = `/api/v1/assets/assets/${id}/` const url = `/api/v1/assets/assets/${id}/`
return this.$axios.delete(url) return this.$axios.delete(url)
}, }
extraActions: [
{
name: 'View',
title: this.$t(`common.UpdateAssetDetail`),
type: 'primary',
can: vm.$hasPerm('assets.refresh_assethardwareinfo'),
callback: function({ cellValue, tableData, row }) {
return this.$router.push({ name: 'AssetMoreInformationEdit', params: { id: row.id }})
}
}
]
} }
} }
} }
}, },
defaultHeaderActions: { defaultHeaderActions: {
hasMoreActions: false,
createRoute: 'HostCreate', createRoute: 'HostCreate',
onCreate: () => { onCreate: () => {
this.showPlatform = true this.showPlatform = true
} },
extraMoreActions: [
{
name: 'DeactiveSelected',
title: this.$t('assets.DeactiveSelected'),
type: 'primary',
can: ({ selectedRows }) => {
return selectedRows.length > 0 && vm.$hasPerm('assets.change_asset')
},
callback: function({ selectedRows }) {
const ids = selectedRows.map((v) => {
return { pk: v.id, is_active: false }
})
this.$axios.patch(`/api/v1/assets/assets/`, ids).then(res => {
this.$message.success(this.$t('common.updateSuccessMsg'))
}).catch(err => {
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
})
}.bind(this)
},
{
name: 'ActiveSelected',
title: this.$t('assets.ActiveSelected'),
type: 'primary',
can: ({ selectedRows }) => {
return selectedRows.length > 0 && vm.$hasPerm('assets.change_asset')
},
callback: function({ selectedRows }) {
const ids = selectedRows.map((v) => {
return { pk: v.id, is_active: true }
})
this.$axios.patch(`/api/v1/assets/assets/`, ids).then(res => {
this.$message.success(this.$t('common.updateSuccessMsg'))
}).catch(err => {
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
})
}.bind(this)
},
{
name: 'actionUpdateSelected',
title: this.$t('common.updateSelected'),
can: ({ selectedRows }) => {
return selectedRows.length > 0 &&
!vm.currentOrgIsRoot &&
vm.$hasPerm('assets.change_asset')
},
callback: ({ selectedRows }) => {
vm.updateSelectedDialogSetting.selectedRows = selectedRows
vm.updateSelectedDialogSetting.visible = true
}
}
]
} }
} }
}, },

View File

@@ -3,12 +3,29 @@
v-if="iVisible" v-if="iVisible"
:title="$tc('assets.SelectPlatforms')" :title="$tc('assets.SelectPlatforms')"
:visible.sync="iVisible" :visible.sync="iVisible"
width="70%" width="60%"
top="1vh" top="1vh"
@confirm="onConfirm" @confirm="onConfirm"
@cancel="onConfirm" @cancel="onConfirm"
> >
<div style="margin: 0 10px"> <div style="margin: 0 10px">
<el-row v-if="showRecentPlatforms.length > 0" :gutter="20">
<p class="recent">{{ this.$t('assets.RecentlyUsed') }}</p>
<el-col
v-for="(item, index) of showRecentPlatforms"
:key="item.id"
:span="6"
>
<el-card
:style="{ borderLeftColor: randomBorderColor(index) }"
class="platform-item"
shadow="hover"
@click.native="createAsset(p)"
>
{{ item.name }}
</el-card>
</el-col>
</el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-collapse v-model="activePlatform" accordion> <el-collapse v-model="activePlatform" accordion>
<el-collapse-item <el-collapse-item
@@ -61,6 +78,7 @@ export default {
data() { data() {
return { return {
platforms: [], platforms: [],
recentPlatforms: {},
activePlatform: 'host', activePlatform: 'host',
typeIconMapper: { typeIconMapper: {
linux: 'fa-linux', linux: 'fa-linux',
@@ -86,34 +104,69 @@ export default {
sortedPlatforms() { sortedPlatforms() {
const { category, platforms } = this const { category, platforms } = this
const filterPlatforms = _.groupBy(platforms, (item) => item.category.value) const filterPlatforms = _.groupBy(platforms, (item) => item.category.value)
return category === 'all' ? filterPlatforms : { [category]: filterPlatforms[category] } return category === 'all' ? filterPlatforms : this.arrangePlatforms(filterPlatforms[category])
}, },
categoryMapper() { categoryMapper() {
const mapper = {} const mapper = {}
for (const p of this.platforms) { for (const p of this.platforms) {
mapper[p.category.value] = p.category.label if (this.category === 'all') {
mapper[p.category.value] = p.category.label
} else {
mapper[p.type.value] = p.type.label
}
} }
return mapper return mapper
} },
}, showRecentPlatforms() {
watch: { return this.category === 'all' ? this.allRecentPlatforms() : this.recentPlatforms[this.category]
category: {
handler(val) {
if (val === 'all') {
this.activePlatform = 'host'
} else {
this.activePlatform = val
}
},
immediate: true
} }
}, },
created() { created() {
this.$axios.get('/api/v1/assets/platforms/').then(data => { this.$axios.get('/api/v1/assets/platforms/').then(data => {
this.platforms = data this.platforms = data
}) })
this.getRecentPlatforms()
}, },
methods: { methods: {
getRecentPlatforms() {
const recentPlatforms = JSON.parse(localStorage.getItem('RecentPlatforms')) || {
host: [],
networking: [],
database: [],
cloud: [],
web: []
}
this.recentPlatforms = recentPlatforms
},
setRecentPlatforms(platform) {
const platforms = { ...this.recentPlatforms }
const categoryValue = platform.category.value
const platformCategory = platforms[categoryValue]
const item = {
id: platform.id,
name: platform.name,
category: platform.category
}
if (!_.some(platformCategory, item)) {
if (platformCategory.length >= 4) {
platformCategory.pop()
}
platformCategory.unshift(item)
localStorage.setItem('RecentPlatforms', JSON.stringify(platforms))
}
},
allRecentPlatforms() {
const { recentPlatforms } = this
const platforms = []
for (const category in recentPlatforms) {
const platformCategory = recentPlatforms[category]
if (platformCategory.length > 0) {
platforms.push(platformCategory[0])
}
}
return platforms
},
onConfirm() { onConfirm() {
this.iVisible = false this.iVisible = false
}, },
@@ -134,6 +187,22 @@ export default {
const route = mapper[platform.category.value] || 'HostCreate' const route = mapper[platform.category.value] || 'HostCreate'
this.$router.push({ name: route, query: { platform: platform.id }}) this.$router.push({ name: route, query: { platform: platform.id }})
this.iVisible = false this.iVisible = false
this.setRecentPlatforms(platform)
},
arrangePlatforms(data = []) {
const filterField = {}
data.length > 0 && data.forEach(el => {
if (el.internal) {
filterField[el.type.value] = [el]
} else {
filterField[el.type.value]?.push(el)
}
})
const filterFieldKey = Object.keys(filterField)
this.activePlatform = filterFieldKey.length > 0 ? filterFieldKey[0] : ''
return filterField
} }
} }
} }
@@ -152,4 +221,8 @@ export default {
cursor: pointer; cursor: pointer;
} }
.recent {
font-weight: 500;
color: #303133;
}
</style> </style>

View File

@@ -1,5 +1,9 @@
<template> <template>
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu" /> <TabPage
:active-menu.sync="config.activeMenu"
:submenu="config.submenu"
@tab-click="handleTabClick"
/>
</template> </template>
<script> <script>
@@ -22,30 +26,30 @@ export default {
}, },
{ {
title: this.$t('applications.host'), title: this.$t('applications.host'),
name: 'host', name: 'hosts',
hidden: () => false, hidden: () => false,
component: () => import('@/views/assets/Asset/AssetList/HostList.vue') component: () => import('@/views/assets/Asset/AssetList/HostList.vue')
}, },
{ {
title: this.$t('route.NetworkDevices'), title: this.$t('route.NetworkDevices'),
name: 'networking', name: 'networks',
hidden: () => false, hidden: () => false,
component: () => import('@/views/assets/Asset/AssetList/NetworkList.vue') component: () => import('@/views/assets/Asset/AssetList/NetworkList.vue')
}, },
{ {
title: this.$t('route.Databases'), title: this.$t('route.Databases'),
name: 'database', name: 'databases',
hidden: () => false, hidden: () => false,
component: () => import('@/views/assets/Asset/AssetList/DatabaseList.vue') component: () => import('@/views/assets/Asset/AssetList/DatabaseList.vue')
}, },
{ {
title: this.$t('assets.CloudPlatform'), title: this.$t('assets.CloudPlatform'),
name: 'cloud', name: 'clouds',
hidden: () => false, hidden: () => false,
component: () => import('@/views/assets/Asset/AssetList/CloudsPlatformList.vue') component: () => import('@/views/assets/Asset/AssetList/CloudsPlatformList.vue')
}, },
{ {
title: 'Web', title: 'Webs',
name: 'web', name: 'web',
hidden: () => false, hidden: () => false,
component: () => import('@/views/assets/Asset/AssetList/WebList.vue') component: () => import('@/views/assets/Asset/AssetList/WebList.vue')
@@ -54,9 +58,15 @@ export default {
} }
} }
}, },
computed: {
},
mounted() { mounted() {
},
methods: {
handleTabClick(tab) {
const params = new URLSearchParams(window.location.search)
params.set('activeTab', tab.name)
const query = Object.fromEntries(params)
this.$router.replace({ query })
}
} }
} }
</script> </script>