Merge pull request #39 from jumpserver/orange_dev

[update]添加表格组件
This commit is contained in:
Orange 2020-04-28 16:04:07 +08:00 committed by GitHub
commit c16ba38169
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 256 additions and 16 deletions

View File

@ -0,0 +1,125 @@
<template>
<div>
<el-select ref="select" v-model="internalValue" multiple placeholder="请选择资产" @focus="handleFocus" />
<el-dialog
:title="this.$t('资产列表')"
:visible.sync="dialogVisible"
width="45%"
:before-close="handleClose"
>
<GenericTreeListPage ref="ListPage" :table-config="tableConfig" :header-actions="headerActions" />
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleConfirm"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import GenericTreeListPage from '@/layout/components/GenericTreeListPage'
import { DetailFormatter } from '@/components/ListTable/formatters'
export default {
componentName: 'AssetSelect',
components: { GenericTreeListPage },
props: {
value: {
type: Array,
default: () => []
}
},
data() {
return {
internalValue: [],
showValue: [],
dialogVisible: false,
tableConfig: {
url: '/api/v1/assets/assets/',
hasTree: true,
treeSetting: {
showMenu: true,
showRefresh: true,
showAssets: false,
url: '/api/v1/assets/assets/',
nodeUrl: '/api/v1/assets/nodes/',
// ?assets=0. =1
treeUrl: '/api/v1/assets/nodes/children/tree/?assets=0'
},
columns: [
{
prop: 'hostname',
label: this.$t('assets.hostname'),
formatter: DetailFormatter,
sortable: true,
route: 'AssetDetail'
},
{
prop: 'ip',
label: this.$t('assets.ip'),
sortable: 'custom'
}
]
},
headerActions: {
hasExport: false,
hasImport: false,
hasRefresh: false,
hasCreate: false,
hasBulkDelete: false,
hasBulkUpdate: false,
hasLeftActions: false,
hasSearch: true,
hasRightActions: false
}
}
},
computed: {
},
mounted() {
this.$on('SelectionChange', (val) => {
//
this.internalValue = []
this.showValue = []
for (const key in val) {
this.internalValue.push(`${val[key].hostname}(${val[key].ip})`)
this.showValue.push(`${val[key].id}`)
}
this.$emit('input', this.showValue)
})
},
methods: {
handleFocus() {
this.$refs.select.blur()
this.dialogVisible = true
},
handleConfirm() {
this.dialogVisible = false
},
handleClose(done) {
this.$confirm('确认关闭?')
.then(_ => {
done()
})
.catch(_ => {
})
}
}
}
</script>
<style lang='less' scoped>
.el-select{
width: 100%;
}
.page /deep/ .page-heading{
display: none;
}
.el-dialog__wrapper /deep/.el-dialog__body{
padding: inherit !important;
}
.page /deep/ .treebox{
height: inherit !important;
}
</style>

View File

@ -131,6 +131,7 @@ export default {
field = this.generateFieldByName(name, field) field = this.generateFieldByName(name, field)
field = this.generateFieldByOther(field, fieldMeta) field = this.generateFieldByOther(field, fieldMeta)
field = Object.assign(field, this.fieldsMeta[name] || {}) field = Object.assign(field, this.fieldsMeta[name] || {})
console.log(field)
_.set(field, 'attrs.error', '') _.set(field, 'attrs.error', '')
return field return field
}, },

View File

