mirror of
https://github.com/jumpserver/lina.git
synced 2025-09-23 12:07:38 +00:00
feat: 平台选择添加最近选择的平台;云同步只在主机中保留;平台选择某种类型时不带类别;
This commit is contained in:
@@ -91,6 +91,9 @@
|
||||
"NoSQLProtocol": "NoSQL Protocol"
|
||||
},
|
||||
"assets": {
|
||||
"All": "All",
|
||||
"CloudPlatform": "Cloud platform",
|
||||
"RecentlyUsed": "Recently used",
|
||||
"AppList": "Application list",
|
||||
"AssociateSystemUsers": "Associate system users",
|
||||
"AssociateAssets": "Associate assets",
|
||||
|
@@ -96,6 +96,9 @@
|
||||
"NoSQLProtocol": "非リレーショナルデータベース"
|
||||
},
|
||||
"assets": {
|
||||
"All": "すべて",
|
||||
"CloudPlatform": "クラウドプラットフォーム",
|
||||
"RecentlyUsed": "最近使われる",
|
||||
"AppList": "アプリケーションリスト",
|
||||
"AssociateSystemUsers": "関連システムユーザー",
|
||||
"AssociateAssets": "関連資産",
|
||||
|
@@ -98,6 +98,7 @@
|
||||
"assets": {
|
||||
"All": "所有",
|
||||
"CloudPlatform": "云平台",
|
||||
"RecentlyUsed": "最近使用",
|
||||
"AddAccount": "添加账号",
|
||||
"Account": "账号",
|
||||
"Defaults": "默认值",
|
||||
|
@@ -160,14 +160,6 @@ export default {
|
||||
{ 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: [
|
||||
{
|
||||
name: 'DeactiveSelected',
|
||||
|
@@ -8,18 +8,54 @@
|
||||
|
||||
<script>
|
||||
import BaseList from './components/BaseList'
|
||||
import { ActionsFormatter } from '@/components/TableFormatters'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BaseList
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
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: {
|
||||
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' })
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/assets/networking/'
|
||||
url: '/api/v1/assets/networks/'
|
||||
},
|
||||
headerActions: {
|
||||
createRoute: 'NetworkingCreate'
|
||||
|
@@ -16,7 +16,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/assets/web/'
|
||||
url: '/api/v1/assets/webs/'
|
||||
},
|
||||
headerActions: {
|
||||
createRoute: 'WebCreate'
|
||||
|
@@ -94,32 +94,71 @@ export default {
|
||||
actions: {
|
||||
formatter: ActionsFormatter,
|
||||
formatterArgs: {
|
||||
performDelete: ({ row, col }) => {
|
||||
performDelete: ({ row }) => {
|
||||
const id = row.id
|
||||
const url = `/api/v1/assets/assets/${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 }})
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
defaultHeaderActions: {
|
||||
hasMoreActions: false,
|
||||
createRoute: 'HostCreate',
|
||||
onCreate: () => {
|
||||
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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -3,12 +3,29 @@
|
||||
v-if="iVisible"
|
||||
:title="$tc('assets.SelectPlatforms')"
|
||||
:visible.sync="iVisible"
|
||||
width="70%"
|
||||
width="60%"
|
||||
top="1vh"
|
||||
@confirm="onConfirm"
|
||||
@cancel="onConfirm"
|
||||
>
|
||||
<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-collapse v-model="activePlatform" accordion>
|
||||
<el-collapse-item
|
||||
@@ -61,6 +78,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
platforms: [],
|
||||
recentPlatforms: {},
|
||||
activePlatform: 'host',
|
||||
typeIconMapper: {
|
||||
linux: 'fa-linux',
|
||||
@@ -86,34 +104,69 @@ export default {
|
||||
sortedPlatforms() {
|
||||
const { category, platforms } = this
|
||||
const filterPlatforms = _.groupBy(platforms, (item) => item.category.value)
|
||||
return category === 'all' ? filterPlatforms : { [category]: filterPlatforms[category] }
|
||||
return category === 'all' ? filterPlatforms : this.arrangePlatforms(filterPlatforms[category])
|
||||
},
|
||||
categoryMapper() {
|
||||
const mapper = {}
|
||||
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
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
category: {
|
||||
handler(val) {
|
||||
if (val === 'all') {
|
||||
this.activePlatform = 'host'
|
||||
} else {
|
||||
this.activePlatform = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
showRecentPlatforms() {
|
||||
return this.category === 'all' ? this.allRecentPlatforms() : this.recentPlatforms[this.category]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$axios.get('/api/v1/assets/platforms/').then(data => {
|
||||
this.platforms = data
|
||||
})
|
||||
this.getRecentPlatforms()
|
||||
},
|
||||
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() {
|
||||
this.iVisible = false
|
||||
},
|
||||
@@ -134,6 +187,22 @@ export default {
|
||||
const route = mapper[platform.category.value] || 'HostCreate'
|
||||
this.$router.push({ name: route, query: { platform: platform.id }})
|
||||
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;
|
||||
}
|
||||
|
||||
.recent {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu" />
|
||||
<TabPage
|
||||
:active-menu.sync="config.activeMenu"
|
||||
:submenu="config.submenu"
|
||||
@tab-click="handleTabClick"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -22,30 +26,30 @@ export default {
|
||||
},
|
||||
{
|
||||
title: this.$t('applications.host'),
|
||||
name: 'host',
|
||||
name: 'hosts',
|
||||
hidden: () => false,
|
||||
component: () => import('@/views/assets/Asset/AssetList/HostList.vue')
|
||||
},
|
||||
{
|
||||
title: this.$t('route.NetworkDevices'),
|
||||
name: 'networking',
|
||||
name: 'networks',
|
||||
hidden: () => false,
|
||||
component: () => import('@/views/assets/Asset/AssetList/NetworkList.vue')
|
||||
},
|
||||
{
|
||||
title: this.$t('route.Databases'),
|
||||
name: 'database',
|
||||
name: 'databases',
|
||||
hidden: () => false,
|
||||
component: () => import('@/views/assets/Asset/AssetList/DatabaseList.vue')
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.CloudPlatform'),
|
||||
name: 'cloud',
|
||||
name: 'clouds',
|
||||
hidden: () => false,
|
||||
component: () => import('@/views/assets/Asset/AssetList/CloudsPlatformList.vue')
|
||||
},
|
||||
{
|
||||
title: 'Web',
|
||||
title: 'Webs',
|
||||
name: 'web',
|
||||
hidden: () => false,
|
||||
component: () => import('@/views/assets/Asset/AssetList/WebList.vue')
|
||||
@@ -54,9 +58,15 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
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>
|
||||
|
Reference in New Issue
Block a user