feat(ui): add CMDBTypeSelectAntd component

This commit is contained in:
LH_R
2025-07-07 12:17:30 +08:00
parent 1947af5693
commit 40a53a0213
5 changed files with 163 additions and 74 deletions

View File

@@ -0,0 +1,108 @@
<template>
<a-select
v-bind="$attrs"
v-model="currenCIType"
style="width: 100%"
:showSearch="true"
:filterOption="filterOption"
:placeholder="placeholder || $t('placeholder2')"
>
<a-select-opt-group
v-for="group in selectOptions"
:key="group.id"
:label="group.name || $t('other')"
>
<a-select-option
v-for="type in group.ci_types"
:key="type.id"
:value="type.id"
:data-alias="type.alias"
:data-name="type.name"
>
{{ type.alias || type.name || $t('other') }}
<span v-if="type.name" class="select-option-name">({{ type.name }})</span>
</a-select-option>
</a-select-opt-group>
</a-select>
</template>
<script>
import _ from 'lodash'
import { getCITypeGroupsConfig } from '@/modules/cmdb/api/ciTypeGroup'
export default {
name: 'CMDBTypeSelectAntd',
model: {
prop: 'value',
event: 'change',
},
props: {
value: {
type: [String, Number, Array],
default: undefined,
},
CITypeGroup: {
type: Array,
default: undefined
},
placeholder: {
type: String,
default: '',
}
},
data() {
return {
selectOptions: []
}
},
computed: {
currenCIType: {
get() {
return this.value
},
set(newVal, oldVal) {
if (newVal !== oldVal) {
this.$emit('change', newVal)
}
return newVal
},
},
},
watch: {
CITypeGroup: {
deep: true,
handler(newValue) {
this.handleSelectOptions()
}
}
},
async mounted() {
this.handleSelectOptions()
},
methods: {
async handleSelectOptions() {
let rawCITypeGroup = []
if (this.CITypeGroup) {
rawCITypeGroup = this.CITypeGroup
} else {
rawCITypeGroup = await getCITypeGroupsConfig({ need_other: true })
}
this.selectOptions = _.cloneDeep(rawCITypeGroup).filter((group) => group?.ci_types?.length)
},
filterOption(input, option) {
const attrs = option?.data?.attrs || {}
const alias = attrs?.['data-alias']?.toLowerCase?.() || ''
const name = attrs?.['data-name']?.toLowerCase?.() || ''
return alias.indexOf(input.toLowerCase()) >= 0 || name.indexOf(input.toLowerCase()) >= 0
}
},
}
</script>
<style lang="less" scoped>
.select-option-name {
font-size: 12px;
color: #A5A9BC;
}
</style>

View File