@ -45,6 +45,7 @@ import Dialog from '../Dialog'
import IBox from '../IBox' import IBox from '../IBox'
import TableAction from './TableAction' import TableAction from './TableAction'
import { createSourceIdCache } from '@/api/common' import { createSourceIdCache } from '@/api/common'
import Emitter from '@/mixins/emitter'
export default { export default {
name: 'ListTable', name: 'ListTable',
@ -54,6 +55,7 @@ export default {
Dialog, Dialog,
IBox IBox
}, },
mixins: [Emitter],
props: { props: {
// table // table
tableConfig: { tableConfig: {
@ -116,6 +118,10 @@ export default {
}, },
handleSelectionChange(val) { handleSelectionChange(val) {
this.selectedRows = val this.selectedRows = val
var obj = {}
val.forEach((item, index) => { obj[index] = item })
// Bug
this.dispatch('AssetSelect', 'SelectionChange', obj)
}, },
reloadTable() { reloadTable() {
this.$refs.dataTable.$refs.dataTable.getList() this.$refs.dataTable.$refs.dataTable.getList()

View File

@ -14,6 +14,7 @@ export { default as ListTable } from './ListTable'
export { default as RelationCard } from './RelationCard' export { default as RelationCard } from './RelationCard'
export { default as ActiveCard } from './ActiveCard' export { default as ActiveCard } from './ActiveCard'
export { default as Select2 } from './Select2' export { default as Select2 } from './Select2'
export { default as AssetSelect } from './AssetSelect'
export { default as SvgIcon } from './SvgIcon' export { default as SvgIcon } from './SvgIcon'
export { default as TreeTable } from './TreeTable' export { default as TreeTable } from './TreeTable'
export { default as IBox } from './IBox' export { default as IBox } from './IBox'

36
src/mixins/emitter.js Normal file
View File

@ -0,0 +1,36 @@
function broadcast(componentName, eventName, params) {
this.$children.forEach(child => {
var name = child.$options.componentName
if (name === componentName) {
child.$emit.apply(child, [eventName].concat(params))
} else {
broadcast.apply(child, [componentName, eventName].concat([params]))
}
})
}
// 已知Issues
// https://github.com/ElemeFE/element/issues/17229
export default {
methods: {
dispatch(componentName, eventName, params) {
var parent = this.$parent || this.$root
var name = parent.$options.componentName
while (parent && (!name || name !== componentName)) {
parent = parent.$parent
if (parent) {
name = parent.$options.componentName
}
}
if (parent) {
parent.$emit.apply(parent, [eventName].concat(params))
}
},
broadcast(componentName, eventName, params) {
broadcast.call(this, componentName, eventName, params)
}
}
}

View File

@ -131,13 +131,13 @@ export const constantRoutes = [
{ {
path: 'domains', path: 'domains',
name: 'DomainList', name: 'DomainList',
component: () => import('@/views/assets/DomainList.vue'), component: () => import('@/views/assets/Domain/DomainList.vue'),
meta: { title: 'DomainList' } meta: { title: 'DomainList' }
}, },
{ {
path: 'domains/create', path: 'domains/create',
name: 'DomainCreate', name: 'DomainCreate',
component: () => import('@/views/assets/DomainCreateUpdate.vue'), component: () => import('@/views/assets/Domain/DomainCreateUpdate.vue'),
meta: { title: 'DomainList' }, meta: { title: 'DomainList' },
hidden: true hidden: true
}, },
@ -151,54 +151,61 @@ export const constantRoutes = [
{ {
path: 'admin-users', path: 'admin-users',
name: 'AdminUserList', name: 'AdminUserList',
component: () => import('@/views/assets/AdminUserList'), component: () => import('@/views/assets/AdminUser/AdminUserList'),
meta: { title: 'AdminUserList' } meta: { title: 'AdminUserList' }
}, },
{ {
path: 'admin-users/create', path: 'admin-users/create',
component: () => import('@/views/assets/AdminUserCreateUpdate.vue'), // Parent router-view component: () => import('@/views/assets/AdminUser/AdminUserCreateUpdate.vue'), // Parent router-view
name: 'AdminUserCreateUpdate', name: 'AdminUserCreateUpdate',
meta: { title: 'AdminUserCreate' }, meta: { title: 'AdminUserCreate' },
hidden: true hidden: true
}, },
{ {
path: 'platform/update/:id', path: 'platform/update/:id',
component: () => import('@/views/assets/PlatformCreateUpdate.vue'), // Parent router-view component: () => import('@/views/assets/Platform/PlatformCreateUpdate.vue'), // Parent router-view
name: 'PlatformUpdate', name: 'PlatformUpdate',
meta: { title: 'PlatformUpdate' }, meta: { title: 'PlatformUpdate' },
hidden: true hidden: true
}, },
{
path: 'platform/detail/:id',
component: () => import('@/views/assets/Platform/PlatformDetail.vue'), // Parent router-view
name: 'PlatformDetail',
meta: { title: 'PlatformDetail' },
hidden: true
},
{ {
path: 'platform/create', path: 'platform/create',
component: () => import('@/views/assets/PlatformCreateUpdate.vue'), // Parent router-view component: () => import('@/views/assets/Platform/PlatformCreateUpdate.vue'), // Parent router-view
name: 'PlatformCreate', name: 'PlatformCreate',
meta: { title: 'PlatformCreate' }, meta: { title: 'PlatformCreate' },
hidden: true hidden: true
}, },
{ {
path: 'cmd-filters/update/:id', path: 'cmd-filters/update/:id',
component: () => import('@/views/assets/CommandFilterCreateUpdate.vue'), // Parent router-view component: () => import('@/views/assets/CommandFilter/CommandFilterCreateUpdate.vue'), // Parent router-view
name: 'CommandFilterUpdate', name: 'CommandFilterUpdate',
meta: { title: 'CommandFilterUpdate' }, meta: { title: 'CommandFilterUpdate' },
hidden: true hidden: true
}, },
{ {
path: 'cmd-filters/create', path: 'cmd-filters/create',
component: () => import('@/views/assets/CommandFilterCreateUpdate.vue'), // Parent router-view component: () => import('@/views/assets/CommandFilter/CommandFilterCreateUpdate.vue'), // Parent router-view
name: 'CommandFilterCreate', name: 'CommandFilterCreate',
meta: { title: 'CommandFilterCreate' }, meta: { title: 'CommandFilterCreate' },
hidden: true hidden: true
}, },
{ {
path: 'cmd-filters/:id', path: 'cmd-filters/:id',
component: () => import('@/views/assets/CommandFilterDetail.vue'), // Parent router-view component: () => import('@/views/assets/CommandFilter/CommandFilterDetail.vue'), // Parent router-view
name: 'CommandFilterDetail', name: 'CommandFilterDetail',
meta: { title: 'CommandFilterDetail' }, meta: { title: 'CommandFilterDetail' },
hidden: true hidden: true
}, },
{ {
path: 'admin-users/:id', path: 'admin-users/:id',
component: () => import('@/views/assets/AdminUserDetail.vue'), // Parent router-view component: () => import('@/views/assets/AdminUser/AdminUserDetail.vue'), // Parent router-view
name: 'AdminUserDetail', name: 'AdminUserDetail',
meta: { title: 'AdminUserDetail' }, meta: { title: 'AdminUserDetail' },
hidden: true hidden: true
@ -210,22 +217,35 @@ export const constantRoutes = [
component: () => import('@/views/assets/SystemUserList.vue'), component: () => import('@/views/assets/SystemUserList.vue'),
meta: { title: 'SystemUserList' } meta: { title: 'SystemUserList' }
}, },
{
path: 'labels/create',
name: 'LabelCreate',
component: () => import('@/views/assets/Label/LabelCreateUpdate.vue'),
meta: { title: 'LabelCreate' },
hidden: true
},
{
path: 'labels/update/:id',
name: 'LabelUpdate',
component: () => import('@/views/assets/Label/LabelCreateUpdate.vue'),
meta: { title: 'LabelUpdate' }, hidden: true
},
{ {
path: 'labels', path: 'labels',
name: 'LabelList', name: 'LabelList',
component: () => import('@/views/assets/LabelList.vue'), component: () => import('@/views/assets/Label/LabelList.vue'),
meta: { title: 'LabelList' } meta: { title: 'LabelList' }
}, },
{ {
path: 'cmd-filters', path: 'cmd-filters',
name: 'CommandFilterList', name: 'CommandFilterList',
component: () => import('@/views/assets/CommandFilterList.vue'), component: () => import('@/views/assets/CommandFilter/CommandFilterList.vue'),
meta: { title: 'CommandFilterList' } meta: { title: 'CommandFilterList' }
}, },
{ {
path: 'platforms', path: 'platforms',
name: 'PlatformList', name: 'PlatformList',
component: () => import('@/views/assets/PlatformList'), component: () => import('@/views/assets/Platform/PlatformList'),
meta: { title: 'PlatformList' } meta: { title: 'PlatformList' }
} }
] ]

View File

@ -5,7 +5,7 @@
<script> <script>
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage' import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
export default { export default {
name: 'GatewayCreate', name: 'GatewayCreateUpdate',
components: { components: {
GenericCreateUpdatePage GenericCreateUpdatePage
}, },

View File

@ -0,0 +1,39 @@
<template>
<GenericCreateUpdatePage :fields="fields" :initial="initial" :fields-meta="fieldsMeta" :url="url" />
</template>
<script>
import { AssetSelect } from '@/components'
import GenericCreateUpdatePage from '@/layout/components/GenericCreateUpdatePage'
export default {
name: 'LabelCreateUpdate',
components: {
GenericCreateUpdatePage
},
data() {
return {
initial: {
},
fields: [
['', ['name', 'value', 'assets']]
],
fieldsMeta: {
assets: {
type: 'assetSelect',
component: AssetSelect,
label: '资产',
rules: [{
required: false
}]
}
},
url: '/api/v1/assets/labels/'
}
}
}
</script>
<style>
</style>

View File

@ -1,13 +1,25 @@
<template> <template>
<GenericDetailPage :object="object" :submenu="submenu" :active-menu="activeSubMenu" :title="title" /> <GenericDetailPage :object="object" :submenu="submenu" :active-menu="activeSubMenu" :title="title">
<template #detail>
<div>
<el-row :gutter="20">
<el-col :md="14" :sm="24">
<DetailCard v-if="flag" :title="cardTitle" :items="detailCardItems" />
</el-col>
</el-row>
</div>
</template>
</GenericDetailPage>
</template> </template>
<script> <script>
import { DetailCard } from '@/components'
import { GenericDetailPage } from '@/layout/components' import { GenericDetailPage } from '@/layout/components'
export default { export default {
name: 'PlatformDetail', name: 'PlatformDetail',
components: { components: {
GenericDetailPage GenericDetailPage,
DetailCard
}, },
data() { data() {
return { return {