mirror of https://github.com/veops/cmdb.git
feat(ui): update ci type choice config
This commit is contained in:
parent
e0c255ffa9
commit
9729725c6a
|
@ -54,6 +54,12 @@
|
|||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">veops-department</div>
|
||||
<div class="code-name">&#xe998;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">duose-changwenben (1)</div>
|
||||
|
@ -5514,9 +5520,9 @@
|
|||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1724135954264') format('woff2'),
|
||||
url('iconfont.woff?t=1724135954264') format('woff'),
|
||||
url('iconfont.ttf?t=1724135954264') format('truetype');
|
||||
src: url('iconfont.woff2?t=1724653006782') format('woff2'),
|
||||
url('iconfont.woff?t=1724653006782') format('woff'),
|
||||
url('iconfont.ttf?t=1724653006782') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
|
@ -5542,6 +5548,15 @@
|
|||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont veops-department"></span>
|
||||
<div class="name">
|
||||
veops-department
|
||||
</div>
|
||||
<div class="code-name">.veops-department
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont duose-changwenben1"></span>
|
||||
<div class="name">
|
||||
|
@ -13732,6 +13747,14 @@
|
|||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#veops-department"></use>
|
||||
</svg>
|
||||
<div class="name">veops-department</div>
|
||||
<div class="code-name">#veops-department</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#duose-changwenben1"></use>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 3857903 */
|
||||
src: url('iconfont.woff2?t=1724135954264') format('woff2'),
|
||||
url('iconfont.woff?t=1724135954264') format('woff'),
|
||||
url('iconfont.ttf?t=1724135954264') format('truetype');
|
||||
src: url('iconfont.woff2?t=1724653006782') format('woff2'),
|
||||
url('iconfont.woff?t=1724653006782') format('woff'),
|
||||
url('iconfont.ttf?t=1724653006782') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -13,6 +13,10 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.veops-department:before {
|
||||
content: "\e998";
|
||||
}
|
||||
|
||||
.duose-changwenben1:before {
|
||||
content: "\e997";
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,13 @@
|
|||
"css_prefix_text": "",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "41570722",
|
||||
"name": "veops-department",
|
||||
"font_class": "veops-department",
|
||||
"unicode": "e998",
|
||||
"unicode_decimal": 59800
|
||||
},
|
||||
{
|
||||
"icon_id": "41437322",
|
||||
"name": "duose-changwenben (1)",
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -107,7 +107,9 @@
|
|||
:type="choice[1].icon.name"
|
||||
/>
|
||||
</template>
|
||||
<span>{{ choice[0] }}</span>
|
||||
<a-tooltip placement="topLeft" :title="choice[1].label || choice[0]">
|
||||
<span>{{ choice[1].label || choice[0] }}</span>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
@ -138,7 +140,7 @@
|
|||
"
|
||||
target="_blank"
|
||||
>
|
||||
{{ item }}
|
||||
{{ getChoiceValueLabel(col, item) || item }}
|
||||
</a>
|
||||
</template>
|
||||
<PasswordField
|
||||
|
@ -163,7 +165,7 @@
|
|||
:style="{ color: getChoiceValueIcon(col, value).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(col, value).name"
|
||||
/>
|
||||
{{ value }}
|
||||
{{ getChoiceValueLabel(col, value) || value }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
|
@ -397,6 +399,14 @@ export default {
|
|||
return {}
|
||||
},
|
||||
|
||||
getChoiceValueLabel(col, colValue) {
|
||||
const _find = col?.filters?.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.label || ''
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
/**
|
||||
* 开启当前 ci 详情弹窗
|
||||
*/
|
||||
|
|
|
@ -105,7 +105,7 @@ export default {
|
|||
return { method, url, parameters, body, headers, authorization }
|
||||
},
|
||||
setParams(params) {
|
||||
const { method, url, parameters, body, headers, authorization = {} } = params ?? {}
|
||||
const { method = 'GET', url = '', parameters = {}, body = '', headers = {}, authorization = {} } = params ?? {}
|
||||
this.method = method
|
||||
this.url = url
|
||||
this.$refs.Parameters.parameters =
|
||||
|
|
|
@ -117,7 +117,7 @@ const cmdb_en = {
|
|||
advancedSettings: 'Advanced Settings',
|
||||
font: 'Font',
|
||||
color: 'Color',
|
||||
choiceValue: 'Predefined value',
|
||||
choiceValue: 'Select List',
|
||||
computedAttribute: 'Computed Attribute',
|
||||
computedAttributeTips: 'The value of this attribute is calculated through an expression constructed from other attributes of the CIType or by executing a piece of code. The reference method of the attribute is: {{ attribute name }}',
|
||||
addAttribute: 'New attribute',
|
||||
|
@ -293,7 +293,19 @@ const cmdb_en = {
|
|||
cascadeAttrTip: 'Cascading attributes note the order',
|
||||
enumValue: 'Value',
|
||||
label: 'Label',
|
||||
valueInputTip: 'Please input value'
|
||||
valueInputTip: 'Please input value',
|
||||
enumValueTip2: 'Enumeration values cannot be repeated',
|
||||
builtin: 'Built In',
|
||||
department: 'Department',
|
||||
user: 'User',
|
||||
userGroup: 'User Group',
|
||||
departmentTip: 'Scroll down to select all departments in the company structure for common settings',
|
||||
userGroupSelectTip: 'Please select user group',
|
||||
displayValue: 'Display Value',
|
||||
displayValueSelectTip: 'Please select Display Value',
|
||||
departmentCascadeDisplay: 'Cascade Display',
|
||||
filterUsers: 'Filter Users',
|
||||
enum: 'Enum',
|
||||
},
|
||||
components: {
|
||||
unselectAttributes: 'Unselected',
|
||||
|
|
|
@ -117,7 +117,7 @@ const cmdb_zh = {
|
|||
advancedSettings: '高级设置',
|
||||
font: '字体',
|
||||
color: '颜色',
|
||||
choiceValue: '预定义值',
|
||||
choiceValue: '下拉列表',
|
||||
computedAttribute: '计算属性',
|
||||
computedAttributeTips: '该属性的值是通过模型的其它属性构建的表达式或者执行一段代码的方式计算而来,属性的引用方法为: {{ 属性名 }}',
|
||||
addAttribute: '新增属性',
|
||||
|
@ -293,7 +293,19 @@ const cmdb_zh = {
|
|||
cascadeAttrTip: '级联属性注意顺序',
|
||||
enumValue: '枚举值',
|
||||
label: '标签',
|
||||
valueInputTip: '请输入枚举值'
|
||||
valueInputTip: '请输入枚举值',
|
||||
enumValueTip2: '枚举值不能重复',
|
||||
builtin: '内置',
|
||||
department: '部门',
|
||||
user: '用户',
|
||||
userGroup: '用户组',
|
||||
departmentTip: '下拉选择为通用设置公司架构里的所有部门',
|
||||
userGroupSelectTip: '请选择用户组',
|
||||
displayValue: '展示值',
|
||||
displayValueSelectTip: '请选择展示值',
|
||||
departmentCascadeDisplay: '部门级联显示',
|
||||
filterUsers: '筛选用户',
|
||||
enum: '枚举',
|
||||
},
|
||||
components: {
|
||||
unselectAttributes: '未选属性',
|
||||
|
|
|
@ -91,6 +91,7 @@ export function getCITableColumns(data, attrList, width = 1600, height) {
|
|||
value_type: attr.value_type,
|
||||
sortable: !!attr.is_sortable,
|
||||
filters: attr.is_choice ? attr.choice_value : null,
|
||||
choice_builtin: null,
|
||||
width: Math.min(Math.max(100, ...data.map(item => strLength(item[attr.name]))), 350),
|
||||
is_link: attr.is_link,
|
||||
is_password: attr.is_password,
|
||||
|
|
|
@ -128,7 +128,9 @@
|
|||
v-if="choice[1] && choice[1].icon && choice[1].icon.name"
|
||||
:type="choice[1].icon.name"
|
||||
/>
|
||||
{{ choice[0] }}
|
||||
<a-tooltip placement="topLeft" :title="choice[1].label || choice[0]" >
|
||||
{{ choice[1].label || choice[0] }}
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
:style="{ color: getChoiceValueIcon(attr, value).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(attr, value).name"
|
||||
/>
|
||||
{{ value }}</span
|
||||
{{ getChoiceValueLabel(attr, value) || value }}</span
|
||||
>
|
||||
</template>
|
||||
<span
|
||||
|
@ -66,7 +66,7 @@
|
|||
:style="{ color: getChoiceValueIcon(attr, ci[attr.name]).color, marginRight: '5px' }"
|
||||
:type="getChoiceValueIcon(attr, ci[attr.name]).name"
|
||||
/>
|
||||
{{ ci[attr.name] }}
|
||||
{{ getChoiceValueLabel(attr, ci[attr.name]) || ci[attr.name] }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="attr.is_list">
|
||||
|
@ -134,7 +134,7 @@
|
|||
:type="choice[1].icon.name"
|
||||
/>
|
||||
</template>
|
||||
{{ choice[0] }}
|
||||
{{ choice[1].label || choice[0] }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
@ -318,6 +318,15 @@ export default {
|
|||
}
|
||||
return {}
|
||||
},
|
||||
|
||||
getChoiceValueLabel(col, colValue) {
|
||||
const _find = col.choice_value.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.label || ''
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
getName(name) {
|
||||
return name ?? ''
|
||||
},
|
||||
|
|
|
@ -233,6 +233,7 @@ export default {
|
|||
this.firstCIJsonAttr[item._type].forEach((attr) => {
|
||||
item[`${attr}`] = item[`${attr}`] ? JSON.stringify(item[`${attr}`]) : ''
|
||||
})
|
||||
this.formatCI(item, this.firstCIColumns)
|
||||
if (item.ci_type in firstCIs) {
|
||||
firstCIs[item.ci_type].push(item)
|
||||
} else {
|
||||
|
@ -251,6 +252,7 @@ export default {
|
|||
this.secondCIJsonAttr[item._type].forEach((attr) => {
|
||||
item[`${attr}`] = item[`${attr}`] ? JSON.stringify(item[`${attr}`]) : ''
|
||||
})
|
||||
this.formatCI(item, this.secondCIColumns)
|
||||
if (item.ci_type in secondCIs) {
|
||||
secondCIs[item.ci_type].push(item)
|
||||
} else {
|
||||
|
@ -261,6 +263,26 @@ export default {
|
|||
})
|
||||
.catch((e) => {})
|
||||
},
|
||||
|
||||
formatCI(ci, columns) {
|
||||
Object.keys(ci).forEach((key) => {
|
||||
const attr = columns?.[ci?._type]?.find((item) => item?.params?.attr?.name === key)?.params?.attr
|
||||
if (attr?.is_choice && attr?.choice_value?.length) {
|
||||
if (attr?.is_list) {
|
||||
ci[key] = ci[key].map((value) => {
|
||||
const label = attr?.choice_value?.find((choice) => choice?.[0] === value)?.[1]?.label
|
||||
return label || ci[key]
|
||||
})
|
||||
} else {
|
||||
const label = attr?.choice_value?.find((choice) => choice?.[0] === ci[key])?.[1]?.label
|
||||
ci[key] = label || ci[key]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return ci
|
||||
},
|
||||
|
||||
async getParentCITypes() {
|
||||
const res = await getCITypeParent(this.typeId)
|
||||
this.parentCITypes = res.parents
|
||||
|
|
|
@ -79,7 +79,9 @@
|
|||
:type="choice[1].icon.name"
|
||||
/>
|
||||
</template>
|
||||
{{ choice[0] }}
|
||||
<a-tooltip placement="topLeft" :title="choice[1].label || choice[0]">
|
||||
{{ choice[1].label || choice[0] }}
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
@ -90,7 +92,7 @@
|
|||
attr.name,
|
||||
{
|
||||
rules: [{ required: attr.is_required, message: $t('placeholder2') + `${attr.alias || attr.name}` }],
|
||||
initialValue: attr.default && attr.default.default ? attr.default.default : '',
|
||||
initialValue: attr.default && attr.default.default ? Array.isArray(attr.default.default) ? attr.default.default.join(',') : attr.default.default : '',
|
||||
},
|
||||
]"
|
||||
>
|
||||
|
|
|
@ -49,7 +49,18 @@ export default {
|
|||
tableData: [],
|
||||
}
|
||||
},
|
||||
inject: ['providerGroupsData'],
|
||||
inject: {
|
||||
providerGroupsData: {
|
||||
default: () => {
|
||||
return () => {
|
||||
return {
|
||||
CITypeGroups: [],
|
||||
otherGroupAttributes: [],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
windowHeight: (state) => state.windowHeight,
|
||||
|
|
|
@ -74,7 +74,8 @@
|
|||
!property.is_password &&
|
||||
!property.is_list &&
|
||||
!property.is_reference &&
|
||||
!property.is_bool
|
||||
!property.is_bool &&
|
||||
!(Array.isArray(property.choice_value) ? property.choice_value.length > 0 : false)
|
||||
"
|
||||
:title="$t(isShowId ? 'cmdb.ciType.cancelSetAsShow' : 'cmdb.ciType.setAsShow')"
|
||||
>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
>
|
||||
<a-form-item
|
||||
:label-col="{ span: currentValueType === '6' ? 4 : 8 }"
|
||||
:wrapper-col="{ span: currentValueType === '6' ? 18 : 12 }"
|
||||
:wrapper-col="{ span: currentValueType === '6' ? 18 : 15 }"
|
||||
:label="$t('cmdb.ciType.defaultValue')"
|
||||
>
|
||||
<template>
|
||||
|
@ -367,7 +367,10 @@
|
|||
ref="preValueArea"
|
||||
:disabled="isShowComputedArea"
|
||||
:CITypeId="CITypeId"
|
||||
:enumValueType="enumValueType"
|
||||
/>
|
||||
|
||||
<a-button type="primary" size="small" ghost @click="resetPreValue" >{{ $t('reset') }}</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24" v-if="!['6', '7', '10', '11'].includes(currentValueType)">
|
||||
|
@ -442,6 +445,7 @@ import PreValueArea from './preValueArea.vue'
|
|||
import FontArea from './fontArea.vue'
|
||||
import RegSelect from '@/components/RegexSelect'
|
||||
import ReferenceModelSelect from './attributeEdit/referenceModelSelect.vue'
|
||||
import { ENUM_VALUE_TYPE } from './preValueAttr/constants.js'
|
||||
|
||||
export default {
|
||||
name: 'AttributeEditForm',
|
||||
|
@ -474,6 +478,7 @@ export default {
|
|||
|
||||
defaultForDatetime: '',
|
||||
re_check: {},
|
||||
enumValueType: ENUM_VALUE_TYPE.INPUT
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -686,6 +691,22 @@ export default {
|
|||
}
|
||||
const _find = attributes.find((item) => item.id === _record.id)
|
||||
if (!['6', '7', '10', '11'].includes(_record.value_type)) {
|
||||
switch (_record.value_type) {
|
||||
case '0':
|
||||
case '1':
|
||||
this.enumValueType = ENUM_VALUE_TYPE.NUMBER
|
||||
break
|
||||
case '3':
|
||||
this.enumValueType = ENUM_VALUE_TYPE.DATE_TIME
|
||||
break
|
||||
case '4':
|
||||
this.enumValueType = ENUM_VALUE_TYPE.DATE
|
||||
break
|
||||
default:
|
||||
this.enumValueType = ENUM_VALUE_TYPE.INPUT
|
||||
break
|
||||
}
|
||||
|
||||
this.$refs.preValueArea.setData({
|
||||
choice_value: (_find || {}).choice_value || [],
|
||||
choice_web_hook: _record.choice_web_hook,
|
||||
|
@ -715,8 +736,6 @@ export default {
|
|||
})
|
||||
}
|
||||
|
||||
delete values['default_show']
|
||||
delete values['is_required']
|
||||
const { default_value } = values
|
||||
if (values.value_type === '10') {
|
||||
values.default = { default: values.is_list ? default_value : Boolean(default_value) }
|
||||
|
@ -748,7 +767,6 @@ export default {
|
|||
values.default = { default: null }
|
||||
}
|
||||
|
||||
delete values.default_value
|
||||
if (values.is_computed) {
|
||||
const computedAreaData = this.$refs.computedArea.getData()
|
||||
values = { ...values, ...computedAreaData }
|
||||
|
@ -756,9 +774,18 @@ export default {
|
|||
// If it is a non-computed attribute, check to see if there is a predefined value
|
||||
if (!['6', '7', '10', '11'].includes(values.value_type)) {
|
||||
const preValueAreaData = this.$refs.preValueArea.getData()
|
||||
// 预定义值校验错误
|
||||
if (preValueAreaData?.isError) {
|
||||
return
|
||||
}
|
||||
values = { ...values, ...preValueAreaData }
|
||||
}
|
||||
}
|
||||
|
||||
delete values['default_show']
|
||||
delete values['is_required']
|
||||
delete values.default_value
|
||||
|
||||
const fontOptions = this.$refs.fontArea.getData()
|
||||
|
||||
if (!['6', '10', '11'].includes(values.value_type)) {
|
||||
|
@ -831,10 +858,19 @@ export default {
|
|||
},
|
||||
changeDefaultForDatetime(value) {
|
||||
this.defaultForDatetime = value
|
||||
if (value === '$custom_time') {
|
||||
this.form.setFieldsValue({
|
||||
default_value: undefined,
|
||||
})
|
||||
switch (value) {
|
||||
case '$custom_time':
|
||||
this.form.setFieldsValue({
|
||||
default_value: undefined,
|
||||
})
|
||||
break
|
||||
case '$updated_at':
|
||||
this.form.setFieldsValue({
|
||||
is_dynamic: true,
|
||||
})
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
},
|
||||
onClick({ key }) {
|
||||
|
@ -862,6 +898,12 @@ export default {
|
|||
}
|
||||
return []
|
||||
},
|
||||
|
||||
resetPreValue() {
|
||||
if (this.$refs.preValueArea) {
|
||||
this.$refs.preValueArea.resetData()
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
}
|
||||
|
|
|
@ -359,7 +359,10 @@
|
|||
:canDefineScript="canDefineScript"
|
||||
:disabled="isShowComputedArea"
|
||||
:CITypeId="CITypeId"
|
||||
:enumValueType="enumValueType"
|
||||
/>
|
||||
|
||||
<a-button type="primary" size="small" ghost @click="resetPreValue" >{{ $t('reset') }}</a-button>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24" v-if="!['6', '7', '10', '11'].includes(currentValueType)">
|
||||
|
@ -416,6 +419,7 @@ import FontArea from './fontArea.vue'
|
|||
import RegSelect from '@/components/RegexSelect'
|
||||
import { getPropertyIcon } from '../../utils/helper'
|
||||
import ReferenceModelSelect from './attributeEdit/referenceModelSelect.vue'
|
||||
import { ENUM_VALUE_TYPE } from './preValueAttr/constants.js'
|
||||
|
||||
export default {
|
||||
name: 'CreateNewAttribute',
|
||||
|
@ -458,6 +462,7 @@ export default {
|
|||
defaultForDatetime: '',
|
||||
|
||||
re_check: {},
|
||||
enumValueType: ENUM_VALUE_TYPE.INPUT
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -485,8 +490,7 @@ export default {
|
|||
console.log(values)
|
||||
const { is_required, default_show, default_value, is_dynamic } = values
|
||||
const data = { is_required, default_show, is_dynamic }
|
||||
delete values.is_required
|
||||
delete values.default_show
|
||||
|
||||
if (values.value_type === '10') {
|
||||
values.default = { default: values.is_list ? (default_value || null) : Boolean(default_value) }
|
||||
} else if (values.value_type === '0' && default_value) {
|
||||
|
@ -516,7 +520,7 @@ export default {
|
|||
} else {
|
||||
values.default = { default: null }
|
||||
}
|
||||
delete values.default_value
|
||||
|
||||
if (values.is_computed) {
|
||||
const computedAreaData = this.$refs.computedArea.getData()
|
||||
values = { ...values, ...computedAreaData }
|
||||
|
@ -524,9 +528,18 @@ export default {
|
|||
// If it is a non-computed attribute, check to see if there is a predefined value
|
||||
if (!['6', '7', '10', '11'].includes(values.value_type)) {
|
||||
const preValueAreaData = this.$refs.preValueArea.getData()
|
||||
// 预定义值校验错误
|
||||
if (preValueAreaData?.isError) {
|
||||
return
|
||||
}
|
||||
values = { ...values, ...preValueAreaData }
|
||||
}
|
||||
}
|
||||
|
||||
delete values.is_required
|
||||
delete values.default_show
|
||||
delete values.default_value
|
||||
|
||||
const fontOptions = this.$refs.fontArea.getData()
|
||||
|
||||
// 索引
|
||||
|
@ -587,6 +600,28 @@ export default {
|
|||
if (['6', '10', '11'].includes(value)) {
|
||||
this.re_check = {}
|
||||
}
|
||||
|
||||
switch (value) {
|
||||
case '0':
|
||||
case '1':
|
||||
this.enumValueType = ENUM_VALUE_TYPE.NUMBER
|
||||
break
|
||||
case '3':
|
||||
this.enumValueType = ENUM_VALUE_TYPE.DATE_TIME
|
||||
break
|
||||
case '4':
|
||||
this.enumValueType = ENUM_VALUE_TYPE.DATE
|
||||
break
|
||||
default:
|
||||
this.enumValueType = ENUM_VALUE_TYPE.INPUT
|
||||
break
|
||||
}
|
||||
if (['0', '1', '3', '4'].includes(value)) {
|
||||
if (this.$refs.preValueArea) {
|
||||
this.$refs.preValueArea.initEnumValue()
|
||||
}
|
||||
}
|
||||
|
||||
this.handleSwitchType({ valueType: value })
|
||||
})
|
||||
},
|
||||
|
@ -660,10 +695,19 @@ export default {
|
|||
},
|
||||
changeDefaultForDatetime(value) {
|
||||
this.defaultForDatetime = value
|
||||
if (value === '$custom_time') {
|
||||
this.form.setFieldsValue({
|
||||
default_value: undefined,
|
||||
})
|
||||
switch (value) {
|
||||
case '$custom_time':
|
||||
this.form.setFieldsValue({
|
||||
default_value: undefined,
|
||||
})
|
||||
break
|
||||
case '$updated_at':
|
||||
this.form.setFieldsValue({
|
||||
is_dynamic: true,
|
||||
})
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
},
|
||||
onClick({ key }) {
|
||||
|
@ -688,6 +732,12 @@ export default {
|
|||
}
|
||||
return []
|
||||
},
|
||||
|
||||
resetPreValue() {
|
||||
if (this.$refs.preValueArea) {
|
||||
this.$refs.preValueArea.resetData()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -545,7 +545,7 @@ export default {
|
|||
},
|
||||
showIdSelectOptions() {
|
||||
const _showIdSelectOptions = this.currentTypeAttrs.filter(
|
||||
(item) => item.id !== this.unique_id && !['6'].includes(item.value_type) && !item.is_password && !item.is_list && !item.is_bool && !item.is_reference
|
||||
(item) => item.id !== this.unique_id && !['6'].includes(item.value_type) && !item.is_password && !item.is_list && !item.is_bool && !item.is_reference && !item?.choice_value?.length
|
||||
)
|
||||
if (this.showIdFilterInput) {
|
||||
return _showIdSelectOptions.filter(
|
||||
|
|
|
@ -7,33 +7,22 @@
|
|||
:tabBarStyle="{ borderBottom: 'none' }"
|
||||
>
|
||||
<a-tab-pane key="define" :disabled="disabled">
|
||||
<span style="font-size:12px;" slot="tab">{{ $t('define') }}</span>
|
||||
<PreValueTag type="add" :item="[]" @add="addNewValue" :disabled="disabled">
|
||||
<template #default>
|
||||
<a-button
|
||||
:style="{ marginBottom: '10px', fontSize: '12px', padding: '1px 7px' }"
|
||||
type="primary"
|
||||
ghost
|
||||
:disabled="disabled"
|
||||
size="small"
|
||||
>
|
||||
<a-icon type="plus" />{{ $t('add') }}</a-button
|
||||
>
|
||||
</template>
|
||||
</PreValueTag>
|
||||
<draggable :list="valueList" handle=".handle" :disabled="disabled">
|
||||
<PreValueTag
|
||||
:disabled="disabled"
|
||||
v-for="(item, index) in valueList"
|
||||
:key="`${item[0]}_${index}`"
|
||||
:item="item"
|
||||
@deleteValue="deleteValue"
|
||||
@editValue="editValue"
|
||||
/>
|
||||
</draggable>
|
||||
<span style="font-size:14px;" slot="tab">{{ $t('cmdb.ciType.enum') }}</span>
|
||||
<PreValueDefine
|
||||
v-model="valueList"
|
||||
:disabled="disabled"
|
||||
:enumValueType="enumValueType"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="builtin" :disabled="disabled">
|
||||
<div class="tab-builtin" slot="tab">
|
||||
<span class="tab-builtin-title">{{ $t('cmdb.ciType.builtin') }}</span>
|
||||
<span v-if="isOpenSource" class="tab-builtin-tag">Pro</span>
|
||||
</div>
|
||||
<PreValueBuiltIn ref="builtInRef" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="webhook" :disabled="disabled">
|
||||
<span style="font-size:12px;" slot="tab">Webhook</span>
|
||||
<span style="font-size:14px;" slot="tab">Webhook</span>
|
||||
<Webhook ref="webhook" style="margin-top:10px" />
|
||||
<a-form-model :model="form">
|
||||
<a-col :span="24">
|
||||
|
@ -59,7 +48,7 @@
|
|||
</a-form-model>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="choice_other" :disabled="disabled">
|
||||
<span style="font-size:12px;" slot="tab">{{ $t('cmdb.ciType.choiceOther') }}</span>
|
||||
<span style="font-size:14px;" slot="tab">{{ $t('cmdb.ciType.choiceOther') }}</span>
|
||||
<a-row :gutter="[24, 24]">
|
||||
<a-col :span="24">
|
||||
<a-form-item
|
||||
|
@ -179,11 +168,11 @@
|
|||
</a-row>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="script" :disabled="disabled || !canDefineScript">
|
||||
<span style="font-size:12px;" slot="tab">{{ $t('cmdb.ciType.code') }}</span>
|
||||
<span style="font-size:14px;" slot="tab">{{ $t('cmdb.ciType.code') }}</span>
|
||||
<a-form-item
|
||||
:style="{ marginBottom: '5px' }"
|
||||
:label="$t('cmdb.ciType.cascadeAttr')"
|
||||
:label-col="{ span: 3 }"
|
||||
:label-col="{ span: $i18n.locale === 'en' ? 3 : 2 }"
|
||||
:wrapper-col="{ span: 19 }"
|
||||
:extra="scriptCodeExtraText"
|
||||
labelAlign="left"
|
||||
|
@ -191,7 +180,7 @@
|
|||
<a-select
|
||||
mode="multiple"
|
||||
style="width: 100%"
|
||||
placeholder="Please select"
|
||||
:placeholder="$t('placeholder2')"
|
||||
optionFilterProp="title"
|
||||
v-model="cascade_attributes"
|
||||
>
|
||||
|
@ -211,9 +200,11 @@
|
|||
<div>2. {{ $t('cmdb.ciType.computedAttrTip2') }}</div>
|
||||
</div>
|
||||
|
||||
<a-button size="small" @click="showAllPropDrawer">
|
||||
{{ $t('cmdb.ciType.viewAllAttr') }}
|
||||
</a-button>
|
||||
<div class="all-attr-btn">
|
||||
<a-button size="small" @click="showAllPropDrawer">
|
||||
{{ $t('cmdb.ciType.viewAllAttr') }}
|
||||
</a-button>
|
||||
</div>
|
||||
<AllAttrDrawer ref="allAttrDrawer" />
|
||||
|
||||
<CustomCodeMirror
|
||||
|
@ -237,6 +228,9 @@ import { getCITypeGroups } from '../../api/ciTypeGroup'
|
|||
import { getCITypeCommonAttributesByTypeIds, getCITypeAttributesById } from '../../api/CITypeAttr'
|
||||
import AttrFilter from './preValueAttr/attrFilter/index.vue'
|
||||
import AllAttrDrawer from './allAttrDrawer.vue'
|
||||
import PreValueDefine from './preValueAttr/define/index.vue'
|
||||
import PreValueBuiltIn from './preValueAttr/builtin/index.vue'
|
||||
import { ENUM_VALUE_TYPE } from './preValueAttr/constants.js'
|
||||
|
||||
import CustomCodeMirror from '@/components/CustomCodeMirror'
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
|
@ -245,7 +239,7 @@ require('codemirror/mode/python/python.js')
|
|||
|
||||
export default {
|
||||
name: 'PreValueArea',
|
||||
components: { draggable, PreValueTag, ColorPicker, Webhook, AttrFilter, CustomCodeMirror, AllAttrDrawer },
|
||||
components: { draggable, PreValueTag, ColorPicker, Webhook, AttrFilter, CustomCodeMirror, AllAttrDrawer, PreValueDefine, PreValueBuiltIn },
|
||||
props: {
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
|
@ -259,12 +253,26 @@ export default {
|
|||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
enumValueType: {
|
||||
type: String,
|
||||
defualt: ENUM_VALUE_TYPE.INPUT
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defautValueColor,
|
||||
activeKey: 'define', // define webhook
|
||||
valueList: [],
|
||||
valueList: [
|
||||
[
|
||||
'',
|
||||
{
|
||||
style: {},
|
||||
icon: {},
|
||||
label: ''
|
||||
}
|
||||
]
|
||||
],
|
||||
form: {
|
||||
ret_key: '',
|
||||
},
|
||||
|
@ -331,6 +339,10 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async getCITypeAttributesById() {
|
||||
if (!this.CITypeId) {
|
||||
this.curModelAttrList = []
|
||||
return
|
||||
}
|
||||
const res = await getCITypeAttributesById(this.CITypeId)
|
||||
let curModelAttrList = []
|
||||
if (res?.attributes?.length) {
|
||||
|
@ -339,47 +351,36 @@ export default {
|
|||
this.curModelAttrList = curModelAttrList
|
||||
},
|
||||
|
||||
addNewValue(newValue, newStyle, newIcon) {
|
||||
if (newValue) {
|
||||
const idx = this.valueList.findIndex((v) => v[0] === newValue)
|
||||
if (idx > -1) {
|
||||
this.$message.warning(this.$t('cmdb.ciType.valueExisted'))
|
||||
} else {
|
||||
this.valueList.push([newValue, { style: newStyle, icon: { ...newIcon } }])
|
||||
}
|
||||
}
|
||||
},
|
||||
deleteValue(item) {
|
||||
const _valueList = _.cloneDeep(this.valueList)
|
||||
const idx = _valueList.findIndex((v) => v[0] === item[0])
|
||||
if (idx > -1) {
|
||||
_valueList.splice(idx, 1)
|
||||
this.valueList = _valueList
|
||||
}
|
||||
},
|
||||
editValue(item, newValue, newStyle, newIcon) {
|
||||
const _valueList = _.cloneDeep(this.valueList)
|
||||
const idx = _valueList.findIndex((v) => v[0] === item[0])
|
||||
if (idx > -1) {
|
||||
_valueList[idx] = [newValue, { style: newStyle, icon: { ...newIcon } }]
|
||||
this.valueList = _valueList
|
||||
}
|
||||
},
|
||||
getData() {
|
||||
if (this.activeKey === 'define') {
|
||||
if (this.activeKey === 'builtin') {
|
||||
return {
|
||||
choice_value: this.valueList,
|
||||
choice_web_hook: null,
|
||||
choice_other: null,
|
||||
choice_builtin: null,
|
||||
}
|
||||
} else if (this.activeKey === 'define') {
|
||||
if (this.validateDefine()) {
|
||||
return {
|
||||
isError: true
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
choice_value: this.valueList.filter((item) => item?.[0]),
|
||||
choice_web_hook: null,
|
||||
choice_other: null,
|
||||
choice_builtin: null
|
||||
}
|
||||
} else if (this.activeKey === 'webhook') {
|
||||
const choice_web_hook = this.$refs.webhook.getParams()
|
||||
choice_web_hook.ret_key = this.form.ret_key
|
||||
return { choice_value: [], choice_web_hook, choice_other: null }
|
||||
return { choice_value: [], choice_web_hook, choice_other: null, choice_builtin: null }
|
||||
} else if (this.activeKey === 'script') {
|
||||
return {
|
||||
choice_value: [],
|
||||
choice_web_hook: null,
|
||||
choice_builtin: null,
|
||||
choice_other: {
|
||||
script: this.script,
|
||||
cascade_attributes: this.cascade_attributes,
|
||||
|
@ -395,9 +396,22 @@ export default {
|
|||
choice_value: [],
|
||||
choice_web_hook: null,
|
||||
choice_other,
|
||||
choice_builtin: null,
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
validateDefine() {
|
||||
const valueList = this.valueList.filter((item) => item?.[0])
|
||||
const isRepeat = _.uniq(valueList.map(item => item?.[0] || '')).length !== valueList.length
|
||||
if (isRepeat) {
|
||||
this.$message.warning(this.$t('cmdb.ciType.enumValueTip2'))
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
|
||||
setData({ choice_value, choice_web_hook, choice_other }) {
|
||||
if (choice_web_hook) {
|
||||
this.activeKey = 'webhook'
|
||||
|
@ -425,7 +439,26 @@ export default {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
this.valueList = choice_value
|
||||
let valueList = [[
|
||||
'',
|
||||
{
|
||||
style: {},
|
||||
icon: {},
|
||||
label: ''
|
||||
}
|
||||
]]
|
||||
if (choice_value?.length) {
|
||||
valueList = choice_value.map((item) => {
|
||||
return [
|
||||
item[0],
|
||||
{
|
||||
...item[1],
|
||||
label: item?.[1]?.['label'] || item[0]
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
this.valueList = valueList
|
||||
this.activeKey = 'define'
|
||||
}
|
||||
const dom = document.querySelector('#preValueArea .ant-tabs-ink-bar')
|
||||
|
@ -436,6 +469,56 @@ export default {
|
|||
dom.style.backgroundColor = '#2f54eb'
|
||||
}
|
||||
},
|
||||
|
||||
resetData() {
|
||||
this.activeKey = 'define'
|
||||
this.$set(this, 'valueList', [
|
||||
[
|
||||
'',
|
||||
{
|
||||
style: {},
|
||||
icon: {},
|
||||
label: ''
|
||||
}
|
||||
]
|
||||
])
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.builtInRef) {
|
||||
this.$refs.builtInRef.setData({})
|
||||
}
|
||||
|
||||
if (this.$refs.webhook) {
|
||||
this.$refs.webhook.setParams({})
|
||||
}
|
||||
this.form.ret_key = ''
|
||||
|
||||
this.script = ''
|
||||
this.cascade_attributes = []
|
||||
if (this.$refs.codemirror) {
|
||||
this.$refs.codemirror.initCodeMirror('')
|
||||
}
|
||||
|
||||
this.choice_other = {
|
||||
type_ids: undefined,
|
||||
attr_id: undefined
|
||||
}
|
||||
if (this.$refs.attrFilter) {
|
||||
this.$refs.attrFilter.init(true, false)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
initEnumValue() {
|
||||
if (this.valueList) {
|
||||
const valueList = _.cloneDeep(this.valueList)
|
||||
valueList.forEach((item) => {
|
||||
item[0] = ''
|
||||
})
|
||||
this.$set(this, 'valueList', valueList)
|
||||
}
|
||||
},
|
||||
|
||||
setExpFromFilter(filterExp) {
|
||||
if (filterExp) {
|
||||
this.filterExp = `${filterExp}`
|
||||
|
@ -462,6 +545,24 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.tab-builtin {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&-tag {
|
||||
background-color: #E1EFFF;
|
||||
color: #2F54EB;
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
padding: 0 3px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.pre-value-edit-color {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -481,6 +582,12 @@ export default {
|
|||
line-height: 22px;
|
||||
color: #a5a9bc;
|
||||
}
|
||||
|
||||
.all-attr-btn {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
(node) => {
|
||||
return {
|
||||
id: node[0],
|
||||
label: node[0],
|
||||
label: node[1].label || node[0],
|
||||
children: node.children,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
export const BUILT_IN_TYPE = {
|
||||
DEPARTMENT: 'department', // 部门
|
||||
USER: 'user', // 用户
|
||||
USER_GROUP: 'userGroup' // 用户组
|
||||
}
|
||||
|
||||
export const DISPLAY_VALUE_SELECT = [
|
||||
{ label: 'cs.companyStructure.nickname', value: 'nickname' },
|
||||
{ label: 'cs.companyStructure.email', value: 'email' },
|
||||
{ label: 'cs.companyStructure.mobile', value: 'mobile' },
|
||||
]
|
||||
|
||||
export const USER_FILTER_SELECT = [
|
||||
{ label: 'cs.companyStructure.nickname', value: 'nickname' },
|
||||
{ label: 'cs.companyStructure.username', value: 'username' },
|
||||
{ label: 'cs.companyStructure.email', value: 'email' },
|
||||
{
|
||||
label: 'cs.companyStructure.sex',
|
||||
value: 'sex',
|
||||
is_choice: true,
|
||||
choice_value: [
|
||||
{ label: 'cs.companyStructure.male', value: '男' },
|
||||
{ label: 'cs.companyStructure.female', value: '女' },
|
||||
],
|
||||
},
|
||||
{ label: 'cs.companyStructure.mobile', value: 'mobile' },
|
||||
{ label: 'cs.companyStructure.departmentName', value: 'department_name' },
|
||||
{ label: 'cs.companyStructure.positionName', value: 'position_name' },
|
||||
{ label: 'cs.companyStructure.supervisor', value: 'direct_supervisor_id' },
|
||||
{ label: 'cs.companyStructure.annualLeave', value: 'annual_leave' },
|
||||
{ label: 'cs.companyStructure.currentCompany', value: 'current_company' },
|
||||
{ label: 'cs.companyStructure.dfcEntryDate', value: 'dfc_entry_date' },
|
||||
{ label: 'cs.companyStructure.entryDate', value: 'entry_date' },
|
||||
{
|
||||
label: 'cs.companyStructure.isInternship',
|
||||
value: 'is_internship',
|
||||
is_choice: true,
|
||||
choice_value: [
|
||||
{ label: 'cs.companyStructure.fullTime', value: 0 },
|
||||
{ label: 'cs.companyStructure.internship', value: 1 },
|
||||
],
|
||||
},
|
||||
{ label: 'cs.companyStructure.leaveDate', value: 'leave_date' },
|
||||
{ label: 'cs.companyStructure.idCard', value: 'id_card' },
|
||||
{ label: 'cs.companyStructure.nation', value: 'nation' },
|
||||
{ label: 'cs.companyStructure.idPlace', value: 'id_place' },
|
||||
{
|
||||
label: 'cs.companyStructure.party',
|
||||
value: 'party',
|
||||
is_choice: true,
|
||||
choice_value: [
|
||||
{ label: 'cs.companyStructure.partyMember', value: '党员' },
|
||||
{ label: 'cs.companyStructure.member', value: '团员' },
|
||||
{ label: 'cs.companyStructure.masses', value: '群众' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'cs.companyStructure.householdRegistrationType',
|
||||
value: 'household_registration_type',
|
||||
is_choice: true,
|
||||
choice_value: [
|
||||
{ label: 'cs.companyStructure.town', value: '城镇' },
|
||||
{ label: 'cs.companyStructure.agriculture', value: '农业' },
|
||||
],
|
||||
},
|
||||
{ label: 'cs.companyStructure.hometown', value: 'hometown' },
|
||||
{
|
||||
label: 'cs.companyStructure.marry',
|
||||
value: 'marry',
|
||||
is_choice: true,
|
||||
choice_value: [
|
||||
{ label: 'cs.companyStructure.unmarried', value: '未婚' },
|
||||
{ label: 'cs.companyStructure.married', value: '已婚' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'cs.companyStructure.maxDegree',
|
||||
value: 'max_degree',
|
||||
is_choice: true,
|
||||
choice_value: [
|
||||
{ label: 'cs.companyStructure.phd', value: '博士' },
|
||||
{ label: 'cs.companyStructure.master', value: '硕士' },
|
||||
{
|
||||
label: 'cs.companyStructure.undergraduate',
|
||||
value: '本科',
|
||||
},
|
||||
{ label: 'cs.companyStructure.specialist', value: '专科' },
|
||||
{ label: 'cs.companyStructure.highSchool', value: '高中' },
|
||||
],
|
||||
},
|
||||
{ label: 'cs.companyStructure.emergencyPerson', value: 'emergency_person' },
|
||||
{ label: 'cs.companyStructure.emergencyPhone', value: 'emergency_phone' },
|
||||
{ label: 'cs.companyStructure.bankCardNumber', value: 'bank_card_number' },
|
||||
{ label: 'cs.companyStructure.bankCardName', value: 'bank_card_name' },
|
||||
{ label: 'cs.companyStructure.openingBank', value: 'opening_bank' },
|
||||
{ label: 'cs.companyStructure.accountOpeningLocation', value: 'account_opening_location' },
|
||||
{ label: 'cs.companyStructure.birthDate', value: 'birth_date' },
|
||||
{ label: 'cs.companyStructure.nationalityRegion', value: 'nationality_region' },
|
||||
{ label: 'cs.companyStructure.birthPlace', value: 'birth_place' },
|
||||
{ label: 'cs.companyStructure.firstEntryDate', value: 'first_entry_date' },
|
||||
{ label: 'cs.companyStructure.estimatedDepartureDate', value: 'estimated_departure_date' },
|
||||
// { label: '角色', value: 'roles' },
|
||||
{ label: 'cs.companyStructure.lastLogin', value: 'last_login' },
|
||||
]
|
|
@ -0,0 +1,279 @@
|
|||
<template>
|
||||
<div class="builtin">
|
||||
<div class="builtin-tab">
|
||||
<div
|
||||
v-for="(item) in tabList"
|
||||
:key="item.key"
|
||||
:class="['builtin-tab-item', activeKey === item.key ? 'builtin-tab-item_active' : '']"
|
||||
@click="clickTab(item.key)"
|
||||
>
|
||||
<ops-icon :type="item.icon" class="builtin-tab-item-icon" />
|
||||
<span class="builtin-tab-item-title">{{ $t(item.title) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="activeKey === BUILT_IN_TYPE.DEPARTMENT"
|
||||
class="builtin-department"
|
||||
>
|
||||
<a-icon class="builtin-department-icon" type="info-circle" />
|
||||
<span class="builtin-department-tip">{{ $t('cmdb.ciType.departmentTip') }}</span>
|
||||
</div>
|
||||
|
||||
<a-form
|
||||
:form="form"
|
||||
v-show="activeKey === BUILT_IN_TYPE.USER"
|
||||
class="builtin-user"
|
||||
>
|
||||
<a-form-item
|
||||
:label="$t('cmdb.ciType.filterUsers')"
|
||||
:label-col="formLayout.labelCol"
|
||||
:wrapper-col="formLayout.wrapperCol"
|
||||
>
|
||||
<UserFilterComp
|
||||
ref="userFilterRef"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
:label="$t('cmdb.ciType.departmentCascadeDisplay')"
|
||||
v-if="activeKey === BUILT_IN_TYPE.USER"
|
||||
:label-col="formLayout.labelCol"
|
||||
:wrapper-col="formLayout.wrapperCol"
|
||||
>
|
||||
<a-switch
|
||||
v-decorator="['cascade_display', { rules: [{ required: false }], valuePropName: 'checked', initialValue: false }]"
|
||||
></a-switch>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-if="activeKey === BUILT_IN_TYPE.USER"
|
||||
:label="$t('cmdb.ciType.displayValue')"
|
||||
:label-col="formLayout.labelCol"
|
||||
:wrapper-col="formLayout.wrapperCol"
|
||||
>
|
||||
<a-select
|
||||
class="builtin-select"
|
||||
v-decorator="['display_value', { rules: [{ required: true, message: $t('cmdb.ciType.displayValueSelectTip') }], initialValue: 'nickname' }]"
|
||||
showSearch
|
||||
optionFilterProp="title"
|
||||
:placeholder="$t('cmdb.ciType.displayValueSelectTip')"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="(item) in DISPLAY_VALUE_SELECT"
|
||||
:value="item.value"
|
||||
:key="item.value"
|
||||
:title="$t(item.label)"
|
||||
>
|
||||
{{ $t(item.label) }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<a-form
|
||||
:form="form"
|
||||
v-if="activeKey === BUILT_IN_TYPE.USER_GROUP"
|
||||
class="builtin-usergroup"
|
||||
>
|
||||
<a-form-item
|
||||
:label="$t('cmdb.ciType.userGroup')"
|
||||
:label-col="formLayout.labelCol"
|
||||
:wrapper-col="formLayout.wrapperCol"
|
||||
>
|
||||
<a-select
|
||||
class="builtin-select"
|
||||
v-decorator="['user_group_key', { rules: [{ required: true, message: $t('cmdb.ciType.userGroupSelectTip') }] }]"
|
||||
showSearch
|
||||
optionFilterProp="title"
|
||||
:placeholder="$t('cmdb.ciType.userGroupSelectTip')"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="(item) in userGroupList"
|
||||
:value="item.group_id"
|
||||
:key="item.group_id"
|
||||
:title="item.group_name"
|
||||
>
|
||||
{{ item.group_name }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
:label-col="formLayout.labelCol"
|
||||
:wrapper-col="formLayout.wrapperCol"
|
||||
:label="$t('cmdb.ciType.displayValue')"
|
||||
>
|
||||
<a-select
|
||||
class="builtin-select"
|
||||
v-decorator="['display_value', { rules: [{ required: true, message: $t('cmdb.ciType.displayValueSelectTip') }], initialValue: 'nickname' }]"
|
||||
showSearch
|
||||
optionFilterProp="title"
|
||||
:placeholder="$t('cmdb.ciType.displayValueSelectTip')"
|
||||
>
|
||||
<a-select-option
|
||||
v-for="(item) in DISPLAY_VALUE_SELECT"
|
||||
:value="item.value"
|
||||
:key="item.value"
|
||||
:title="$t(item.label)"
|
||||
>
|
||||
{{ $t(item.label) }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { BUILT_IN_TYPE, DISPLAY_VALUE_SELECT } from './constants.js'
|
||||
import UserFilterComp from './userFilterComp/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'PreValueBuiltIn',
|
||||
components: { UserFilterComp },
|
||||
data() {
|
||||
return {
|
||||
BUILT_IN_TYPE,
|
||||
DISPLAY_VALUE_SELECT,
|
||||
activeKey: BUILT_IN_TYPE.DEPARTMENT,
|
||||
tabList: [
|
||||
{
|
||||
key: BUILT_IN_TYPE.DEPARTMENT,
|
||||
title: 'cmdb.ciType.department',
|
||||
icon: 'veops-department'
|
||||
},
|
||||
{
|
||||
key: BUILT_IN_TYPE.USER,
|
||||
title: 'cmdb.ciType.user',
|
||||
icon: 'icon-shidi-yonghu'
|
||||
},
|
||||
{
|
||||
key: BUILT_IN_TYPE.USER_GROUP,
|
||||
title: 'cmdb.ciType.userGroup',
|
||||
icon: 'ops-setting-group'
|
||||
}
|
||||
],
|
||||
userGroupList: [],
|
||||
allFlatEmployees: [],
|
||||
form: this.$form.createForm(this),
|
||||
formLayout: {
|
||||
labelCol: { span: 5 },
|
||||
wrapperCol: { span: 16 },
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setData(data) {
|
||||
this.activeKey = data?.builtin_type || BUILT_IN_TYPE.DEPARTMENT
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.form.setFieldsValue({
|
||||
cascade_display: data?.cascade_display ?? false,
|
||||
display_value: data?.display_value ?? undefined,
|
||||
user_group_key: data?.user_group_key ?? undefined
|
||||
})
|
||||
|
||||
this.$refs.userFilterRef.setRuleList(data?.filter_rule_list || [])
|
||||
})
|
||||
},
|
||||
|
||||
getData() {
|
||||
let params = {}
|
||||
this.form.validateFields({ force: true }, (err, values) => {
|
||||
if (err) {
|
||||
params.isError = true
|
||||
return
|
||||
}
|
||||
|
||||
params = {
|
||||
...values,
|
||||
builtin_type: this.activeKey,
|
||||
}
|
||||
|
||||
if (this.activeKey === BUILT_IN_TYPE.USER) {
|
||||
params.filter_rule_list = this.$refs.userFilterRef.getRuleList()
|
||||
}
|
||||
})
|
||||
|
||||
return params
|
||||
},
|
||||
|
||||
async clickTab(key) {
|
||||
this.activeKey = key
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.builtin {
|
||||
width: 100%;
|
||||
|
||||
&-tab {
|
||||
padding: 4px 80px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 60px;
|
||||
|
||||
&-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
border: solid 1px #E4E7ED;
|
||||
border-radius: 2px;
|
||||
padding: 0 20px;
|
||||
min-width: 72px;
|
||||
height: 64px;
|
||||
cursor: pointer;
|
||||
|
||||
&-icon {
|
||||
font-size: 20px;
|
||||
color: #A5A9BC;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 14px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
&_active {
|
||||
border-color: #B1C9FF;
|
||||
|
||||
.builtin-tab-item-icon {
|
||||
color: #7F97FA;
|
||||
}
|
||||
|
||||
.builtin-tab-item-title {
|
||||
color: #2F54EB;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-department {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 60px;
|
||||
|
||||
&-icon {
|
||||
font-size: 12px;
|
||||
color: #A5A9BC;
|
||||
}
|
||||
|
||||
&-tip {
|
||||
color: #4E5969;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&-select {
|
||||
width: 240px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,16 @@
|
|||
export const ruleTypeList = [
|
||||
{ value: '&', label: 'cs.components.and' },
|
||||
{ value: '|', label: 'cs.components.or' },
|
||||
]
|
||||
|
||||
export const expList = [
|
||||
{ value: 1, label: 'cs.components.equal' },
|
||||
{ value: 2, label: 'cs.components.notEqual' },
|
||||
{ value: 7, label: 'cs.components.isEmpty' },
|
||||
{ value: 8, label: 'cs.components.isNotEmpty' },
|
||||
]
|
||||
|
||||
export const compareTypeList = [
|
||||
{ value: 5, label: 'cs.components.moreThan' },
|
||||
{ value: 6, label: 'cs.components.lessThan' },
|
||||
]
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<treeselect
|
||||
class="employee-tree-select"
|
||||
:style="{ width: '100px' }"
|
||||
:disable-branch-nodes="!multiple"
|
||||
:multiple="multiple"
|
||||
:options="employeeTreeSelectOption"
|
||||
:placeholder="readOnly ? '' : placeholder || $t('cs.components.selectEmployee')"
|
||||
v-model="treeValue"
|
||||
:max-height="150"
|
||||
:noChildrenText="$t('cs.components.empty')"
|
||||
:noOptionsText="$t('cs.components.empty')"
|
||||
:class="className ? className : 'ops-setting-treeselect'"
|
||||
value-consists-of="LEAF_PRIORITY"
|
||||
:limit="limit"
|
||||
:limitText="(count) => `+ ${count}`"
|
||||
v-bind="$attrs"
|
||||
:zIndex="1050"
|
||||
:flat="flat"
|
||||
>
|
||||
<div
|
||||
:title="node.label"
|
||||
slot="option-label"
|
||||
slot-scope="{ node }"
|
||||
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
|
||||
>
|
||||
{{ node.label }}
|
||||
</div>
|
||||
</treeselect>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import { formatOption } from '@/utils/util'
|
||||
|
||||
export default {
|
||||
name: 'EmployeeTreeSelect',
|
||||
components: {
|
||||
Treeselect,
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Array, Number, null],
|
||||
default: null,
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: 'ops-setting-treeselect',
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
idType: {
|
||||
type: Number,
|
||||
default: 3,
|
||||
},
|
||||
departmentKey: {
|
||||
type: String,
|
||||
default: 'department_id',
|
||||
},
|
||||
employeeKey: {
|
||||
type: String,
|
||||
default: 'employee_id',
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
flat: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
inject: {
|
||||
provide_allTreeDepAndEmp: {
|
||||
from: 'provide_allTreeDepAndEmp',
|
||||
default: () => {
|
||||
return () => {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
readOnly: {
|
||||
from: 'readOnly',
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
treeValue: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('change', val)
|
||||
return val
|
||||
},
|
||||
},
|
||||
allTreeDepAndEmp() {
|
||||
return this.provide_allTreeDepAndEmp()
|
||||
},
|
||||
employeeTreeSelectOption() {
|
||||
const option = formatOption(this.allTreeDepAndEmp, this.idType, false, this.departmentKey, this.employeeKey)
|
||||
return option
|
||||
},
|
||||
},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.employee-tree-select {
|
||||
/deep/ .vue-treeselect__menu {
|
||||
width: 100px;
|
||||
overflow-x: auto;
|
||||
|
||||
& > .vue-treeselect__list {
|
||||
width: fit-content;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.vue-treeselect__label-container {
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.vue-treeselect__option {
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,347 @@
|
|||
<template>
|
||||
<div class="user-filter">
|
||||
<a-button
|
||||
v-if="!ruleList.length"
|
||||
type="primary"
|
||||
ghost
|
||||
size="small"
|
||||
class="add-btn"
|
||||
@click="handleAddRule"
|
||||
>
|
||||
<a-icon type="plus" />
|
||||
{{ $t('add') }}
|
||||
</a-button>
|
||||
<template v-else>
|
||||
<a-space :style="{ display: 'flex', marginBottom: '10px' }" v-for="(item, index) in ruleList" :key="item.id">
|
||||
<div :style="{ width: '50px', height: '24px', position: 'relative' }">
|
||||
<treeselect
|
||||
v-if="index"
|
||||
class="custom-treeselect"
|
||||
:style="{ width: '50px', '--custom-height': '36px', position: 'absolute', top: '-30px', left: 0 }"
|
||||
v-model="item.relation"
|
||||
:multiple="false"
|
||||
:clearable="false"
|
||||
searchable
|
||||
:options="ruleTypeList"
|
||||
:normalizer="
|
||||
(node) => {
|
||||
return {
|
||||
id: node.value,
|
||||
label: $t(node.label),
|
||||
children: node.children,
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
</treeselect>
|
||||
</div>
|
||||
<treeselect
|
||||
class="custom-treeselect"
|
||||
:style="{ width: '140px', '--custom-height': '36px' }"
|
||||
v-model="item.column"
|
||||
:multiple="false"
|
||||
:clearable="false"
|
||||
searchable
|
||||
:options="userFilterSelect"
|
||||
:maxHeight="150"
|
||||
:normalizer="
|
||||
(node) => {
|
||||
return {
|
||||
id: node.value,
|
||||
label: $t(node.label),
|
||||
children: node.children,
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<div
|
||||
slot="option-label"
|
||||
slot-scope="{ node }"
|
||||
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
|
||||
>
|
||||
<a-tooltip :title="$t(node.label)">
|
||||
{{ $t(node.label) }}
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div
|
||||
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
|
||||
slot="value-label"
|
||||
slot-scope="{ node }"
|
||||
>
|
||||
<a-tooltip :title="$t(node.label)">
|
||||
{{ $t(node.label) }}
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</treeselect>
|
||||
<treeselect
|
||||
class="custom-treeselect"
|
||||
:style="{ width: '90px', '--custom-height': '36px' }"
|
||||
v-model="item.operator"
|
||||
:multiple="false"
|
||||
:clearable="false"
|
||||
searchable
|
||||
:options="[...expList, ...compareTypeList]"
|
||||
:maxHeight="150"
|
||||
:normalizer="
|
||||
(node) => {
|
||||
return {
|
||||
id: node.value,
|
||||
label: $t(node.label),
|
||||
children: node.children,
|
||||
}
|
||||
}
|
||||
"
|
||||
@select="(value) => handleChangeExp(value, item, index)"
|
||||
>
|
||||
<div
|
||||
slot="option-label"
|
||||
slot-scope="{ node }"
|
||||
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
|
||||
>
|
||||
<a-tooltip :title="$t(node.label)">
|
||||
{{ $t(node.label) }}
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div
|
||||
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
|
||||
slot="value-label"
|
||||
slot-scope="{ node }"
|
||||
>
|
||||
<a-tooltip :title="$t(node.label)">
|
||||
{{ $t(node.label) }}
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</treeselect>
|
||||
<treeselect
|
||||
class="custom-treeselect"
|
||||
:style="{ width: '100px', '--custom-height': '36px' }"
|
||||
v-model="item.value"
|
||||
:multiple="false"
|
||||
:clearable="false"
|
||||
searchable
|
||||
v-if="isChoiceByProperty(item.column) && (item.operator === 1 || item.operator === 2)"
|
||||
:options="getChoiceValueByProperty(item.column)"
|
||||
:placeholder="$t('cs.components.selectPlaceholder')"
|
||||
:normalizer="
|
||||
(node) => {
|
||||
return {
|
||||
id: node.value,
|
||||
label: $t(node.label),
|
||||
children: node.children,
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<div
|
||||
:title="$t(node.label)"
|
||||
slot="option-label"
|
||||
slot-scope="{ node }"
|
||||
:style="{ width: '100%', whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }"
|
||||
>
|
||||
{{ $t(node.label) }}
|
||||
</div>
|
||||
</treeselect>
|
||||
<div v-else-if="item.column === 'direct_supervisor_id' && (item.operator === 1 || item.operator === 2)">
|
||||
<EmployeeTreeSelect v-model="item.value" className="custom-treeselect"/>
|
||||
</div>
|
||||
<a-input
|
||||
v-else-if="item.operator !== 7 && item.operator !== 8"
|
||||
size="small"
|
||||
v-model="item.value"
|
||||
:placeholder="item.exp === 'in' || item.exp === '~in' ? $t('cs.components.operatorInPlaceholder') : ''"
|
||||
class="ops-input"
|
||||
></a-input>
|
||||
<a-tooltip :title="$t('cs.components.copy')">
|
||||
<a class="operation" @click="handleCopyRule(item)"><ops-icon type="veops-copy"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="$t('delete')">
|
||||
<a class="operation" @click="handleDeleteRule(item)"><ops-icon type="veops-reduce"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="$t('add')">
|
||||
<a class="operation" @click="handleAddRule"><ops-icon type="veops-increase"/></a>
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import _ from 'lodash'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import { ruleTypeList, expList, compareTypeList } from './constants'
|
||||
import { USER_FILTER_SELECT } from '../constants'
|
||||
import EmployeeTreeSelect from './employeeTreeSelect.vue'
|
||||
|
||||
export default {
|
||||
name: 'UserFilterComp',
|
||||
components: {
|
||||
Treeselect,
|
||||
EmployeeTreeSelect
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
USER_FILTER_SELECT,
|
||||
ruleTypeList,
|
||||
expList,
|
||||
compareTypeList,
|
||||
ruleList: [],
|
||||
filterExp: '',
|
||||
userFilterSelect: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user'])
|
||||
},
|
||||
created() {
|
||||
this.initUserFilterSelect()
|
||||
},
|
||||
methods: {
|
||||
initUserFilterSelect() {
|
||||
const permissions = this.user?.detailPermissions?.backend?.find((item) => item.name === 'Employee_Fields')?.permissions
|
||||
const userFilterSelect = USER_FILTER_SELECT.filter((item) => {
|
||||
return permissions.includes(item.value)
|
||||
})
|
||||
this.userFilterSelect = userFilterSelect
|
||||
},
|
||||
async setRuleList(ruleList) {
|
||||
this.ruleList = ruleList?.length ? ruleList : []
|
||||
},
|
||||
handleAddRule() {
|
||||
this.ruleList.push({
|
||||
id: uuidv4(),
|
||||
relation: '&',
|
||||
column: this.userFilterSelect?.[0]?.value ?? null,
|
||||
operator: 1,
|
||||
value: null,
|
||||
})
|
||||
},
|
||||
handleCopyRule(item) {
|
||||
this.ruleList.push({ ...item, id: uuidv4() })
|
||||
},
|
||||
handleDeleteRule(item) {
|
||||
const idx = this.ruleList.findIndex((r) => r.id === item.id)
|
||||
if (idx > -1) {
|
||||
this.ruleList.splice(idx, 1)
|
||||
}
|
||||
},
|
||||
|
||||
getRuleList() {
|
||||
if (this.ruleList && this.ruleList.length) {
|
||||
const ruleList = _.cloneDeep(this.ruleList)
|
||||
ruleList.forEach((item, index) => {
|
||||
if (item.column === 'direct_supervisor_id') {
|
||||
ruleList[index].value = item.value ? (item.value + '').includes('-') ? +item.value.split('-')[1] : +item.value : 0
|
||||
}
|
||||
})
|
||||
if (ruleList?.length > 0) {
|
||||
ruleList[0].relation = '&'
|
||||
}
|
||||
|
||||
return ruleList.map((rule) => {
|
||||
return _.omit(rule, 'id')
|
||||
})
|
||||
}
|
||||
|
||||
return []
|
||||
},
|
||||
handleChangeExp({ value }, item, index) {
|
||||
const _ruleList = _.cloneDeep(this.ruleList)
|
||||
if (value === 7 || value === 8) {
|
||||
_ruleList[index] = {
|
||||
..._ruleList[index],
|
||||
value: null,
|
||||
operator: value
|
||||
}
|
||||
} else {
|
||||
_ruleList[index] = {
|
||||
..._ruleList[index],
|
||||
operator: value,
|
||||
}
|
||||
}
|
||||
this.ruleList = _ruleList
|
||||
},
|
||||
filterOption(input, option) {
|
||||
return option.componentOptions.children[1].children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
},
|
||||
isChoiceByProperty(column) {
|
||||
const _find = this.userFilterSelect.find((item) => item.value === column)
|
||||
if (_find) {
|
||||
return _find.is_choice
|
||||
}
|
||||
return false
|
||||
},
|
||||
getChoiceValueByProperty(column) {
|
||||
const _find = this.userFilterSelect.find((item) => item.value === column)
|
||||
if (_find) {
|
||||
return _find.choice_value
|
||||
}
|
||||
return []
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.user-filter {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
line-height: 36px;
|
||||
|
||||
.ops-input {
|
||||
height: 36px;
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-filter {
|
||||
.table-filter-add {
|
||||
margin-top: 10px;
|
||||
& > a {
|
||||
padding: 2px 8px;
|
||||
&:hover {
|
||||
background-color: #f0faff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.table-filter-extra-icon {
|
||||
padding: 0px 2px;
|
||||
&:hover {
|
||||
display: inline-block;
|
||||
border-radius: 5px;
|
||||
background-color: #f0faff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
font-size: 12px;
|
||||
width: 80px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.table-filter-extra-operation {
|
||||
.ant-popover-inner-content {
|
||||
padding: 3px 4px;
|
||||
.operation {
|
||||
cursor: pointer;
|
||||
width: 90px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 3px 4px;
|
||||
border-radius: 5px;
|
||||
transition: all 0.3s;
|
||||
&:hover {
|
||||
background-color: #f0faff;
|
||||
}
|
||||
> .anticon {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -39,3 +39,10 @@ export const compareTypeList = [
|
|||
{ value: '3', label: '<' },
|
||||
{ value: '4', label: '<=' },
|
||||
]
|
||||
|
||||
export const ENUM_VALUE_TYPE = {
|
||||
INPUT: 'input',
|
||||
DATE: 'date',
|
||||
DATE_TIME: 'dateTIme',
|
||||
NUMBER: 'number'
|
||||
}
|
||||
|
|
|
@ -0,0 +1,310 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-popover
|
||||
:visible="popoverVisible"
|
||||
placement="bottom"
|
||||
trigger="focus"
|
||||
overlayClassName="pre-value-edit-popover"
|
||||
@visibleChange="handleVisibleChange"
|
||||
>
|
||||
<div @click="popoverVisible = true" ref="popoverLabelRef">
|
||||
<a-input
|
||||
v-show="!labelData.label || popoverVisible"
|
||||
type="text"
|
||||
:style="{ width: '210px' }"
|
||||
:value="labelData.label"
|
||||
@change="changeLabel"
|
||||
>
|
||||
</a-input>
|
||||
|
||||
<div
|
||||
class="pre-value-tag"
|
||||
:style="labelData.style ? labelData.style : {}"
|
||||
v-show="!popoverVisible && labelData.label"
|
||||
>
|
||||
<span>
|
||||
<img
|
||||
v-if="labelData.icon.id && labelData.icon.url"
|
||||
:src="`/api/common-setting/v1/file/${labelData.icon.url}`"
|
||||
:style="{ maxHeight: '12px', maxWidth: '12px', marginRight: '5px' }"
|
||||
/>
|
||||
<ops-icon
|
||||
v-else-if="labelData.icon.name"
|
||||
:type="labelData.icon.name"
|
||||
:style="{ marginRight: '5px', color: labelData.icon.color || '#595959' }"
|
||||
/>
|
||||
<a-tooltip :title="labelData.label">
|
||||
<span class="pre-value-tag-text">{{ labelData.label }}</span>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ref="preValueEdit" slot="content">
|
||||
<a-divider orientation="left" style="margin:8px 0;color:gray;font-size:10px;">{{ $t('icon') }}</a-divider>
|
||||
<CustomIconSelect
|
||||
:style="{ marginLeft: '10px' }"
|
||||
:value="labelData.icon"
|
||||
@change="changeIcon"
|
||||
/>
|
||||
<a-divider orientation="left" style="margin:8px 0;color:gray;font-size:10px;">{{ $t('cmdb.ciType.font') }}</a-divider>
|
||||
<div :style="{ display: 'flex', justifyContent: 'space-around' }">
|
||||
<div
|
||||
@click="changeFontStyle('fontWeight', 'bold')"
|
||||
:class="`attributes-font-icon ${labelData.style.fontWeight === 'bold' ? 'attributes-font-icon-selected' : ''}`"
|
||||
>
|
||||
<a-icon type="bold" />
|
||||
</div>
|
||||
<div
|
||||
@click="changeFontStyle('fontStyle', 'italic')"
|
||||
:class="`attributes-font-icon ${labelData.style.fontStyle === 'italic' ? 'attributes-font-icon-selected' : ''}`"
|
||||
>
|
||||
<a-icon type="italic" />
|
||||
</div>
|
||||
<div
|
||||
@click="changeFontStyle('textDecoration', 'underline')"
|
||||
:class="
|
||||
`attributes-font-icon ${labelData.style.textDecoration === 'underline' ? 'attributes-font-icon-selected' : ''}`
|
||||
"
|
||||
>
|
||||
<a-icon type="underline" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-divider orientation="left" style="margin:8px 0;color:gray;font-size:10px;">{{ $t('cmdb.ciType.color') }}</a-divider>
|
||||
<div :style="{ display: 'flex', justifyContent: 'space-around' }">
|
||||
<div class="attributes-font-color">
|
||||
<a-icon type="font-colors" />
|
||||
<el-color-picker
|
||||
size="mini"
|
||||
:value="labelData.style.color"
|
||||
@change="(v) => changeFontStyle('color', v)"
|
||||
:predefine="defaultBGColors"
|
||||
>
|
||||
</el-color-picker>
|
||||
</div>
|
||||
<div class="attributes-font-color">
|
||||
<a-icon type="bg-colors" />
|
||||
<el-color-picker
|
||||
size="mini"
|
||||
:value="labelData.style.backgroundColor"
|
||||
@change="(v) => changeFontStyle('backgroundColor', v)"
|
||||
:predefine="defaultBGColors"
|
||||
>
|
||||
</el-color-picker>
|
||||
</div>
|
||||
</div>
|
||||
<a-divider orientation="left" style="margin:8px 0;color:gray;font-size:10px;">{{ $t('operation') }}</a-divider>
|
||||
<div style="text-align:right;">
|
||||
<a-tooltip
|
||||
:title="$t('delete')"
|
||||
>
|
||||
<a>
|
||||
<a-icon
|
||||
@click="handleDelete"
|
||||
style="margin-right:10px;color:red;"
|
||||
type="delete"
|
||||
/>
|
||||
</a>
|
||||
</a-tooltip>
|
||||
<a-tooltip
|
||||
:title="$t('confirm')"
|
||||
>
|
||||
<a>
|
||||
<a-icon @click="popoverVisible = false" style="margin-right:10px;color:green;" type="check"/>
|
||||
</a>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</a-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import { ColorPicker } from 'element-ui'
|
||||
import CustomIconSelect from '@/components/CustomIconSelect'
|
||||
import { defautValueColor, defaultBGColors } from '@/modules/cmdb/utils/const.js'
|
||||
import lang from 'element-ui/lib/locale/lang/en'
|
||||
import locale from 'element-ui/lib/locale'
|
||||
locale.use(lang)
|
||||
|
||||
export default {
|
||||
name: 'DefineLabel',
|
||||
components: { ElColorPicker: ColorPicker, CustomIconSelect },
|
||||
props: {
|
||||
labelData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defautValueColor,
|
||||
defaultBGColors,
|
||||
popoverVisible: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('click', this.eventListener)
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener('click', this.eventListener)
|
||||
},
|
||||
methods: {
|
||||
eventListener(e) {
|
||||
if (this.popoverVisible) {
|
||||
const dom = this.$refs.preValueEdit
|
||||
const dom_label = this.$refs.popoverLabelRef
|
||||
const dom_icon = document.getElementById(`custom-icon-select-popover`)
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
if (dom) {
|
||||
const isSelf =
|
||||
dom.contains(e.target) || (dom_label && dom_label.contains(e.target)) || (dom_icon && dom_icon.contains(e.target))
|
||||
if (!isSelf) {
|
||||
this.popoverVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleDelete() {
|
||||
this.popoverVisible = false
|
||||
this.$emit('deleteData')
|
||||
},
|
||||
|
||||
changeFontStyle(key, value) {
|
||||
const style = {
|
||||
...(this.labelData.style || {}),
|
||||
[key]: this.labelData.style[key] === value ? 'initial' : value,
|
||||
}
|
||||
this.$emit('change', 'style', style)
|
||||
},
|
||||
|
||||
changeLabel(e) {
|
||||
const value = e.target.value
|
||||
this.$emit('change', 'label', value)
|
||||
},
|
||||
|
||||
changeIcon(value) {
|
||||
this.$emit('change', 'icon', value)
|
||||
},
|
||||
|
||||
handleVisibleChange(v) {
|
||||
if (!v) {
|
||||
this.popoverVisible = false
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.pre-value-edit-color {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
.pre-value-edit-color-item {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
width: 25px;
|
||||
height: 20px;
|
||||
margin: 5px;
|
||||
}
|
||||
}
|
||||
.pre-value-tag {
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
max-width: 100%;
|
||||
|
||||
&-text {
|
||||
overflow: hidden;
|
||||
text-wrap: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
> span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&:hover .pre-value-tag-dropdown-icon {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
.pre-value-tag-dropdown {
|
||||
font-size: 10px;
|
||||
color: #999999;
|
||||
&:hover {
|
||||
color: #2f54eb;
|
||||
}
|
||||
.pre-value-tag-dropdown-icon {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.pre-value-tag-input {
|
||||
border: none;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
font-size: 12px;
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
.pre-value-edit-popover.ant-popover-placement-top .ant-popover-content {
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
.pre-value-edit-popover.ant-popover-placement-bottom .ant-popover-content {
|
||||
margin-top: -10px;
|
||||
}
|
||||
.pre-value-edit-popover {
|
||||
.ant-popover-content {
|
||||
width: 150px;
|
||||
.ant-popover-arrow {
|
||||
display: none;
|
||||
}
|
||||
.ant-popover-inner-content {
|
||||
padding: 3px 4px;
|
||||
}
|
||||
}
|
||||
.attributes-font-icon {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
border: 1px solid #fff;
|
||||
&:hover {
|
||||
background-color: #eeeeee;
|
||||
border-color: #606266;
|
||||
}
|
||||
> i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
.attributes-font-icon-selected {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
.attributes-font-color {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: 50%;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,245 @@
|
|||
<template>
|
||||
<div class="define-wrap">
|
||||
<a-button
|
||||
v-if="!defineList.length"
|
||||
type="primary"
|
||||
ghost
|
||||
:disabled="disabled"
|
||||
size="small"
|
||||
class="add-btn"
|
||||
@click="addData"
|
||||
>
|
||||
<a-icon type="plus" />
|
||||
{{ $t('add') }}
|
||||
</a-button>
|
||||
|
||||
<vxe-table
|
||||
v-else
|
||||
ref="xTable"
|
||||
:data="defineList"
|
||||
size="mini"
|
||||
show-header-overflow
|
||||
:row-config="{ height: 46 }"
|
||||
:min-height="75"
|
||||
border="outer"
|
||||
class="define-wrap-table"
|
||||
>
|
||||
<vxe-column field="value" width="230" :title="$t('cmdb.ciType.enumValue')">
|
||||
<template #header="{ column }">
|
||||
<span class="table-header-required">*</span>
|
||||
{{ column.title }}
|
||||
</template>
|
||||
<template #default="{ row, rowIndex }">
|
||||
<a-input
|
||||
v-if="enumValueType === ENUM_VALUE_TYPE.INPUT"
|
||||
:value="row.value"
|
||||
:placeholder="$t('cmdb.ciType.valueInputTip')"
|
||||
@change="(e) => changeValue(rowIndex, e.target.value)"
|
||||
></a-input>
|
||||
<a-input-number
|
||||
v-else-if="enumValueType === ENUM_VALUE_TYPE.NUMBER"
|
||||
:value="row.value"
|
||||
@change="(v) => changeValue(rowIndex, v)"
|
||||
>
|
||||
</a-input-number>
|
||||
<a-date-picker
|
||||
v-else
|
||||
style="width: 100%"
|
||||
:value="row.value"
|
||||
:format="enumValueType === ENUM_VALUE_TYPE.DATE ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
|
||||
:showTime="enumValueType === ENUM_VALUE_TYPE.DATE ? false : { format: 'HH:mm:ss' }"
|
||||
@change="(e) => changeDate(rowIndex, e)"
|
||||
/>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column width="230" :title="$t('cmdb.ciType.label')">
|
||||
<template #default="{ row, rowIndex }">
|
||||
<DefineLabel
|
||||
:labelData="row"
|
||||
@change="(key, value) => changeStyle(rowIndex, key, value)"
|
||||
@deleteData="handleClear(rowIndex)"
|
||||
/>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<div class="define-wrap-action">
|
||||
<div
|
||||
v-for="(item, index) in defineList"
|
||||
:key="item.id"
|
||||
class="define-wrap-action-item"
|
||||
>
|
||||
<a-icon
|
||||
type="plus-circle"
|
||||
class="define-wrap-action-item-icon"
|
||||
@click="addData(index)"
|
||||
/>
|
||||
<a-icon
|
||||
type="minus-circle"
|
||||
class="define-wrap-action-item-icon"
|
||||
@click="deleteData(index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import _ from 'lodash'
|
||||
import DefineLabel from './defineLabel.vue'
|
||||
import { ENUM_VALUE_TYPE } from '../constants.js'
|
||||
|
||||
export default {
|
||||
name: 'PreValueDefine',
|
||||
components: {
|
||||
DefineLabel
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 枚举值控件类型
|
||||
enumValueType: {
|
||||
type: String,
|
||||
default: ENUM_VALUE_TYPE.INPUT
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change',
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ENUM_VALUE_TYPE
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
defineList: {
|
||||
get() {
|
||||
return this.value.map((item) => {
|
||||
return {
|
||||
value: item?.[0] ?? '',
|
||||
...(item?.[1] ?? {}),
|
||||
id: uuidv4()
|
||||
}
|
||||
})
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('change', val.map((item) => {
|
||||
return [
|
||||
item?.value ?? '',
|
||||
{
|
||||
style: item?.style ?? {},
|
||||
icon: item?.icon ?? {},
|
||||
label: item?.label ?? '',
|
||||
}
|
||||
]
|
||||
}))
|
||||
return val
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
addData(index) {
|
||||
const list = _.cloneDeep(this.value)
|
||||
list.splice(index + 1, 0, [
|
||||
'',
|
||||
{
|
||||
style: {},
|
||||
icon: {},
|
||||
label: ''
|
||||
}
|
||||
])
|
||||
this.$emit('change', list)
|
||||
},
|
||||
deleteData(index) {
|
||||
if (this.value.length <= 1) {
|
||||
this.$message.error(this.$t('cmdb.ad.deleteTip'))
|
||||
return
|
||||
}
|
||||
const list = _.cloneDeep(this.value)
|
||||
list.splice(index, 1)
|
||||
this.$emit('change', list)
|
||||
},
|
||||
|
||||
changeValue(rowIndex, value) {
|
||||
const list = _.cloneDeep(this.value)
|
||||
list[rowIndex][0] = value
|
||||
this.$emit('change', list)
|
||||
},
|
||||
|
||||
changeDate(rowIndex, e) {
|
||||
const format = this.enumValueType === ENUM_VALUE_TYPE.DATE ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'
|
||||
const value = e.format(format)
|
||||
const list = _.cloneDeep(this.value)
|
||||
list[rowIndex][0] = value
|
||||
this.$emit('change', list)
|
||||
},
|
||||
|
||||
changeStyle(rowIndex, key, value) {
|
||||
const list = _.cloneDeep(this.value)
|
||||
list[rowIndex][1] = {
|
||||
...list[rowIndex][1],
|
||||
[key]: value
|
||||
}
|
||||
this.$emit('change', list)
|
||||
},
|
||||
|
||||
handleClear(rowIndex) {
|
||||
const list = _.cloneDeep(this.value)
|
||||
list[rowIndex][1] = {
|
||||
style: {},
|
||||
icon: {},
|
||||
label: ''
|
||||
}
|
||||
this.$emit('change', list)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.define-wrap {
|
||||
display: flex;
|
||||
|
||||
.add-btn {
|
||||
font-size: 12px;
|
||||
padding: 1px 7px;
|
||||
}
|
||||
|
||||
&-table {
|
||||
flex-shrink: 0;
|
||||
|
||||
.table-header-required {
|
||||
color: #FD4C6A;
|
||||
}
|
||||
|
||||
/deep/ .ant-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&-action {
|
||||
flex-shrink: 0;
|
||||
margin-left: 11px;
|
||||
padding-top: 36px;
|
||||
|
||||
&-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 46px;
|
||||
gap: 12px;
|
||||
|
||||
&-icon {
|
||||
cursor: pointer;
|
||||
color: #2F54EB;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -179,6 +179,7 @@
|
|||
>
|
||||
<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>
|
||||
|
@ -674,6 +675,11 @@ export default {
|
|||
.modal-attribute-action {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.model-select-name {
|
||||
font-size: 12px;
|
||||
color: #A5A9BC;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
@change="handleSourceTypeChange"
|
||||
:filterOption="filterOption"
|
||||
>
|
||||
<a-select-option :value="CIType.id" :key="CIType.id" v-for="CIType in displayCITypes">{{
|
||||
CIType.alias || CIType.name
|
||||
}}</a-select-option>
|
||||
<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 :label="$t('cmdb.ciType.dstCIType')">
|
||||
|
@ -39,6 +40,7 @@
|
|||
>
|
||||
<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>
|
||||
|
@ -408,4 +410,9 @@ export default {
|
|||
.modal-attribute-action {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.model-select-name {
|
||||
font-size: 12px;
|
||||
color: #A5A9BC;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -63,6 +63,14 @@
|
|||
{{ id }}
|
||||
</a>
|
||||
</template>
|
||||
<template #default="{row}" v-else-if="col.is_choice">
|
||||
<span
|
||||
v-for="value in (col.is_list ? row[col.field] : [row[col.field]])"
|
||||
:key="value"
|
||||
>
|
||||
{{ getChoiceValueLabel(col, value) || value }}
|
||||
</span>
|
||||
</template>
|
||||
<template #default="{row}" v-else-if="col.value_type == '6'">
|
||||
<span v-if="col.value_type == '6' && row[col.field]">{{ JSON.stringify(row[col.field]) }}</span>
|
||||
</template>
|
||||
|
@ -253,6 +261,14 @@ export default {
|
|||
this.currentPage = page
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
getChoiceValueLabel(col, colValue) {
|
||||
const _find = col.filters.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.label || ''
|
||||
}
|
||||
return ''
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
"
|
||||
target="_blank"
|
||||
>
|
||||
{{ item }}
|
||||
{{ getChoiceValueLabel(col, item) || item }}
|
||||
</a>
|
||||
</template>
|
||||
<PasswordField
|
||||
|
@ -143,11 +143,13 @@
|
|||
margin: '2px',
|
||||
...getChoiceValueStyle(col, value),
|
||||
}"
|
||||
><ops-icon
|
||||
:style="{ color: getChoiceValueIcon(col, value).color }"
|
||||
:type="getChoiceValueIcon(col, value).name"
|
||||
/>{{ value }}</span
|
||||
>
|
||||
<ops-icon
|
||||
:style="{ color: getChoiceValueIcon(col, value).color }"
|
||||
:type="getChoiceValueIcon(col, value).name"
|
||||
/>
|
||||
{{ getChoiceValueLabel(col, value) || value }}
|
||||
</span>
|
||||
</template>
|
||||
<span
|
||||
v-else
|
||||
|
@ -162,8 +164,8 @@
|
|||
:style="{ color: getChoiceValueIcon(col, row[col.field]).color }"
|
||||
:type="getChoiceValueIcon(col, row[col.field]).name"
|
||||
/>
|
||||
{{ row[col.field] }}</span
|
||||
>
|
||||
{{ getChoiceValueLabel(col, row[col.field]) || row[col.field] }}
|
||||
</span>
|
||||
</template>
|
||||
</template>
|
||||
</vxe-column>
|
||||
|
@ -582,6 +584,13 @@ export default {
|
|||
}
|
||||
return {}
|
||||
},
|
||||
getChoiceValueLabel(col, colValue) {
|
||||
const _find = col?.filters?.find((item) => String(item[0]) === String(colValue))
|
||||
if (_find) {
|
||||
return _find[1]?.label || ''
|
||||
}
|
||||
return ''
|
||||
},
|
||||
handleExport() {
|
||||
this.$refs.batchDownload.open({
|
||||
preferenceAttrList: [
|
||||
|
@ -611,6 +620,7 @@ export default {
|
|||
return { ...item }
|
||||
}),
|
||||
],
|
||||
original: true,
|
||||
download: false,
|
||||
})
|
||||
this.selectedRowKeys = []
|
||||
|
|
|
@ -1185,7 +1185,23 @@ export default {
|
|||
if (!res.result.length) {
|
||||
this.handleNullNodeTips(this.$t('cmdb.topo.noInstancePerm'))
|
||||
} else {
|
||||
this.currentNodeValues = res.result[0]
|
||||
const currentNodeValues = res.result[0]
|
||||
Object.keys(currentNodeValues).forEach((key) => {
|
||||
const attr = this.currentNodeAttributes.find((attr) => attr.name === key)
|
||||
if (attr?.choice_value?.length) {
|
||||
if (Array.isArray(currentNodeValues[key])) {
|
||||
currentNodeValues[key] = currentNodeValues[key].map((value) => {
|
||||
const choice = attr.choice_value.find((choice) => value === choice?.[0])
|
||||
return choice?.[1]?.label || value
|
||||
})
|
||||
} else {
|
||||
const choice = attr.choice_value.find((choice) => currentNodeValues[key] === choice?.[0])
|
||||
currentNodeValues[key] = choice?.[1]?.label || currentNodeValues[key]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.currentNodeValues = currentNodeValues
|
||||
}
|
||||
}).catch(error => {
|
||||
this.handleNullNodeTips(((error.response || {}).data || {}).message)
|
||||
|
|
|
@ -375,10 +375,9 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async getAttributeList() {
|
||||
await getCITypeAttributesById(Number(this.typeId)).then((res) => {
|
||||
this.attrList = res.attributes
|
||||
this.attributes = res
|
||||
})
|
||||
const res = await getCITypeAttributesById(Number(this.typeId))
|
||||
this.attrList = res.attributes
|
||||
this.attributes = res
|
||||
},
|
||||
async getTreeViews() {
|
||||
this.subscribeTreeViewCiTypesLoading = true
|
||||
|
@ -519,10 +518,18 @@ export default {
|
|||
|
||||
wrapTreeData(facet) {
|
||||
// 切面
|
||||
console.log('facet', facet)
|
||||
const _treeData = Object.values(facet)[0].map((item) => {
|
||||
let title = item[0]
|
||||
const attr = this.attrList.find((attr) => attr.name === item[2])
|
||||
if (attr?.choice_value?.length) {
|
||||
const choice = attr.choice_value.find((choice) => item[0] === choice?.[0])
|
||||
if (choice?.[1]?.label) {
|
||||
title = choice[1].label
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
title: item[0],
|
||||
title: title,
|
||||
childLength: item[1],
|
||||
key: this.treeKeys.join(this.keySplit) + this.keySplit + item[0],
|
||||
isLeaf: this.levels.length - 1 === this.treeKeys.length,
|
||||
|
|
Loading…
Reference in New Issue