@@ -171,23 +171,12 @@
</a-select> </a-select>
</a-form-item> </a-form-item>
<a-form-item :label="$t('cmdb.ciType.dstCIType')"> <a-form-item :label="$t('cmdb.ciType.dstCIType')">
<a-select <CMDBTypeSelectAntd
showSearch v-decorator="['ci_type_id', { rules: [{ required: true, message: $t('cmdb.ciType.dstCITypeTips') }] }]"
name="ci_type_id" name="ci_type_id"
:placeholder="$t('cmdb.ciType.dstCITypeTips')" :placeholder="$t('cmdb.ciType.dstCITypeTips')"
v-decorator="['ci_type_id', { rules: [{ required: true, message: $t('cmdb.ciType.dstCITypeTips') }] }]"
:filterOption="filterOption"
@change="changeChild" @change="changeChild"
> />
<a-select-option
:value="CIType.id"
:key="CIType.id"
v-for="CIType in CITypes"
>
{{ CIType.alias || CIType.name }}
<span class="model-select-name">({{ CIType.name }})</span>
</a-select-option>
</a-select>
</a-form-item> </a-form-item>
<a-form-item :label="$t('cmdb.ciType.relationType')"> <a-form-item :label="$t('cmdb.ciType.relationType')">
@@ -285,12 +274,14 @@ import { getCITypes } from '@/modules/cmdb/api/CIType'
import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr' import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import CMDBGrant from '../../components/cmdbGrant' import CMDBGrant from '@/modules/cmdb/components/cmdbGrant'
import CMDBTypeSelectAntd from '@/modules/cmdb/components/cmdbTypeSelect/cmdbTypeSelectAntd'
export default { export default {
name: 'RelationTable', name: 'RelationTable',
components: { components: {
CMDBGrant, CMDBGrant,
CMDBTypeSelectAntd
}, },
props: { props: {
CITypeId: { CITypeId: {
@@ -513,13 +504,6 @@ export default {
cmdbGrantType: 'type_relation', cmdbGrantType: 'type_relation',
}) })
}, },
filterOption(input, option) {
const inputValue = input.toLowerCase()
const alias = option.componentOptions.children[0].text.toLowerCase()
const name = option.componentOptions.children[1]?.elm?.innerHTML?.toLowerCase?.() ?? ''
return alias.indexOf(inputValue) >= 0 || name.indexOf(inputValue) >= 0
},
rowClass({ row }) { rowClass({ row }) {
if (row.isDivider) return 'relation-table-divider' if (row.isDivider) return 'relation-table-divider'
if (row.isParent) return 'relation-table-parent' if (row.isParent) return 'relation-table-parent'
@@ -604,9 +588,11 @@ export default {
this.modalAttrList.forEach((item) => { this.modalAttrList.forEach((item) => {
item.childAttrId = undefined item.childAttrId = undefined
}) })
if (value) {
getCITypeAttributesById(value).then((res) => { getCITypeAttributesById(value).then((res) => {
this.modalChildAttributes = res?.attributes ?? [] this.modalChildAttributes = res?.attributes ?? []
}) })
}
}, },
filterAttributes(attributes) { filterAttributes(attributes) {
// filter password/json/is_list/longText/bool/reference // filter password/json/is_list/longText/bool/reference

View File

@@ -51,31 +51,21 @@
:label="$t('cmdb.ciType.ciType')" :label="$t('cmdb.ciType.ciType')"
prop="type_ids" prop="type_ids"
> >
<a-select <CMDBTypeSelectAntd
show-search
optionFilterProp="children"
@change="changeCIType"
v-model="form.type_ids" v-model="form.type_ids"
:placeholder="$t('cmdb.ciType.selectCIType')"
mode="multiple" mode="multiple"
> :CITypeGroup="CITypeGroup"
<a-select-option v-for="ci_type in ci_types" :key="ci_type.id" :value="ci_type.id">{{ :placeholder="$t('cmdb.ciType.selectCIType')"
ci_type.alias || ci_type.name @change="changeCIType"
}}</a-select-option> />
</a-select>
</a-form-model-item> </a-form-model-item>
<a-form-model-item v-else :label="$t('cmdb.ciType.ciType')" prop="type_id"> <a-form-model-item v-else :label="$t('cmdb.ciType.ciType')" prop="type_id">
<a-select <CMDBTypeSelectAntd
show-search
optionFilterProp="children"
@change="changeCIType"
v-model="form.type_id" v-model="form.type_id"
:CITypeGroup="CITypeGroup"
:placeholder="$t('cmdb.ciType.selectCIType')" :placeholder="$t('cmdb.ciType.selectCIType')"
> @change="changeCIType"
<a-select-option v-for="ci_type in ci_types" :key="ci_type.id" :value="ci_type.id">{{ />
ci_type.alias || ci_type.name
}}</a-select-option>
</a-select>
</a-form-model-item> </a-form-model-item>
<a-form-model-item <a-form-model-item
:label="$t('cmdb.custom_dashboard.dimensions')" :label="$t('cmdb.custom_dashboard.dimensions')"
@@ -309,17 +299,26 @@
<script> <script>
import Chart from './chart.vue' import Chart from './chart.vue'
import { dashboardCategory } from './constant' import { dashboardCategory } from './constant'
import { postCustomDashboard, putCustomDashboard, postCustomDashboardPreview } from '../../api/customDashboard' import { postCustomDashboard, putCustomDashboard, postCustomDashboardPreview } from '@/modules/cmdb/api/customDashboard'
import { getCITypeAttributesByTypeIds, getCITypeCommonAttributesByTypeIds } from '../../api/CITypeAttr' import { getCITypeAttributesByTypeIds, getCITypeCommonAttributesByTypeIds } from '@/modules/cmdb/api/CITypeAttr'
import { getRecursive_level2children } from '../../api/CITypeRelation' import { getRecursive_level2children } from '@/modules/cmdb/api/CITypeRelation'
import { getLastLayout } from '../../utils/helper' import { getCITypeGroupsConfig } from '@/modules/cmdb/api/ciTypeGroup'
import { getLastLayout } from '@/modules/cmdb/utils/helper'
import FilterComp from '@/components/CMDBFilterComp' import FilterComp from '@/components/CMDBFilterComp'
import ColorPicker from './colorPicker.vue' import ColorPicker from './colorPicker.vue'
import ColorListPicker from './colorListPicker.vue' import ColorListPicker from './colorListPicker.vue'
import CMDBTypeSelectAntd from '@/modules/cmdb/components/cmdbTypeSelect/cmdbTypeSelectAntd'
export default { export default {
name: 'ChartForm', name: 'ChartForm',
components: { Chart, FilterComp, ColorPicker, ColorListPicker }, components: {
Chart,
FilterComp,
ColorPicker,
ColorListPicker,
CMDBTypeSelectAntd
},
props: { props: {
ci_types: { ci_types: {
type: Array, type: Array,
@@ -365,6 +364,7 @@ export default {
level2children: {}, level2children: {},
isShadow: false, isShadow: false,
changeCITypeRequestValue: null, changeCITypeRequestValue: null,
CITypeGroup: []
} }
}, },
computed: { computed: {
@@ -484,6 +484,7 @@ export default {
showIcon, showIcon,
tableCategory: ret === 'cis' ? 2 : 1, tableCategory: ret === 'cis' ? 2 : 1,
} }
this.getCITypeGroup()
}, },
handleclose() { handleclose() {
this.attributes = [] this.attributes = []
@@ -491,6 +492,9 @@ export default {
this.isShowPreview = false this.isShowPreview = false
this.visible = false this.visible = false
}, },
async getCITypeGroup() {
this.CITypeGroup = await getCITypeGroupsConfig({ need_other: true })
},
changeCIType(value) { changeCIType(value) {
this.form.attr_ids = [] this.form.attr_ids = []
this.commonAttributes = [] this.commonAttributes = []

View File

@@ -14,35 +14,26 @@
> >
<a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }"> <a-form :form="form" @submit="handleSubmit" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
<a-form-item :label="$t('cmdb.ciType.sourceCIType')"> <a-form-item :label="$t('cmdb.ciType.sourceCIType')">
<a-select <CMDBTypeSelectAntd
showSearch
name="source_ci_type_id"
v-decorator="[ v-decorator="[
'source_ci_type_id', 'source_ci_type_id',
{ rules: [{ required: true, message: $t('cmdb.ciType.sourceCITypeTips') }] }, { rules: [{ required: true, message: $t('cmdb.ciType.sourceCITypeTips') }] },
]" ]"
name="source_ci_type_id"
:CITypeGroup="CITypeGroups"
@change="handleSourceTypeChange" @change="handleSourceTypeChange"
:filterOption="filterOption" />
>
<a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayCITypes">
{{ CIType.alias || CIType.name }}
<span class="model-select-name">({{ CIType.name }})</span>
</a-select-option>
</a-select>
</a-form-item> </a-form-item>
<a-form-item :label="$t('cmdb.ciType.dstCIType')"> <a-form-item :label="$t('cmdb.ciType.dstCIType')">
<a-select <CMDBTypeSelectAntd
showSearch v-decorator="[
'ci_type_id',
{ rules: [{ required: true, message: $t('cmdb.ciType.dstCITypeTips') }] },
]"
name="ci_type_id" name="ci_type_id"
v-decorator="['ci_type_id', { rules: [{ required: true, message: $t('cmdb.ciType.dstCITypeTips') }] }]" :CITypeGroup="CITypeGroups"
@change="handleTargetTypeChange" @change="handleTargetTypeChange"
:filterOption="filterOption" />
>
<a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayTargetCITypes">
{{ CIType.alias || CIType.name }}
<span class="model-select-name">({{ CIType.name }})</span>
</a-select-option>
</a-select>
</a-form-item> </a-form-item>
<a-form-item :label="$t('cmdb.ciType.relationType')"> <a-form-item :label="$t('cmdb.ciType.relationType')">
@@ -127,7 +118,6 @@
</template> </template>
<script> <script>
import ModelRelationTable from './modules/modelRelationTable.vue'
import { searchResourceType } from '@/modules/acl/api/resource' import { searchResourceType } from '@/modules/acl/api/resource'
import { getCITypeGroupsConfig } from '@/modules/cmdb/api/ciTypeGroup' import { getCITypeGroupsConfig } from '@/modules/cmdb/api/ciTypeGroup'
import { getCITypes } from '@/modules/cmdb/api/CIType' import { getCITypes } from '@/modules/cmdb/api/CIType'
@@ -135,10 +125,14 @@ import { createRelation, deleteRelation, getRelationTypes } from '@/modules/cmdb
import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr' import { getCITypeAttributesById } from '@/modules/cmdb/api/CITypeAttr'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import ModelRelationTable from './modules/modelRelationTable.vue'
import CMDBTypeSelectAntd from '@/modules/cmdb/components/cmdbTypeSelect/cmdbTypeSelectAntd'
export default { export default {
name: 'Index', name: 'Index',
components: { components: {
ModelRelationTable, ModelRelationTable,
CMDBTypeSelectAntd
}, },
data() { data() {
return { return {
@@ -362,9 +356,6 @@ export default {
this.modalChildAttributes = res?.attributes ?? [] this.modalChildAttributes = res?.attributes ?? []
}) })
}, },
filterOption(input, option) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
filterAttributes(attributes) { filterAttributes(attributes) {
// filter password/json/is_list/longText/bool/reference // filter password/json/is_list/longText/bool/reference
return attributes.filter((attr) => { return attributes.filter((attr) => {

View File

@@ -15,7 +15,7 @@
@edit-closed="handleEditClose" @edit-closed="handleEditClose"
@edit-actived="handleEditActived" @edit-actived="handleEditActived"
> >
<vxe-column field="created_at" :title="$t('created_at')" sortable width="159px"></vxe-column> <vxe-column field="created_at" :title="$t('created_at')" sortable width="170"></vxe-column>
<vxe-column field="parent.alias" :title="$t('cmdb.ciType.sourceCIType')"></vxe-column> <vxe-column field="parent.alias" :title="$t('cmdb.ciType.sourceCIType')"></vxe-column>
<vxe-column <vxe-column
field="relation_type_id" field="relation_type_id"