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"
|
"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",
|
||||||
|
@@ -96,6 +96,9 @@
|
|||||||
"NoSQLProtocol": "非リレーショナルデータベース"
|
"NoSQLProtocol": "非リレーショナルデータベース"
|
||||||
},
|
},
|
||||||
"assets": {
|
"assets": {
|
||||||
|
"All": "すべて",
|
||||||
|
"CloudPlatform": "クラウドプラットフォーム",
|
||||||
|
"RecentlyUsed": "最近使われる",
|
||||||
"AppList": "アプリケーションリスト",
|
"AppList": "アプリケーションリスト",
|
||||||
"AssociateSystemUsers": "関連システムユーザー",
|
"AssociateSystemUsers": "関連システムユーザー",
|
||||||
"AssociateAssets": "関連資産",
|
"AssociateAssets": "関連資産",
|
||||||
|
@@ -98,6 +98,7 @@
|
|||||||
"assets": {
|
"assets": {
|
||||||
"All": "所有",
|
"All": "所有",
|
||||||
"CloudPlatform": "云平台",
|
"CloudPlatform": "云平台",
|
||||||
|
"RecentlyUsed": "最近使用",
|
||||||
"AddAccount": "添加账号",
|
"AddAccount": "添加账号",
|
||||||
"Account": "账号",
|
"Account": "账号",
|
||||||
"Defaults": "默认值",
|
"Defaults": "默认值",
|
||||||
|
@@ -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',
|
||||||
|
@@ -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' })
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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'
|
||||||
|
@@ -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'
|
||||||
|
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -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>
|
||||||
|
@@ -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>
|
||||||
|
Reference in New Issue
Block a user