perf: 修改 platform list 和 asset list

This commit is contained in:
ibuler
2022-08-19 19:38:24 +08:00
parent 01919a496e
commit d48a61c597
10 changed files with 303 additions and 130 deletions

View File

@@ -148,6 +148,6 @@ export default {
color: var(--color-primary);
}
.form-buttons {
padding-top: 10px;
margin-top: 20px;
}
</style>

View File

@@ -2,10 +2,21 @@
<div>
<div v-for="(item, index) in items" :key="item.name" style="display: flex;margin-top: 8px;">
<el-input v-model="item.port" class="input-with-select" v-bind="$attrs">
<el-select slot="prepend" v-model="item.name" class="prepend" @change="handleProtocolChange($event, item)">
<el-select
slot="prepend"
v-model="item.name"
class="prepend"
@change="handleProtocolChange($event, item)"
>
<el-option v-for="p of remainProtocols" :key="p.name" :label="p.name" :value="p.name" />
</el-select>
<el-button v-if="showSetting" slot="append" icon="el-icon-setting" @click="onSettingClick(item)" />
<el-button
v-if="showSetting(item)"
slot="append"
icon="el-icon-setting"
:disabled="disableSetting(item)"
@click="onSettingClick(item)"
/>
</el-input>
<div style="display: flex; margin-left: 20px" class="input-button">
<el-button
@@ -46,8 +57,16 @@ export default {
default: () => ([])
},
showSetting: {
type: Boolean,
default: false
type: Function,
default: (item) => {
return false
}
},
disableSetting: {
type: Function,
default: (item) => {
return false
}
},
onSettingClick: {
type: Function,
@@ -59,7 +78,8 @@ export default {
data() {
return {
name: '',
items: []
items: [],
settingItem: {}
}
},
computed: {
@@ -144,5 +164,6 @@ export default {
.el-input-group__append .el-button {
font-size: 14px;
color: #1a1a1a;
padding: 9px 20px;
}
</style>

View File

@@ -81,32 +81,8 @@ export default {
}
},
data() {
const defaultActions = [
{
name: 'actionCreate',
title: this.createTitle,
type: 'primary',
has: this.hasCreate && !this.moreCreates,
can: this.canCreate,
callback: this.onCreate || this.handleCreate
}
]
if (this.moreCreates) {
const defaultMoreCreate = {
name: 'actionMoreCreate',
title: this.createTitle,
type: 'primary',
has: true,
can: this.canCreate,
dropdown: [],
callback: this.onCreate || this.handleCreate
}
const createCreateAction = Object.assign(defaultMoreCreate, this.moreCreates)
defaultActions.push(createCreateAction)
}
const vm = this
return {
defaultActions: defaultActions,
defaultMoreActions: [
{
title: this.$t('common.deleteSelected'),
@@ -131,6 +107,32 @@ export default {
}
},
computed: {
defaultActions() {
const defaultActions = [
{
name: 'actionCreate',
title: this.createTitle,
type: 'primary',
has: this.hasCreate && !this.moreCreates,
can: this.canCreate,
callback: this.onCreate || this.handleCreate
}
]
if (this.moreCreates) {
const defaultMoreCreate = {
name: 'actionMoreCreate',
title: this.createTitle,
type: 'primary',
has: true,
can: this.canCreate,
dropdown: [],
callback: this.onCreate || this.handleCreate
}
const createCreateAction = Object.assign(defaultMoreCreate, this.moreCreates)
defaultActions.push(createCreateAction)
}
return defaultActions
},
iActions() {
return [...this.actions, this.moreAction]
},

View File

@@ -17,14 +17,21 @@
</component>
</div>
<div :style="iShowTree?('display: flex;width: calc(100% - 20%);'):('display: flex;width:100%;')">
<div class="mini">
<div style="display:block" class="mini-button" @click="iShowTree=!iShowTree">
<i v-show="iShowTree" class="fa fa-angle-left fa-x" /><i v-show="!iShowTree" class="fa fa-angle-right fa-x" />
<div v-if="showTree" class="mini">
<div style="display:block" class="mini-button" @click="iShowTree = !iShowTree">
<i v-show="iShowTree" class="fa fa-angle-left fa-x" />
<i v-show="!iShowTree" class="fa fa-angle-right fa-x" />
</div>
</div>
<div class="transition-box" style="width: calc(100% - 17px);">
<slot name="table">
<ListTable ref="ListTable" :key="componentKey" :table-config="iTableConfig" :header-actions="headerActions" v-on="$listeners" />
<ListTable
ref="ListTable"
:key="componentKey"
:table-config="iTableConfig"
:header-actions="headerActions"
v-on="$listeners"
/>
</slot>
</div>
</div>
@@ -74,6 +81,9 @@ export default {
handler(val) {
},
deep: true
},
showTree(val) {
this.iShowTree = val
}
},
mounted() {

View File

@@ -22,7 +22,8 @@ import { mapGetters } from 'vuex'
export default {
name: 'GenericTreeListPage',
components: {
Page, TreeTable
Page,
TreeTable
},
computed: {
...mapGetters(['currentOrgIsRoot'])

View File

@@ -1,19 +1,21 @@
<template>
<div>
<GenericTreeListPage
ref="TreeList"
:table-config="tableConfig"
:help-message="helpMessage"
:header-actions="headerActions"
:tree-setting="treeSetting"
>
<TreeMenu
slot="rMenu"
:tree="treeRef"
@showAll="showAll"
/>
</GenericTreeListPage>
<TabPage :active-menu.sync="tab.activeMenu" :submenu="tab.submenu" @tab-click="handleTabChange">
<TreeTable
ref="TreeList"
:table-config="tableConfig"
:help-message="helpMessage"
:header-actions="headerActions"
:tree-setting="treeSetting"
:show-tree="showTree"
>
<TreeMenu
slot="rMenu"
:tree="treeRef"
@showAll="showAll"
/>
</TreeTable>
</TabPage>
<AssetBulkUpdateDialog
:visible.sync="updateSelectedDialogSetting.visible"
v-bind="updateSelectedDialogSetting"
@@ -23,7 +25,15 @@
</template>
<script>
import GenericTreeListPage from '@/layout/components/GenericTreeListPage/index'
import { TabPage } from '@/layout/components'
import { TreeTable } from '@/components'
import $ from '@/utils/jquery-vendor'
import { mapGetters } from 'vuex'
import { connectivityMeta } from '@/components/AccountListTable/const'
import AssetBulkUpdateDialog from './AssetBulkUpdateDialog'
import PlatformDialog from './PlatformDialog'
import TreeMenu from './TreeMenu'
import { Categories } from '@/views/assets/const'
import {
DetailFormatter,
ActionsFormatter,
@@ -31,25 +41,28 @@ import {
NestedObjectFormatter,
ChoicesDisplayFormatter
} from '@/components/TableFormatters'
import $ from '@/utils/jquery-vendor'
import { mapGetters } from 'vuex'
import { connectivityMeta } from '@/components/AccountListTable/const'
import AssetBulkUpdateDialog from './AssetBulkUpdateDialog'
import PlatformDialog from './PlatformDialog'
import TreeMenu from './TreeMenu'
export default {
components: {
GenericTreeListPage,
AssetBulkUpdateDialog,
TreeMenu,
PlatformDialog
PlatformDialog,
TreeTable,
TabPage
},
data() {
const vm = this
return {
treeRef: null,
showPlatform: false,
showTree: true,
tab: {
submenu: [
{ name: 'all', title: '所有' },
...Categories
],
activeMenu: 'host'
},
treeSetting: {
showMenu: true,
showRefresh: true,
@@ -67,10 +80,8 @@ export default {
url: '/api/v1/assets/assets/',
hasTree: true,
columns: [
'name', 'ip',
'category', 'type', 'platform',
'labels', 'nodes',
'is_active', 'connectivity',
'name', 'ip', 'category', 'type', 'platform',
'labels', 'nodes', 'is_active', 'connectivity',
'created_by', 'date_created', 'comment', 'org_name',
'actions'
],
@@ -100,9 +111,6 @@ export default {
sortable: 'custom',
width: '140px'
},
sn: {
showOverflowTooltip: true
},
comment: {
showOverflowTooltip: true
},
@@ -278,6 +286,16 @@ export default {
this.decorateRMenu()
const url = `${this.treeSetting.url}?node_id=${node.meta.data.id}&show_current_asset=${showCurrentAsset}`
this.$refs.TreeList.$refs.TreeTable.handleUrlChange(url)
},
handleTabChange(item) {
let url = '/api/v1/assets/assets/'
const showTree = item.name === 'all'
if (item.name !== 'all') {
url = `${url}?category=${item.name}`
}
this.treeSetting.url = url
this.showTree = showTree
this.tableConfig.url = url
}
}
}

View File

@@ -1,27 +1,44 @@
<template>
<GenericCreateUpdatePage
:url="url"
:fields="fields"
:initial="initial"
:fields-meta="fieldsMeta"
:clean-form-value="cleanFormValue"
:after-get-form-value="afterGetFormValue"
/>
<div>
<GenericCreateUpdatePage
:url="url"
:fields="fields"
:initial="initial"
:fields-meta="fieldsMeta"
:clean-form-value="cleanFormValue"
:after-get-form-value="afterGetFormValue"
/>
<ProtocolSettingDialog
:visible.sync="showDialog"
:item="settingItem"
/>
</div>
</template>
<script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
import rules from '@/components/DataForm/rules'
import { assetFieldsMeta } from '@/views/assets/const'
import ProtocolSettingDialog from './ProtocolSettingDialog'
export default {
name: 'PlatformCreateUpdate',
components: { GenericCreateUpdatePage },
components: {
GenericCreateUpdatePage,
ProtocolSettingDialog
},
data() {
const category = this.$route.query.category
const type = this.$route.query.type
const assetMeta = assetFieldsMeta()
return {
loading: true,
showDialog: false,
settingItem: {
setting: {},
name: '',
port: 0
},
initial: {
comment: '',
charset: 'utf8',
@@ -48,44 +65,6 @@ export default {
[this.$t('common.Other'), ['comment']]
],
fieldsMeta: {
meta: {
fields: ['security', 'console'],
fieldsMeta: {
security: {
prop: 'meta.security',
type: 'select',
label: 'RDP security',
options: [{
label: 'RDP',
value: 'rdp'
},
{
label: 'NLA',
value: 'nla'
},
{
label: 'TLS',
value: 'tls'
},
{
label: 'Any',
value: 'any'
}]
},
console: {
type: 'select',
label: 'RDP console',
options: [{
label: this.$t('common.Yes'),
value: 'true'
}, {
label: this.$t('common.No'),
value: 'false'
}]
}
},
hidden: form => form.base !== 'Windows'
},
category_type: {
type: 'cascader',
label: this.$t('assets.Type'),
@@ -113,7 +92,12 @@ export default {
...assetMeta.protocols,
el: {
choices: [],
showSetting: true
showSetting: (item) => true,
onSettingClick: (item) => {
this.settingItem = item
this.showDialog = true
},
disableSetting: (item) => item.name !== 'rdp'
},
hidden: (formValue) => {
return !formValue['protocols_enabled']

View File

@@ -1,17 +1,29 @@
<template>
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
<TabPage :active-menu.sync="tab.activeMenu" :submenu="tab.submenu" @tab-click="changeMoreCreates">
<keep-alive>
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
</keep-alive>
</TabPage>
</template>
<script>
import { GenericListPage } from '@/layout/components'
import { GenericListTable, TabPage } from '@/layout/components'
import { ChoicesDisplayFormatter } from '@/components/TableFormatters'
import { Categories } from '@/views/assets/const'
export default {
components: {
GenericListPage
TabPage,
GenericListTable
},
data() {
const vm = this
return {
show: true,
tab: {
submenu: Categories,
activeMenu: 'host'
},
tableConfig: {
url: '/api/v1/assets/platforms/',
columns: [
@@ -42,8 +54,8 @@ export default {
name: 'PlatformUpdate',
params: { id: row.id },
query: {
category: row.category,
type: row.type
category: row.category.value,
type: row.type.value
}
}
},
@@ -51,8 +63,8 @@ export default {
return {
name: 'PlatformCreate',
query: {
category: row.category,
type: row.type,
category: row.category.value,
type: row.type.value,
clone_from: row.id
}
}
@@ -68,17 +80,34 @@ export default {
createRoute: 'PlatformCreate',
canCreate: () => {
return this.$hasPerm('assets.add_platform')
},
moreCreates: {
callback: (item) => {
this.$router.push({
name: 'PlatformCreate',
query: { type: item.name, category: item.category }
})
},
dropdown: []
}
// moreCreates: {
// callback: (item) => {
// this.$router.push({
// name: 'PlatformCreate',
// query: { type: item.name, category: item.category }
// })
// },
// dropdown: this.$store.state.assets.assetCategoriesDropdown
// }
}
},
categoriesDropdown: this.$store.state.assets.assetCategoriesDropdown
}
},
computed: {
url() {
return `/api/v1/assets/platforms/?category=${this.tab.activeMenu}`
}
},
mounted() {
this.changeMoreCreates()
},
methods: {
changeMoreCreates() {
this.tableConfig.url = this.url
this.headerActions.moreCreates.dropdown = this.categoriesDropdown.filter(item => {
return item.category === this.tab.activeMenu
})
}
}
}

View File

@@ -0,0 +1,86 @@
<template>
<Dialog
:title="$tc('Protocol setting: ') + item.name"
:destroy-on-close="true"
:show-cancel="false"
:show-confirm="false"
:close-on-click-modal="false"
width="70%"
v-bind="$attrs"
v-on="$listeners"
>
<DataForm class="data-form" v-bind="config" @submit="onSubmit" />
</Dialog>
</template>
<script>
import { Dialog, DataForm } from '@/components'
export default {
name: 'ProtocolSetting',
components: {
Dialog,
DataForm
},
props: {
item: {
type: Object,
default: () => ({})
}
},
data() {
return {
config: {
form: {
console: true,
security: 'any'
},
hasSaveContinue: false,
fields: [
{
id: 'console',
label: 'Console',
type: 'switch'
},
{
id: 'security',
label: 'Security',
type: 'radio-group',
options: [
{
label: 'RDP',
value: 'rdp'
},
{
label: 'NLA',
value: 'nla'
},
{
label: 'TLS',
value: 'tls'
},
{
label: 'Any',
value: 'any'
}
]
}
]
}
}
},
methods: {
onSubmit(form) {
this.item.setting = form
this.$emit('update:visible', false)
}
}
}
</script>
<style lang="scss" scoped>
.data-form >>> .el-form-item.form-buttons {
padding-top: 10px;
margin-bottom: 0;
}
</style>

View File

@@ -73,3 +73,25 @@ export const assetFieldsMeta = (vm) => {
}
}
export const Categories = [
{
title: '主机',
name: 'host'
},
{
title: '网络设备',
name: 'network'
},
{
title: '数据库',
name: 'database'
},
{
title: '云平台',
name: 'cloud'
},
{
title: 'Web',
name: 'web'
}
]