mirror of https://github.com/veops/cmdb.git
feat: dynamic attribute (#534)
This commit is contained in:
parent
1a774490ac
commit
fa737e75c3
|
@ -383,12 +383,12 @@ class CIManager(object):
|
|||
computed_attrs.append(attr.to_dict())
|
||||
elif attr.is_password:
|
||||
if attr.name in ci_dict:
|
||||
password_dict[attr.id] = ci_dict.pop(attr.name)
|
||||
password_dict[attr.id] = (ci_dict.pop(attr.name), attr.is_dynamic)
|
||||
elif attr.alias in ci_dict:
|
||||
password_dict[attr.id] = ci_dict.pop(attr.alias)
|
||||
password_dict[attr.id] = (ci_dict.pop(attr.alias), attr.is_dynamic)
|
||||
|
||||
if attr.re_check and password_dict.get(attr.id):
|
||||
value_manager.check_re(attr.re_check, password_dict[attr.id])
|
||||
value_manager.check_re(attr.re_check, password_dict[attr.id][0])
|
||||
|
||||
if computed_attrs:
|
||||
value_manager.handle_ci_compute_attributes(ci_dict, computed_attrs, ci)
|
||||
|
@ -421,7 +421,8 @@ class CIManager(object):
|
|||
operate_type = OperateType.UPDATE if ci is not None else OperateType.ADD
|
||||
try:
|
||||
ci = ci or CI.create(type_id=ci_type.id, is_auto_discovery=is_auto_discovery)
|
||||
record_id = value_manager.create_or_update_attr_value(ci, ci_dict, key2attr, ticket_id=ticket_id)
|
||||
record_id, has_dynamic = value_manager.create_or_update_attr_value(
|
||||
ci, ci_dict, key2attr, ticket_id=ticket_id)
|
||||
except BadRequest as e:
|
||||
if existed is None:
|
||||
cls.delete(ci.id)
|
||||
|
@ -431,7 +432,7 @@ class CIManager(object):
|
|||
for attr_id in password_dict:
|
||||
record_id = cls.save_password(ci.id, attr_id, password_dict[attr_id], record_id, ci_type.id)
|
||||
|
||||
if record_id: # has change
|
||||
if record_id or has_dynamic: # has change
|
||||
ci_cache.apply_async(args=(ci.id, operate_type, record_id), queue=CMDB_QUEUE)
|
||||
|
||||
if ref_ci_dict: # add relations
|
||||
|
@ -440,7 +441,6 @@ class CIManager(object):
|
|||
return ci.id
|
||||
|
||||
def update(self, ci_id, _is_admin=False, ticket_id=None, __sync=False, **ci_dict):
|
||||
current_app.logger.info((ci_id, ci_dict, __sync))
|
||||
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
ci = self.confirm_ci_existed(ci_id)
|
||||
|
||||
|
@ -465,12 +465,12 @@ class CIManager(object):
|
|||
computed_attrs.append(attr.to_dict())
|
||||
elif attr.is_password:
|
||||
if attr.name in ci_dict:
|
||||
password_dict[attr.id] = ci_dict.pop(attr.name)
|
||||
password_dict[attr.id] = (ci_dict.pop(attr.name), attr.is_dynamic)
|
||||
elif attr.alias in ci_dict:
|
||||
password_dict[attr.id] = ci_dict.pop(attr.alias)
|
||||
password_dict[attr.id] = (ci_dict.pop(attr.alias), attr.is_dynamic)
|
||||
|
||||
if attr.re_check and password_dict.get(attr.id):
|
||||
value_manager.check_re(attr.re_check, password_dict[attr.id])
|
||||
value_manager.check_re(attr.re_check, password_dict[attr.id][0])
|
||||
|
||||
if computed_attrs:
|
||||
value_manager.handle_ci_compute_attributes(ci_dict, computed_attrs, ci)
|
||||
|
@ -495,7 +495,8 @@ class CIManager(object):
|
|||
ci_dict.pop(k)
|
||||
|
||||
try:
|
||||
record_id = value_manager.create_or_update_attr_value(ci, ci_dict, key2attr, ticket_id=ticket_id)
|
||||
record_id, has_dynamic = value_manager.create_or_update_attr_value(
|
||||
ci, ci_dict, key2attr, ticket_id=ticket_id)
|
||||
except BadRequest as e:
|
||||
raise e
|
||||
|
||||
|
@ -503,25 +504,25 @@ class CIManager(object):
|
|||
for attr_id in password_dict:
|
||||
record_id = self.save_password(ci.id, attr_id, password_dict[attr_id], record_id, ci.type_id)
|
||||
|
||||
if record_id: # has change
|
||||
if record_id or has_dynamic: # has change
|
||||
if not __sync:
|
||||
ci_cache.apply_async(args=(ci_id, OperateType.UPDATE, record_id), queue=CMDB_QUEUE)
|
||||
else:
|
||||
ci_cache((ci_id, OperateType.UPDATE, record_id))
|
||||
ci_cache(ci_id, OperateType.UPDATE, record_id)
|
||||
|
||||
ref_ci_dict = {k: v for k, v in ci_dict.items() if k.startswith("$") and "." in k}
|
||||
if ref_ci_dict:
|
||||
if not __sync:
|
||||
ci_relation_add.apply_async(args=(ref_ci_dict, ci.id), queue=CMDB_QUEUE)
|
||||
else:
|
||||
ci_relation_add((ref_ci_dict, ci.id))
|
||||
ci_relation_add(ref_ci_dict, ci.id)
|
||||
|
||||
@staticmethod
|
||||
def update_unique_value(ci_id, unique_name, unique_value):
|
||||
ci = CI.get_by_id(ci_id) or abort(404, ErrFormat.ci_not_found.format("id={}".format(ci_id)))
|
||||
|
||||
key2attr = {unique_name: AttributeCache.get(unique_name)}
|
||||
record_id = AttributeValueManager().create_or_update_attr_value(ci, {unique_name: unique_value}, key2attr)
|
||||
record_id, _ = AttributeValueManager().create_or_update_attr_value(ci, {unique_name: unique_value}, key2attr)
|
||||
|
||||
ci_cache.apply_async(args=(ci_id, OperateType.UPDATE, record_id), queue=CMDB_QUEUE)
|
||||
|
||||
|
@ -761,6 +762,7 @@ class CIManager(object):
|
|||
|
||||
@classmethod
|
||||
def save_password(cls, ci_id, attr_id, value, record_id, type_id):
|
||||
value, is_dynamic = value
|
||||
changed = None
|
||||
encrypt_value = None
|
||||
value_table = ValueTypeMap.table[ValueTypeEnum.PASSWORD]
|
||||
|
@ -777,14 +779,18 @@ class CIManager(object):
|
|||
if existed is None:
|
||||
if value:
|
||||
value_table.create(ci_id=ci_id, attr_id=attr_id, value=encrypt_value)
|
||||
changed = [(ci_id, attr_id, OperateType.ADD, '', PASSWORD_DEFAULT_SHOW, type_id)]
|
||||
if not is_dynamic:
|
||||
changed = [(ci_id, attr_id, OperateType.ADD, '', PASSWORD_DEFAULT_SHOW, type_id)]
|
||||
elif existed.value != encrypt_value:
|
||||
if value:
|
||||
existed.update(ci_id=ci_id, attr_id=attr_id, value=encrypt_value)
|
||||
changed = [(ci_id, attr_id, OperateType.UPDATE, PASSWORD_DEFAULT_SHOW, PASSWORD_DEFAULT_SHOW, type_id)]
|
||||
if not is_dynamic:
|
||||
changed = [(ci_id, attr_id, OperateType.UPDATE, PASSWORD_DEFAULT_SHOW,
|
||||
PASSWORD_DEFAULT_SHOW, type_id)]
|
||||
else:
|
||||
existed.delete()
|
||||
changed = [(ci_id, attr_id, OperateType.DELETE, PASSWORD_DEFAULT_SHOW, '', type_id)]
|
||||
if not is_dynamic:
|
||||
changed = [(ci_id, attr_id, OperateType.DELETE, PASSWORD_DEFAULT_SHOW, '', type_id)]
|
||||
|
||||
if current_app.config.get('SECRETS_ENGINE') == 'vault':
|
||||
vault = VaultClient(current_app.config.get('VAULT_URL'), current_app.config.get('VAULT_TOKEN'))
|
||||
|
|
|
@ -856,7 +856,9 @@ class CITypeRelationManager(object):
|
|||
if ci_type is None:
|
||||
return nodes, edges
|
||||
|
||||
nodes.append(ci_type.to_dict())
|
||||
ci_type_dict = ci_type.to_dict()
|
||||
ci_type_dict.setdefault('level', [0])
|
||||
nodes.append(ci_type_dict)
|
||||
node_ids.add(ci_type.id)
|
||||
|
||||
def _find(_id, lv):
|
||||
|
|
|
@ -172,6 +172,7 @@ class TopologyViewManager(object):
|
|||
_type = CITypeCache.get(central_node_type)
|
||||
if not _type:
|
||||
return dict(nodes=nodes, links=links)
|
||||
type2meta = {_type.id: _type.icon}
|
||||
root_ids = []
|
||||
show_key = AttributeCache.get(_type.show_id or _type.unique_id)
|
||||
|
||||
|
@ -192,7 +193,6 @@ class TopologyViewManager(object):
|
|||
prefix = REDIS_PREFIX_CI_RELATION
|
||||
key = list(map(str, root_ids))
|
||||
id2node = {}
|
||||
type2meta = {}
|
||||
for level in sorted([i for i in path.keys() if int(i) > 0]):
|
||||
type_ids = {int(i) for i in path[level]}
|
||||
|
||||
|
|
|
@ -253,6 +253,9 @@ def is_app_admin(app=None):
|
|||
if app is None:
|
||||
return False
|
||||
|
||||
if hasattr(current_user, 'username') and current_user.username == 'worker':
|
||||
return True
|
||||
|
||||
app_id = app.id
|
||||
if 'acl_admin' in session.get("acl", {}).get("parentRoles", []):
|
||||
return True
|
||||
|
|
|
@ -79,7 +79,8 @@ class PermissionCRUD(object):
|
|||
return r and cls.get_all(r.id)
|
||||
|
||||
@staticmethod
|
||||
def grant(rid, perms, resource_id=None, group_id=None, rebuild=True, source=AuditOperateSource.acl):
|
||||
def grant(rid, perms, resource_id=None, group_id=None, rebuild=True,
|
||||
source=AuditOperateSource.acl, force_update=False):
|
||||
app_id = None
|
||||
rt_id = None
|
||||
|
||||
|
@ -106,8 +107,23 @@ class PermissionCRUD(object):
|
|||
if not perms:
|
||||
perms = [i.get('name') for i in ResourceTypeCRUD.get_perms(group.resource_type_id)]
|
||||
|
||||
_role_permissions = []
|
||||
if force_update:
|
||||
revoke_role_permissions = []
|
||||
existed_perms = RolePermission.get_by(rid=rid,
|
||||
app_id=app_id,
|
||||
group_id=group_id,
|
||||
resource_id=resource_id,
|
||||
to_dict=False)
|
||||
for role_perm in existed_perms:
|
||||
perm = PermissionCache.get(role_perm.perm_id, rt_id)
|
||||
if perm and perm.name not in perms:
|
||||
role_perm.soft_delete()
|
||||
revoke_role_permissions.append(role_perm)
|
||||
|
||||
AuditCRUD.add_permission_log(app_id, AuditOperateType.revoke, rid, rt_id,
|
||||
revoke_role_permissions, source=source)
|
||||
|
||||
_role_permissions = []
|
||||
for _perm in set(perms):
|
||||
perm = PermissionCache.get(_perm, rt_id)
|
||||
if not perm:
|
||||
|
|
|
@ -51,12 +51,12 @@ def _auth_with_key():
|
|||
user, authenticated = User.query.authenticate_with_key(key, secret, req_args, path)
|
||||
if user and authenticated:
|
||||
login_user(user)
|
||||
reset_session(user)
|
||||
# reset_session(user)
|
||||
return True
|
||||
|
||||
role, authenticated = Role.query.authenticate_with_key(key, secret, req_args, path)
|
||||
if role and authenticated:
|
||||
reset_session(None, role=role.name)
|
||||
# reset_session(None, role=role.name)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
|
@ -104,6 +104,7 @@ class Attribute(Model):
|
|||
is_link = db.Column(db.Boolean, default=False)
|
||||
is_password = db.Column(db.Boolean, default=False)
|
||||
is_sortable = db.Column(db.Boolean, default=False)
|
||||
is_dynamic = db.Column(db.Boolean, default=False)
|
||||
|
||||
default = db.Column(db.JSON) # {"default": None}
|
||||
|
||||
|
|
|
@ -200,7 +200,9 @@ const cmdb_en = {
|
|||
show: 'show attribute',
|
||||
setAsShow: 'Set as show attribute',
|
||||
cancelSetAsShow: 'Cancel show attribute',
|
||||
showTips: 'The names of nodes in the service tree and topology view'
|
||||
showTips: 'The names of nodes in the service tree and topology view',
|
||||
isDynamic: 'Dynamic',
|
||||
dynamicTips: 'For example, for monitoring data and frequently updated data, it is recommended to set it as a dynamic attribute, so that the change history of the attribute will not be recorded.',
|
||||
},
|
||||
components: {
|
||||
unselectAttributes: 'Unselected',
|
||||
|
@ -538,7 +540,7 @@ if __name__ == "__main__":
|
|||
rollbackSuccess: 'Rollback successfully',
|
||||
rollbackingTips: 'Rollbacking',
|
||||
batchRollbacking: 'Deleting {total} items in total, {successNum} items successful, {errorNum} items failed',
|
||||
baselineTips: 'Changes at this point in time will also be rollbacked, Unique ID and password attributes do not support',
|
||||
baselineTips: 'Changes at this point in time will also be rollbacked, Unique ID, password and dynamic attributes do not support',
|
||||
},
|
||||
serviceTree: {
|
||||
remove: 'Remove',
|
||||
|
|
|
@ -78,7 +78,7 @@ const cmdb_zh = {
|
|||
password: '密码',
|
||||
link: '链接',
|
||||
list: '多值',
|
||||
listTips: '字段的值是1个或者多个,接口返回的值的类型是list',
|
||||
listTips: '属性的值是1个或者多个,接口返回的值的类型是list',
|
||||
computeForAllCITips: '所有CI触发计算',
|
||||
confirmcomputeForAllCITips: '确认触发所有CI的计算?',
|
||||
isUnique: '是否唯一',
|
||||
|
@ -89,7 +89,7 @@ const cmdb_zh = {
|
|||
isSortable: '可排序',
|
||||
isIndex: '是否索引',
|
||||
index: '索引',
|
||||
indexTips: '字段可被用于检索,加速查询',
|
||||
indexTips: '属性可被用于全文检索,加速查询',
|
||||
confirmDelete: '确认删除【{name}】?',
|
||||
confirmDelete2: '确认删除?',
|
||||
computeSuccess: '触发成功!',
|
||||
|
@ -200,7 +200,9 @@ const cmdb_zh = {
|
|||
show: '展示属性',
|
||||
setAsShow: '设置为展示属性',
|
||||
cancelSetAsShow: '取消设置为展示属性',
|
||||
showTips: '服务树和拓扑视图里节点的名称'
|
||||
showTips: '服务树和拓扑视图里节点的名称',
|
||||
isDynamic: '动态属性',
|
||||
dynamicTips: '譬如监控类的数据, 频繁更新的数据, 建议设置为动态属性, 则不会记录该属性的变更历史',
|
||||
},
|
||||
components: {
|
||||
unselectAttributes: '未选属性',
|
||||
|
@ -538,7 +540,7 @@ if __name__ == "__main__":
|
|||
rollbackSuccess: '回滚成功',
|
||||
rollbackingTips: '正在批量回滚中',
|
||||
batchRollbacking: '正在回滚,共{total}个,成功{successNum}个,失败{errorNum}个',
|
||||
baselineTips: '该时间点的变更也会被回滚, 唯一标识、密码属性不支持回滚',
|
||||
baselineTips: '该时间点的变更也会被回滚, 唯一标识、密码属性、动态属性不支持回滚',
|
||||
},
|
||||
serviceTree: {
|
||||
remove: '移除',
|
||||
|
|
|
@ -163,6 +163,12 @@ export default {
|
|||
width: 110,
|
||||
help: this.$t('cmdb.ci.tips10'),
|
||||
},
|
||||
{
|
||||
field: 'is_dynamic',
|
||||
title: this.$t('cmdb.ciType.isDynamic'),
|
||||
width: 110,
|
||||
help: this.$t('cmdb.ciType.dynamicTips'),
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
|
|
|
@ -180,6 +180,10 @@ export default {
|
|||
label: this.$t('cmdb.ciType.isIndex'),
|
||||
property: 'is_index',
|
||||
},
|
||||
{
|
||||
label: this.$t('cmdb.ciType.isDynamic'),
|
||||
property: 'is_dynamic',
|
||||
},
|
||||
]
|
||||
},
|
||||
inherited() {
|
||||
|
|
|
@ -157,33 +157,6 @@
|
|||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="6">
|
||||
<a-form-item
|
||||
:label-col="horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
:label="$t('required')"
|
||||
>
|
||||
<a-switch
|
||||
@change="(checked) => onChange(checked, 'is_required')"
|
||||
name="is_required"
|
||||
v-decorator="['is_required', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6" v-if="currentValueType !== '6' && currentValueType !== '7'">
|
||||
<a-form-item
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
:label="$t('cmdb.ciType.unique')"
|
||||
>
|
||||
<a-switch
|
||||
:disabled="isShowComputedArea"
|
||||
@change="onChange"
|
||||
name="is_unique"
|
||||
v-decorator="['is_unique', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="currentValueType === '2' ? 6 : 0" v-if="currentValueType !== '6'">
|
||||
<a-form-item
|
||||
:hidden="currentValueType === '2' ? false : true"
|
||||
|
@ -196,7 +169,7 @@
|
|||
>{{ $t('cmdb.ciType.index') }}
|
||||
<a-tooltip :title="$t('cmdb.ciType.indexTips')">
|
||||
<a-icon
|
||||
style="position:absolute;top:3px;left:-17px;color:#2f54eb;"
|
||||
style="position:absolute;top:2px;left:-17px;color:#2f54eb;"
|
||||
type="question-circle"
|
||||
theme="filled"
|
||||
@click="
|
||||
|
@ -217,10 +190,37 @@
|
|||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-col :span="6" v-if="currentValueType !== '6' && currentValueType !== '7'">
|
||||
<a-form-item
|
||||
:label-col="currentValueType === '2' ? { span: 8 } : horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
:label="$t('cmdb.ciType.unique')"
|
||||
>
|
||||
<a-switch
|
||||
:disabled="isShowComputedArea"
|
||||
@change="onChange"
|
||||
name="is_unique"
|
||||
v-decorator="['is_unique', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item
|
||||
:label-col="['2', '6', '7'].findIndex(i => currentValueType === i) === -1 ? { span: 8 } : horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
:label="$t('required')"
|
||||
>
|
||||
<a-switch
|
||||
@change="(checked) => onChange(checked, 'is_required')"
|
||||
name="is_required"
|
||||
v-decorator="['is_required', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item
|
||||
:label-col="currentValueType === '2' ? { span: 12 } : horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
>
|
||||
<template slot="label">
|
||||
<span
|
||||
|
@ -228,7 +228,7 @@
|
|||
>{{ $t('cmdb.ciType.defaultShow') }}
|
||||
<a-tooltip :title="$t('cmdb.ciType.defaultShowTips')">
|
||||
<a-icon
|
||||
style="position:absolute;top:3px;left:-17px;color:#2f54eb;"
|
||||
style="position:absolute;top:2px;left:-17px;color:#2f54eb;"
|
||||
type="question-circle"
|
||||
theme="filled"
|
||||
@click="
|
||||
|
@ -295,6 +295,37 @@
|
|||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col span="6">
|
||||
<a-form-item
|
||||
:label-col="['2', '6', '7'].findIndex(i => currentValueType === i) === -1 ? { span: 12 } : horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
>
|
||||
<template slot="label">
|
||||
<span
|
||||
style="position:relative;white-space:pre;"
|
||||
>{{ $t('cmdb.ciType.isDynamic') }}
|
||||
<a-tooltip :title="$t('cmdb.ciType.dynamicTips')">
|
||||
<a-icon
|
||||
style="position:absolute;top:3px;left:-17px;color:#2f54eb;"
|
||||
type="question-circle"
|
||||
theme="filled"
|
||||
@click="
|
||||
(e) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<a-switch
|
||||
@change="(checked) => onChange(checked, 'is_dynamic')"
|
||||
name="is_dynamic"
|
||||
v-decorator="['is_dynamic', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-divider style="font-size:14px;margin-top:6px;">{{ $t('cmdb.ciType.advancedSettings') }}</a-divider>
|
||||
<a-row>
|
||||
<a-col :span="24" v-if="!['6'].includes(currentValueType)">
|
||||
|
@ -534,6 +565,7 @@ export default {
|
|||
is_index: _record.is_index,
|
||||
is_sortable: _record.is_sortable,
|
||||
is_computed: _record.is_computed,
|
||||
is_dynamic: _record.is_dynamic,
|
||||
})
|
||||
}
|
||||
console.log(_record)
|
||||
|
|
|
@ -150,42 +150,19 @@
|
|||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-col :span="6">
|
||||
<a-col :span="currentValueType === '2' ? 6 : 0" v-if="currentValueType !== '6'">
|
||||
<a-form-item
|
||||
:hidden="currentValueType === '2' ? false : true"
|
||||
:label-col="horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
:label="$t('required')"
|
||||
>
|
||||
<a-switch
|
||||
@change="(checked) => onChange(checked, 'is_required')"
|
||||
name="is_required"
|
||||
v-decorator="['is_required', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6" v-if="currentValueType !== '6' && currentValueType !== '7'">
|
||||
<a-form-item
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
:label="$t('cmdb.ciType.unique')"
|
||||
>
|
||||
<a-switch
|
||||
:disabled="isShowComputedArea"
|
||||
@change="onChange"
|
||||
name="is_unique"
|
||||
v-decorator="['is_unique', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6" v-if="currentValueType === '2'">
|
||||
<a-form-item :label-col="horizontalFormItemLayout.labelCol" :wrapper-col="horizontalFormItemLayout.wrapperCol">
|
||||
<template slot="label">
|
||||
<span
|
||||
style="position:relative;white-space:pre;"
|
||||
>{{ $t('cmdb.ciType.index') }}
|
||||
<a-tooltip :title="$t('cmdb.ciType.indexTips')">
|
||||
<a-icon
|
||||
style="position:absolute;top:3px;left:-17px;color:#2f54eb;"
|
||||
style="position:absolute;top:2px;left:-17px;color:#2f54eb;"
|
||||
type="question-circle"
|
||||
theme="filled"
|
||||
@click="
|
||||
|
@ -206,10 +183,37 @@
|
|||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-col :span="6" v-if="currentValueType !== '6' && currentValueType !== '7'">
|
||||
<a-form-item
|
||||
:label-col="currentValueType === '2' ? { span: 8 } : horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
:label="$t('cmdb.ciType.unique')"
|
||||
>
|
||||
<a-switch
|
||||
:disabled="isShowComputedArea"
|
||||
@change="onChange"
|
||||
name="is_unique"
|
||||
v-decorator="['is_unique', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item
|
||||
:label-col="['2', '6', '7'].findIndex(i => currentValueType === i) === -1 ? { span: 8 } : horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
:label="$t('required')"
|
||||
>
|
||||
<a-switch
|
||||
@change="(checked) => onChange(checked, 'is_required')"
|
||||
name="is_required"
|
||||
v-decorator="['is_required', { rules: [], valuePropName: 'checked' }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-item
|
||||
:label-col="currentValueType === '2' ? { span: 12 } : horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
>
|
||||
<template slot="label">
|
||||
<span
|
||||
|
@ -217,7 +221,7 @@
|
|||
>{{ $t('cmdb.ciType.defaultShow') }}
|
||||
<a-tooltip :title="$t('cmdb.ciType.defaultShowTips')">
|
||||
<a-icon
|
||||
style="position:absolute;top:3px;left:-17px;color:#2f54eb;"
|
||||
style="position:absolute;top:2px;left:-17px;color:#2f54eb;"
|
||||
type="question-circle"
|
||||
theme="filled"
|
||||
@click="
|
||||
|
@ -284,6 +288,37 @@
|
|||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col span="6">
|
||||
<a-form-item
|
||||
:label-col="['2', '6', '7'].findIndex(i => currentValueType === i) === -1 ? { span: 12 } : horizontalFormItemLayout.labelCol"
|
||||
:wrapper-col="horizontalFormItemLayout.wrapperCol"
|
||||
>
|
||||
<template slot="label">
|
||||
<span
|
||||
style="position:relative;white-space:pre;"
|
||||
>{{ $t('cmdb.ciType.isDynamic') }}
|
||||
<a-tooltip :title="$t('cmdb.ciType.dynamicTips')">
|
||||
<a-icon
|
||||
style="position:absolute;top:3px;left:-17px;color:#2f54eb;"
|
||||
type="question-circle"
|
||||
theme="filled"
|
||||
@click="
|
||||
(e) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</template>
|
||||
<a-switch
|
||||
@change="(checked) => onChange(checked, 'is_dynamic')"
|
||||
name="is_dynamic"
|
||||
v-decorator="['is_dynamic', { rules: [], valuePropName: 'checked', initialValue: currentValueType === '6' ? true: false }]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-divider style="font-size:14px;margin-top:6px;">{{ $t('cmdb.ciType.advancedSettings') }}</a-divider>
|
||||
<a-row>
|
||||
<a-col :span="24" v-if="!['6'].includes(currentValueType)">
|
||||
|
@ -404,8 +439,8 @@ export default {
|
|||
}
|
||||
|
||||
console.log(values)
|
||||
const { is_required, default_show, default_value } = values
|
||||
const data = { is_required, default_show }
|
||||
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 === '0' && default_value) {
|
||||
|
|
|
@ -7,15 +7,15 @@
|
|||
<a-tab-pane key="2" :tab="$t('cmdb.ciType.relation')">
|
||||
<RelationTable :CITypeId="CITypeId" :CITypeName="CITypeName"></RelationTable>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="3" :tab="$t('cmdb.ciType.trigger')">
|
||||
<TriggerTable ref="triggerTable" :CITypeId="CITypeId"></TriggerTable>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="4" :tab="$t('cmdb.ciType.attributeAD')">
|
||||
<a-tab-pane key="3" :tab="$t('cmdb.ciType.attributeAD')">
|
||||
<AttrAD :CITypeId="CITypeId"></AttrAD>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="5" :tab="$t('cmdb.ciType.relationAD')">
|
||||
<a-tab-pane key="4" :tab="$t('cmdb.ciType.relationAD')">
|
||||
<RelationAD :CITypeId="CITypeId"></RelationAD>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="5" :tab="$t('cmdb.ciType.trigger')">
|
||||
<TriggerTable ref="triggerTable" :CITypeId="CITypeId"></TriggerTable>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="6" :tab="$t('cmdb.ciType.grant')">
|
||||
<GrantComp :CITypeId="CITypeId" resourceType="CIType" :resourceTypeName="CITypeName"></GrantComp>
|
||||
<div class="citype-detail-title">{{ $t('cmdb.components.relationGrant') }}</div>
|
||||
|
@ -67,7 +67,7 @@ export default {
|
|||
if (activeKey === '1') {
|
||||
this.$refs.attributesTable.getCITypeGroupData()
|
||||
}
|
||||
if (activeKey === '3') {
|
||||
if (activeKey === '5') {
|
||||
this.$refs.triggerTable.getTableData()
|
||||
}
|
||||
})
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
show-search
|
||||
>
|
||||
<a-select-option
|
||||
v-for="attr in commonAttributes.filter((attr) => !attr.is_password)"
|
||||
v-for="attr in commonAttributes.filter((attr) => !attr.is_password && attr.value_type !== '6')"
|
||||
:key="attr.id"
|
||||
:value="attr.id"
|
||||
>{{ attr.alias || attr.name }}</a-select-option
|
||||
|
|
Loading…
Reference in New Issue