mirror of https://github.com/veops/cmdb.git
Merge pull request #663 from veops/dev_ui_241224
feat(ui): update style
This commit is contained in:
commit
b669775cd6
|
@ -106,7 +106,7 @@
|
|||
<CIReferenceAttr
|
||||
v-if="getAttr(item.property).is_reference && (item.exp === 'is' || item.exp === '~is')"
|
||||
:style="{ width: '175px' }"
|
||||
class="select-filter-component"
|
||||
class="select-filter-component ops-select-bg"
|
||||
:referenceTypeId="getAttr(item.property).reference_type_id"
|
||||
:disabled="disabled"
|
||||
v-model="item.value"
|
||||
|
@ -114,7 +114,7 @@
|
|||
<a-select
|
||||
v-else-if="getAttr(item.property).is_bool && (item.exp === 'is' || item.exp === '~is')"
|
||||
v-model="item.value"
|
||||
class="select-filter-component"
|
||||
class="select-filter-component ops-select-bg"
|
||||
:style="{ width: '175px' }"
|
||||
:disabled="disabled"
|
||||
:placeholder="$t('placeholder2')"
|
||||
|
@ -398,7 +398,6 @@ export default {
|
|||
|
||||
/deep/ .ant-select-selection {
|
||||
height: 24px;
|
||||
background: #f7f8fa;
|
||||
line-height: 24px;
|
||||
border: none;
|
||||
|
||||
|
|
|
@ -1,302 +1,302 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-popover
|
||||
v-if="isDropdown"
|
||||
v-model="visible"
|
||||
trigger="click"
|
||||
:placement="placement"
|
||||
overlayClassName="table-filter"
|
||||
@visibleChange="visibleChange"
|
||||
>
|
||||
<slot name="popover_item">
|
||||
<a-button type="primary" ghost>{{ $t('cmdbFilterComp.conditionFilter') }}<a-icon type="filter"/></a-button>
|
||||
</slot>
|
||||
<template slot="content">
|
||||
<Expression
|
||||
:needAddHere="needAddHere"
|
||||
v-model="ruleList"
|
||||
:canSearchPreferenceAttrList="canSearchPreferenceAttrList.filter((attr) => !attr.is_password)"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
<a-divider :style="{ margin: '10px 0' }" />
|
||||
<div style="width:554px">
|
||||
<a-space :style="{ display: 'flex', justifyContent: 'flex-end' }">
|
||||
<a-button type="primary" size="small" @click="handleSubmit">{{ $t('confirm') }}</a-button>
|
||||
<a-button size="small" @click="handleClear">{{ $t('clear') }}</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
<Expression
|
||||
:needAddHere="needAddHere"
|
||||
v-else
|
||||
v-model="ruleList"
|
||||
:canSearchPreferenceAttrList="canSearchPreferenceAttrList.filter((attr) => !attr.is_password)"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import Expression from './expression.vue'
|
||||
import { advancedExpList, compareTypeList } from './constants'
|
||||
|
||||
export default {
|
||||
name: 'FilterComp',
|
||||
components: { Expression },
|
||||
props: {
|
||||
canSearchPreferenceAttrList: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [],
|
||||
},
|
||||
expression: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
regQ: {
|
||||
type: String,
|
||||
default: '(?<=q=).+(?=&)|(?<=q=).+$',
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'bottomRight',
|
||||
},
|
||||
isDropdown: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
needAddHere: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
advancedExpList,
|
||||
compareTypeList,
|
||||
visible: false,
|
||||
ruleList: [],
|
||||
filterExp: '',
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
visibleChange(open, isInitOne = true) {
|
||||
// isInitOne 初始化exp为空时,ruleList是否默认给一条
|
||||
// const regQ = /(?<=q=).+(?=&)|(?<=q=).+$/g
|
||||
const exp = this.expression.match(new RegExp(this.regQ, 'g'))
|
||||
? this.expression.match(new RegExp(this.regQ, 'g'))[0]
|
||||
: null
|
||||
if (open && exp) {
|
||||
const expArray = exp.split(',').map((item) => {
|
||||
let has_not = ''
|
||||
const key = item.split(':')[0]
|
||||
const val = item
|
||||
.split(':')
|
||||
.slice(1)
|
||||
.join(':')
|
||||
let type, property, exp, value, min, max, compareType
|
||||
if (key.includes('-')) {
|
||||
type = 'or'
|
||||
if (key.includes('~')) {
|
||||
property = key.substring(2)
|
||||
has_not = '~'
|
||||
} else {
|
||||
property = key.substring(1)
|
||||
}
|
||||
} else {
|
||||
type = 'and'
|
||||
if (key.includes('~')) {
|
||||
property = key.substring(1)
|
||||
has_not = '~'
|
||||
} else {
|
||||
property = key
|
||||
}
|
||||
}
|
||||
|
||||
const in_reg = /(?<=\().+(?=\))/g
|
||||
const range_reg = /(?<=\[).+(?=\])/g
|
||||
const compare_reg = /(?<=>=|<=|>(?!=)|<(?!=)).+/
|
||||
if (val === '*') {
|
||||
exp = has_not + 'value'
|
||||
value = ''
|
||||
} else if (in_reg.test(val)) {
|
||||
exp = has_not + 'in'
|
||||
value = val.match(in_reg)[0]
|
||||
} else if (range_reg.test(val)) {
|
||||
exp = has_not + 'range'
|
||||
value = val.match(range_reg)[0]
|
||||
min = value.split('_TO_')[0]
|
||||
max = value.split('_TO_')[1]
|
||||
} else if (compare_reg.test(val)) {
|
||||
exp = has_not + 'compare'
|
||||
value = val.match(compare_reg)[0]
|
||||
const _compareType = val.substring(0, val.match(compare_reg)['index'])
|
||||
const idx = compareTypeList.findIndex((item) => item.label === _compareType)
|
||||
compareType = compareTypeList[idx].value
|
||||
} else if (!val.includes('*')) {
|
||||
exp = has_not + 'is'
|
||||
value = val
|
||||
} else {
|
||||
const resList = [
|
||||
['contain', /(?<=\*).*(?=\*)/g],
|
||||
['end_with', /(?<=\*).+/g],
|
||||
['start_with', /.+(?=\*)/g],
|
||||
]
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const reg = resList[i]
|
||||
if (reg[1].test(val)) {
|
||||
exp = has_not + reg[0]
|
||||
value = val.match(reg[1])[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
id: uuidv4(),
|
||||
type,
|
||||
property,
|
||||
exp,
|
||||
value,
|
||||
min,
|
||||
max,
|
||||
compareType,
|
||||
}
|
||||
})
|
||||
this.ruleList = [...expArray]
|
||||
} else if (open) {
|
||||
const _canSearchPreferenceAttrList = this.canSearchPreferenceAttrList.filter((attr) => !attr.is_password)
|
||||
this.ruleList = isInitOne
|
||||
? [
|
||||
{
|
||||
id: uuidv4(),
|
||||
type: 'and',
|
||||
property:
|
||||
_canSearchPreferenceAttrList && _canSearchPreferenceAttrList.length
|
||||
? _canSearchPreferenceAttrList[0].name
|
||||
: undefined,
|
||||
exp: 'is',
|
||||
value: null,
|
||||
},
|
||||
]
|
||||
: []
|
||||
}
|
||||
},
|
||||
handleClear() {
|
||||
this.ruleList = [
|
||||
{
|
||||
id: uuidv4(),
|
||||
type: 'and',
|
||||
property: this.canSearchPreferenceAttrList[0].name,
|
||||
exp: 'is',
|
||||
value: null,
|
||||
},
|
||||
]
|
||||
this.filterExp = ''
|
||||
this.visible = false
|
||||
this.$emit('setExpFromFilter', this.filterExp)
|
||||
},
|
||||
handleSubmit() {
|
||||
if (this.ruleList && this.ruleList.length) {
|
||||
this.ruleList[0].type = 'and' // 增删后,以防万一第一个不是and
|
||||
this.filterExp = ''
|
||||
const expList = this.ruleList.map((rule) => {
|
||||
let singleRuleExp = ''
|
||||
let _exp = rule.exp
|
||||
if (rule.type === 'or') {
|
||||
singleRuleExp += '-'
|
||||
}
|
||||
if (rule.exp.includes('~')) {
|
||||
singleRuleExp += '~'
|
||||
_exp = rule.exp.split('~')[1]
|
||||
}
|
||||
singleRuleExp += `${rule.property}:`
|
||||
if (_exp === 'is') {
|
||||
singleRuleExp += `${rule.value ?? ''}`
|
||||
}
|
||||
if (_exp === 'contain') {
|
||||
singleRuleExp += `*${rule.value ?? ''}*`
|
||||
}
|
||||
if (_exp === 'start_with') {
|
||||
singleRuleExp += `${rule.value ?? ''}*`
|
||||
}
|
||||
if (_exp === 'end_with') {
|
||||
singleRuleExp += `*${rule.value ?? ''}`
|
||||
}
|
||||
if (_exp === 'value') {
|
||||
singleRuleExp += `*`
|
||||
}
|
||||
if (_exp === 'in') {
|
||||
singleRuleExp += `(${rule.value ?? ''})`
|
||||
}
|
||||
if (_exp === 'range') {
|
||||
singleRuleExp += `[${rule.min}_TO_${rule.max}]`
|
||||
}
|
||||
if (_exp === 'compare') {
|
||||
const idx = compareTypeList.findIndex((item) => item.value === rule.compareType)
|
||||
singleRuleExp += `${compareTypeList[idx].label}${rule.value ?? ''}`
|
||||
}
|
||||
return singleRuleExp
|
||||
})
|
||||
this.filterExp = expList.join(',')
|
||||
this.$emit('setExpFromFilter', this.filterExp)
|
||||
} else {
|
||||
this.$emit('setExpFromFilter', '')
|
||||
}
|
||||
this.visible = false
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
.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>
|
||||
<template>
|
||||
<div>
|
||||
<a-popover
|
||||
v-if="isDropdown"
|
||||
v-model="visible"
|
||||
trigger="click"
|
||||
:placement="placement"
|
||||
overlayClassName="table-filter"
|
||||
@visibleChange="visibleChange"
|
||||
>
|
||||
<slot name="popover_item">
|
||||
<a-button type="primary" ghost>{{ $t('cmdbFilterComp.conditionFilter') }}<a-icon type="filter"/></a-button>
|
||||
</slot>
|
||||
<template slot="content">
|
||||
<Expression
|
||||
:needAddHere="needAddHere"
|
||||
v-model="ruleList"
|
||||
:canSearchPreferenceAttrList="canSearchPreferenceAttrList.filter((attr) => !attr.is_password)"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
<a-divider :style="{ margin: '10px 0' }" />
|
||||
<div style="width:554px">
|
||||
<a-space :style="{ display: 'flex', justifyContent: 'flex-end' }">
|
||||
<a-button type="primary" size="small" @click="handleSubmit">{{ $t('confirm') }}</a-button>
|
||||
<a-button size="small" @click="handleClear">{{ $t('clear') }}</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
<Expression
|
||||
:needAddHere="needAddHere"
|
||||
v-else
|
||||
v-model="ruleList"
|
||||
:canSearchPreferenceAttrList="canSearchPreferenceAttrList.filter((attr) => !attr.is_password)"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import Expression from './expression.vue'
|
||||
import { advancedExpList, compareTypeList } from './constants'
|
||||
|
||||
export default {
|
||||
name: 'FilterComp',
|
||||
components: { Expression },
|
||||
props: {
|
||||
canSearchPreferenceAttrList: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [],
|
||||
},
|
||||
expression: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
regQ: {
|
||||
type: String,
|
||||
default: '(?<=q=).+(?=&)|(?<=q=).+$',
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'bottomRight',
|
||||
},
|
||||
isDropdown: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
needAddHere: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
advancedExpList,
|
||||
compareTypeList,
|
||||
visible: false,
|
||||
ruleList: [],
|
||||
filterExp: '',
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
visibleChange(open, isInitOne = true) {
|
||||
// isInitOne 初始化exp为空时,ruleList是否默认给一条
|
||||
// const regQ = /(?<=q=).+(?=&)|(?<=q=).+$/g
|
||||
const exp = this.expression.match(new RegExp(this.regQ, 'g'))
|
||||
? this.expression.match(new RegExp(this.regQ, 'g'))[0]
|
||||
: null
|
||||
if (open && exp) {
|
||||
const expArray = exp.split(',').map((item) => {
|
||||
let has_not = ''
|
||||
const key = item.split(':')[0]
|
||||
const val = item
|
||||
.split(':')
|
||||
.slice(1)
|
||||
.join(':')
|
||||
let type, property, exp, value, min, max, compareType
|
||||
if (key.includes('-')) {
|
||||
type = 'or'
|
||||
if (key.includes('~')) {
|
||||
property = key.substring(2)
|
||||
has_not = '~'
|
||||
} else {
|
||||
property = key.substring(1)
|
||||
}
|
||||
} else {
|
||||
type = 'and'
|
||||
if (key.includes('~')) {
|
||||
property = key.substring(1)
|
||||
has_not = '~'
|
||||
} else {
|
||||
property = key
|
||||
}
|
||||
}
|
||||
|
||||
const in_reg = /(?<=\().+(?=\))/g
|
||||
const range_reg = /(?<=\[).+(?=\])/g
|
||||
const compare_reg = /(?<=>=|<=|>(?!=)|<(?!=)).+/
|
||||
if (val === '*') {
|
||||
exp = has_not + 'value'
|
||||
value = ''
|
||||
} else if (in_reg.test(val)) {
|
||||
exp = has_not + 'in'
|
||||
value = val.match(in_reg)[0]
|
||||
} else if (range_reg.test(val)) {
|
||||
exp = has_not + 'range'
|
||||
value = val.match(range_reg)[0]
|
||||
min = value.split('_TO_')[0]
|
||||
max = value.split('_TO_')[1]
|
||||
} else if (compare_reg.test(val)) {
|
||||
exp = has_not + 'compare'
|
||||
value = val.match(compare_reg)[0]
|
||||
const _compareType = val.substring(0, val.match(compare_reg)['index'])
|
||||
const idx = compareTypeList.findIndex((item) => item.label === _compareType)
|
||||
compareType = compareTypeList[idx].value
|
||||
} else if (!val.includes('*')) {
|
||||
exp = has_not + 'is'
|
||||
value = val
|
||||
} else {
|
||||
const resList = [
|
||||
['contain', /(?<=\*).*(?=\*)/g],
|
||||
['end_with', /(?<=\*).+/g],
|
||||
['start_with', /.+(?=\*)/g],
|
||||
]
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const reg = resList[i]
|
||||
if (reg[1].test(val)) {
|
||||
exp = has_not + reg[0]
|
||||
value = val.match(reg[1])[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
id: uuidv4(),
|
||||
type,
|
||||
property,
|
||||
exp,
|
||||
value,
|
||||
min,
|
||||
max,
|
||||
compareType,
|
||||
}
|
||||
})
|
||||
this.ruleList = [...expArray]
|
||||
} else if (open) {
|
||||
const _canSearchPreferenceAttrList = this.canSearchPreferenceAttrList.filter((attr) => !attr.is_password)
|
||||
this.ruleList = isInitOne
|
||||
? [
|
||||
{
|
||||
id: uuidv4(),
|
||||
type: 'and',
|
||||
property:
|
||||
_canSearchPreferenceAttrList && _canSearchPreferenceAttrList.length
|
||||
? _canSearchPreferenceAttrList[0].name
|
||||
: undefined,
|
||||
exp: 'is',
|
||||
value: null,
|
||||
},
|
||||
]
|
||||
: []
|
||||
}
|
||||
},
|
||||
handleClear() {
|
||||
this.ruleList = [
|
||||
{
|
||||
id: uuidv4(),
|
||||
type: 'and',
|
||||
property: this.canSearchPreferenceAttrList[0].name,
|
||||
exp: 'is',
|
||||
value: null,
|
||||
},
|
||||
]
|
||||
this.filterExp = ''
|
||||
this.visible = false
|
||||
this.$emit('setExpFromFilter', this.filterExp)
|
||||
},
|
||||
handleSubmit() {
|
||||
if (this.ruleList && this.ruleList.length) {
|
||||
this.ruleList[0].type = 'and' // 增删后,以防万一第一个不是and
|
||||
this.filterExp = ''
|
||||
const expList = this.ruleList.map((rule) => {
|
||||
let singleRuleExp = ''
|
||||
let _exp = rule.exp
|
||||
if (rule.type === 'or') {
|
||||
singleRuleExp += '-'
|
||||
}
|
||||
if (rule.exp.includes('~')) {
|
||||
singleRuleExp += '~'
|
||||
_exp = rule.exp.split('~')[1]
|
||||
}
|
||||
singleRuleExp += `${rule.property}:`
|
||||
if (_exp === 'is') {
|
||||
singleRuleExp += `${rule.value ?? ''}`
|
||||
}
|
||||
if (_exp === 'contain') {
|
||||
singleRuleExp += `*${rule.value ?? ''}*`
|
||||
}
|
||||
if (_exp === 'start_with') {
|
||||
singleRuleExp += `${rule.value ?? ''}*`
|
||||
}
|
||||
if (_exp === 'end_with') {
|
||||
singleRuleExp += `*${rule.value ?? ''}`
|
||||
}
|
||||
if (_exp === 'value') {
|
||||
singleRuleExp += `*`
|
||||
}
|
||||
if (_exp === 'in') {
|
||||
singleRuleExp += `(${rule.value ?? ''})`
|
||||
}
|
||||
if (_exp === 'range') {
|
||||
singleRuleExp += `[${rule.min}_TO_${rule.max}]`
|
||||
}
|
||||
if (_exp === 'compare') {
|
||||
const idx = compareTypeList.findIndex((item) => item.value === rule.compareType)
|
||||
singleRuleExp += `${compareTypeList[idx].label}${rule.value ?? ''}`
|
||||
}
|
||||
return singleRuleExp
|
||||
})
|
||||
this.filterExp = expList.join(',')
|
||||
this.$emit('setExpFromFilter', this.filterExp)
|
||||
} else {
|
||||
this.$emit('setExpFromFilter', '')
|
||||
}
|
||||
this.visible = false
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.table-filter {
|
||||
.table-filter-add {
|
||||
margin-top: 10px;
|
||||
& > a {
|
||||
padding: 2px 8px;
|
||||
&:hover {
|
||||
background-color: @primary-color_5;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.table-filter-extra-icon {
|
||||
padding: 0px 2px;
|
||||
&:hover {
|
||||
display: inline-block;
|
||||
border-radius: 5px;
|
||||
background-color: #f0faff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
.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>
|
||||
|
|
|
@ -341,7 +341,7 @@ export default {
|
|||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
<style lang="less" scoped>
|
||||
.pop_btn {
|
||||
text-align: right;
|
||||
margin-top: 24px;
|
||||
|
|
|
@ -226,16 +226,16 @@ export default {
|
|||
right: 4px;
|
||||
display: none;
|
||||
&:hover {
|
||||
color: #1f78d1;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
&:hover .ant-transfer-list-icon {
|
||||
display: inline;
|
||||
background-color: #c0eaff;
|
||||
background-color: @primary-color_4;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.ant-transfer-list-content-item-selected {
|
||||
background-color: #f0faff;
|
||||
background-color: ~'@{primary-color_8}35';
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -58,10 +58,7 @@
|
|||
:title="$t('acl.visualRole')"
|
||||
:width="120"
|
||||
align="center"
|
||||
:filters="[
|
||||
{ label: $t('yes'), value: 1 },
|
||||
{ label: $t('no'), value: 0 },
|
||||
]"
|
||||
:filters="visualRoleFilters"
|
||||
:filterMultiple="false"
|
||||
:filter-method="
|
||||
({ value, row }) => {
|
||||
|
@ -155,6 +152,10 @@ export default {
|
|||
pageSizeOptions: ['20', '50', '100', '200'],
|
||||
searchName: '',
|
||||
filterTableValue: { user_role: 1, user_only: 0 },
|
||||
visualRoleFilters: [
|
||||
{ label: this.$t('yes'), value: 1 },
|
||||
{ label: this.$t('no'), value: 0 }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -187,7 +187,7 @@ export default {
|
|||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: @primary-color;
|
||||
border: solid 3px #E2E7FC;
|
||||
border: solid 3px @primary-color_4;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,150 +1,156 @@
|
|||
<template>
|
||||
<div class="ci-type-grant">
|
||||
<vxe-table
|
||||
ref="xTable"
|
||||
size="mini"
|
||||
stripe
|
||||
class="ops-stripe-table"
|
||||
:data="filterTableData"
|
||||
:max-height="`${tableHeight}px`"
|
||||
:row-style="(params) => getCurrentRowStyle(params, addedRids)"
|
||||
>
|
||||
<vxe-column field="name"></vxe-column>
|
||||
<vxe-column v-for="col in columns" :key="col" :field="col" :title="permMap[col]">
|
||||
<template #default="{row}">
|
||||
<ReadCheckbox
|
||||
v-if="['read'].includes(col.split('_')[0])"
|
||||
:value="row[col.split('_')[0]]"
|
||||
:valueKey="col"
|
||||
:rid="row.rid"
|
||||
@openReadGrantModal="() => openReadGrantModal(col, row)"
|
||||
/>
|
||||
<a-checkbox v-else-if="col === 'grant'" :checked="row[col]" @click="clickGrant(col, row)"></a-checkbox>
|
||||
<a-checkbox @change="(e) => handleChange(e, col, row)" v-else v-model="row[col]"></a-checkbox>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<template #empty>
|
||||
<div v-if="loading()" style="height: 200px; line-height: 200px;color:#2F54EB">
|
||||
<a-icon type="loading" /> {{ $t('loading') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<img :style="{ width: '100px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import { permMap } from './constants.js'
|
||||
import { grantCiType, revokeCiType } from '../../api/CIType'
|
||||
import ReadCheckbox from './readCheckbox.vue'
|
||||
import { getCurrentRowStyle } from './utils'
|
||||
|
||||
export default {
|
||||
name: 'CiTypeGrant',
|
||||
components: { ReadCheckbox },
|
||||
inject: ['loading', 'isModal'],
|
||||
props: {
|
||||
CITypeId: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
tableData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
grantType: {
|
||||
type: String,
|
||||
default: 'ci_type',
|
||||
},
|
||||
addedRids: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
filterTableData() {
|
||||
const _tableData = this.tableData.filter((data) => {
|
||||
const _intersection = _.intersection(
|
||||
Object.keys(data),
|
||||
this.columns.map((col) => col.split('_')[0])
|
||||
)
|
||||
return _intersection && _intersection.length
|
||||
})
|
||||
return _.uniqBy(_tableData, (item) => item.rid)
|
||||
},
|
||||
columns() {
|
||||
if (this.grantType === 'ci_type') {
|
||||
return ['config', 'grant']
|
||||
}
|
||||
return ['read_attr', 'read_ci', 'create', 'update', 'delete']
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableHeight() {
|
||||
if (this.isModal) {
|
||||
return (this.windowHeight - 104) / 2
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowStyle,
|
||||
async handleChange(e, col, row) {
|
||||
if (e.target.checked) {
|
||||
await grantCiType(this.CITypeId, row.rid, { perms: [col] }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
} else {
|
||||
await revokeCiType(this.CITypeId, row.rid, { perms: [col] }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
}
|
||||
},
|
||||
grantDepart() {
|
||||
this.$emit('grantDepart', this.grantType)
|
||||
},
|
||||
grantRole() {
|
||||
this.$emit('grantRole', this.grantType)
|
||||
},
|
||||
openReadGrantModal(col, row) {
|
||||
this.$emit('openReadGrantModal', col, row)
|
||||
},
|
||||
clickGrant(col, row, rowIndex) {
|
||||
if (!row[col]) {
|
||||
this.handleChange({ target: { checked: true } }, col, row)
|
||||
const _idx = this.tableData.findIndex((item) => item.rid === row.rid)
|
||||
this.$set(this.tableData, _idx, { ...this.tableData[_idx], grant: true })
|
||||
} else {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: that.$t('warning'),
|
||||
content: that.$t('cmdb.components.confirmRevoke', { name: `${row.name}` }),
|
||||
onOk() {
|
||||
that.handleChange({ target: { checked: false } }, col, row)
|
||||
const _idx = that.tableData.findIndex((item) => item.rid === row.rid)
|
||||
that.$set(that.tableData, _idx, { ...that.tableData[_idx], grant: false })
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ci-type-grant {
|
||||
padding: 10px 0;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="ci-type-grant">
|
||||
<vxe-table
|
||||
ref="xTable"
|
||||
size="mini"
|
||||
stripe
|
||||
class="ops-stripe-table"
|
||||
:data="filterTableData"
|
||||
:max-height="`${tableHeight}px`"
|
||||
:row-class-name="(params) => getCurrentRowClass(params, addedRids)"
|
||||
>
|
||||
<vxe-column field="name"></vxe-column>
|
||||
<vxe-column v-for="col in columns" :key="col" :field="col" :title="permMap[col]">
|
||||
<template #default="{row}">
|
||||
<ReadCheckbox
|
||||
v-if="['read'].includes(col.split('_')[0])"
|
||||
:value="row[col.split('_')[0]]"
|
||||
:valueKey="col"
|
||||
:rid="row.rid"
|
||||
@openReadGrantModal="() => openReadGrantModal(col, row)"
|
||||
/>
|
||||
<a-checkbox v-else-if="col === 'grant'" :checked="row[col]" @click="clickGrant(col, row)"></a-checkbox>
|
||||
<a-checkbox @change="(e) => handleChange(e, col, row)" v-else v-model="row[col]"></a-checkbox>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<template #empty>
|
||||
<div v-if="loading()" class="ci-type-grant-loading">
|
||||
<a-icon type="loading" /> {{ $t('loading') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<img :style="{ width: '100px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import { permMap } from './constants.js'
|
||||
import { grantCiType, revokeCiType } from '../../api/CIType'
|
||||
import ReadCheckbox from './readCheckbox.vue'
|
||||
import { getCurrentRowClass } from './utils'
|
||||
|
||||
export default {
|
||||
name: 'CiTypeGrant',
|
||||
components: { ReadCheckbox },
|
||||
inject: ['loading', 'isModal'],
|
||||
props: {
|
||||
CITypeId: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
tableData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
grantType: {
|
||||
type: String,
|
||||
default: 'ci_type',
|
||||
},
|
||||
addedRids: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
filterTableData() {
|
||||
const _tableData = this.tableData.filter((data) => {
|
||||
const _intersection = _.intersection(
|
||||
Object.keys(data),
|
||||
this.columns.map((col) => col.split('_')[0])
|
||||
)
|
||||
return _intersection && _intersection.length
|
||||
})
|
||||
return _.uniqBy(_tableData, (item) => item.rid)
|
||||
},
|
||||
columns() {
|
||||
if (this.grantType === 'ci_type') {
|
||||
return ['config', 'grant']
|
||||
}
|
||||
return ['read_attr', 'read_ci', 'create', 'update', 'delete']
|
||||
},
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableHeight() {
|
||||
if (this.isModal) {
|
||||
return (this.windowHeight - 104) / 2
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowClass,
|
||||
async handleChange(e, col, row) {
|
||||
if (e.target.checked) {
|
||||
await grantCiType(this.CITypeId, row.rid, { perms: [col] }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
} else {
|
||||
await revokeCiType(this.CITypeId, row.rid, { perms: [col] }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
}
|
||||
},
|
||||
grantDepart() {
|
||||
this.$emit('grantDepart', this.grantType)
|
||||
},
|
||||
grantRole() {
|
||||
this.$emit('grantRole', this.grantType)
|
||||
},
|
||||
openReadGrantModal(col, row) {
|
||||
this.$emit('openReadGrantModal', col, row)
|
||||
},
|
||||
clickGrant(col, row, rowIndex) {
|
||||
if (!row[col]) {
|
||||
this.handleChange({ target: { checked: true } }, col, row)
|
||||
const _idx = this.tableData.findIndex((item) => item.rid === row.rid)
|
||||
this.$set(this.tableData, _idx, { ...this.tableData[_idx], grant: true })
|
||||
} else {
|
||||
const that = this
|
||||
this.$confirm({
|
||||
title: that.$t('warning'),
|
||||
content: that.$t('cmdb.components.confirmRevoke', { name: `${row.name}` }),
|
||||
onOk() {
|
||||
that.handleChange({ target: { checked: false } }, col, row)
|
||||
const _idx = that.tableData.findIndex((item) => item.rid === row.rid)
|
||||
that.$set(that.tableData, _idx, { ...that.tableData[_idx], grant: false })
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ci-type-grant {
|
||||
padding: 10px 0;
|
||||
|
||||
&-loading {
|
||||
height: 200px;
|
||||
line-height: 200px;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -366,5 +366,9 @@ export default {
|
|||
|
||||
.btn-wave-hover(@primary-color_4, -1);
|
||||
}
|
||||
|
||||
.grant-table-row-focus {
|
||||
background-color: @primary-color_8;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,98 +1,98 @@
|
|||
<template>
|
||||
<div class="ci-relation-grant">
|
||||
<vxe-table
|
||||
ref="xTable"
|
||||
size="mini"
|
||||
stripe
|
||||
class="ops-stripe-table"
|
||||
:data="tableData"
|
||||
:max-height="`${tableHeight}px`"
|
||||
:row-style="(params) => getCurrentRowStyle(params, addedRids)"
|
||||
>
|
||||
<vxe-column field="name"></vxe-column>
|
||||
<vxe-column v-for="col in columns" :key="col" :field="col" :title="permMap[col]">
|
||||
<template #default="{row}">
|
||||
<a-checkbox @change="(e) => handleChange(e, col, row)" v-model="row[col]"></a-checkbox>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { permMap } from './constants.js'
|
||||
import { grantRelationView, revokeRelationView } from '../../api/preference.js'
|
||||
import { getCurrentRowStyle } from './utils'
|
||||
|
||||
export default {
|
||||
name: 'RelationViewGrant',
|
||||
inject: ['loading', 'isModal'],
|
||||
props: {
|
||||
resourceTypeName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
tableData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
grantType: {
|
||||
type: String,
|
||||
default: 'relation_view',
|
||||
},
|
||||
addedRids: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columns: ['read', 'grant'],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableHeight() {
|
||||
if (this.isModal) {
|
||||
return (this.windowHeight - 104) / 2
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowStyle,
|
||||
grantDepart() {
|
||||
this.$emit('grantDepart', this.grantType)
|
||||
},
|
||||
grantRole() {
|
||||
this.$emit('grantRole', this.grantType)
|
||||
},
|
||||
handleChange(e, col, row) {
|
||||
if (e.target.checked) {
|
||||
grantRelationView(row.rid, { perms: [col], name: this.resourceTypeName }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
} else {
|
||||
revokeRelationView(row.rid, { perms: [col], name: this.resourceTypeName }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ci-relation-grant {
|
||||
padding: 10px 0;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="ci-relation-grant">
|
||||
<vxe-table
|
||||
ref="xTable"
|
||||
size="mini"
|
||||
stripe
|
||||
class="ops-stripe-table"
|
||||
:data="tableData"
|
||||
:max-height="`${tableHeight}px`"
|
||||
:row-class-name="(params) => getCurrentRowClass(params, addedRids)"
|
||||
>
|
||||
<vxe-column field="name"></vxe-column>
|
||||
<vxe-column v-for="col in columns" :key="col" :field="col" :title="permMap[col]">
|
||||
<template #default="{row}">
|
||||
<a-checkbox @change="(e) => handleChange(e, col, row)" v-model="row[col]"></a-checkbox>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { permMap } from './constants.js'
|
||||
import { grantRelationView, revokeRelationView } from '../../api/preference.js'
|
||||
import { getCurrentRowClass } from './utils'
|
||||
|
||||
export default {
|
||||
name: 'RelationViewGrant',
|
||||
inject: ['loading', 'isModal'],
|
||||
props: {
|
||||
resourceTypeName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
tableData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
grantType: {
|
||||
type: String,
|
||||
default: 'relation_view',
|
||||
},
|
||||
addedRids: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columns: ['read', 'grant'],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableHeight() {
|
||||
if (this.isModal) {
|
||||
return (this.windowHeight - 104) / 2
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowClass,
|
||||
grantDepart() {
|
||||
this.$emit('grantDepart', this.grantType)
|
||||
},
|
||||
grantRole() {
|
||||
this.$emit('grantRole', this.grantType)
|
||||
},
|
||||
handleChange(e, col, row) {
|
||||
if (e.target.checked) {
|
||||
grantRelationView(row.rid, { perms: [col], name: this.resourceTypeName }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
} else {
|
||||
revokeRelationView(row.rid, { perms: [col], name: this.resourceTypeName }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ci-relation-grant {
|
||||
padding: 10px 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
:data="tableData"
|
||||
:max-height="`${tableHeight}px`"
|
||||
:scroll-y="{enabled: true}"
|
||||
:row-style="(params) => getCurrentRowStyle(params, addedRids)"
|
||||
:row-class-name="(params) => getCurrentRowClass(params, addedRids)"
|
||||
>
|
||||
<vxe-column field="name"></vxe-column>
|
||||
<vxe-column v-for="col in columns" :key="col" :field="col" :title="permMap[col]">
|
||||
|
@ -27,7 +27,7 @@
|
|||
<script>
|
||||
import { permMap } from './constants.js'
|
||||
import { grantTopologyView, revokeTopologyView } from '@/modules/cmdb/api/topology.js'
|
||||
import { getCurrentRowStyle } from './utils'
|
||||
import { getCurrentRowClass } from './utils'
|
||||
export default {
|
||||
name: 'TopologyViewGrant',
|
||||
inject: ['loading', 'isModal'],
|
||||
|
@ -73,7 +73,7 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowStyle,
|
||||
getCurrentRowClass,
|
||||
grantDepart() {
|
||||
this.$emit('grantDepart', this.grantType)
|
||||
},
|
||||
|
|
|
@ -1,100 +1,100 @@
|
|||
<template>
|
||||
<div class="ci-relation-grant">
|
||||
<vxe-table
|
||||
ref="xTable"
|
||||
size="mini"
|
||||
stripe
|
||||
class="ops-stripe-table"
|
||||
:data="tableData"
|
||||
:max-height="`${tableHeight}px`"
|
||||
:row-style="(params) => getCurrentRowStyle(params, addedRids)"
|
||||
>
|
||||
<vxe-column field="name"></vxe-column>
|
||||
<vxe-column v-for="col in columns" :key="col" :field="col" :title="permMap[col]">
|
||||
<template #default="{row}">
|
||||
<a-checkbox @change="(e) => handleChange(e, col, row)" v-model="row[col]"></a-checkbox>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { permMap } from './constants.js'
|
||||
import { grantTypeRelation, revokeTypeRelation } from '../../api/CITypeRelation.js'
|
||||
import { getCurrentRowStyle } from './utils'
|
||||
|
||||
export default {
|
||||
name: 'TypeRelationGrant',
|
||||
inject: ['loading', 'isModal'],
|
||||
props: {
|
||||
tableData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
grantType: {
|
||||
type: String,
|
||||
default: 'type_relation',
|
||||
},
|
||||
typeRelationIds: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
addedRids: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columns: ['create', 'grant', 'delete'],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableHeight() {
|
||||
if (this.isModal) {
|
||||
return (this.windowHeight - 104) / 2
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowStyle,
|
||||
grantDepart() {
|
||||
this.$emit('grantDepart', this.grantType)
|
||||
},
|
||||
grantRole() {
|
||||
this.$emit('grantRole', this.grantType)
|
||||
},
|
||||
handleChange(e, col, row) {
|
||||
const first = this.typeRelationIds[0]
|
||||
const second = this.typeRelationIds[1]
|
||||
if (e.target.checked) {
|
||||
grantTypeRelation(first, second, row.rid, { perms: [col] }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
} else {
|
||||
revokeTypeRelation(first, second, row.rid, { perms: [col] }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ci-relation-grant {
|
||||
padding: 10px 0;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="ci-relation-grant">
|
||||
<vxe-table
|
||||
ref="xTable"
|
||||
size="mini"
|
||||
stripe
|
||||
class="ops-stripe-table"
|
||||
:data="tableData"
|
||||
:max-height="`${tableHeight}px`"
|
||||
:row-class-name="(params) => getCurrentRowClass(params, addedRids)"
|
||||
>
|
||||
<vxe-column field="name"></vxe-column>
|
||||
<vxe-column v-for="col in columns" :key="col" :field="col" :title="permMap[col]">
|
||||
<template #default="{row}">
|
||||
<a-checkbox @change="(e) => handleChange(e, col, row)" v-model="row[col]"></a-checkbox>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<a-space>
|
||||
<span class="grant-button" @click="grantDepart">{{ $t('cmdb.components.grantUser') }}</span>
|
||||
<span class="grant-button" @click="grantRole">{{ $t('cmdb.components.grantRole') }}</span>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { permMap } from './constants.js'
|
||||
import { grantTypeRelation, revokeTypeRelation } from '../../api/CITypeRelation.js'
|
||||
import { getCurrentRowClass } from './utils'
|
||||
|
||||
export default {
|
||||
name: 'TypeRelationGrant',
|
||||
inject: ['loading', 'isModal'],
|
||||
props: {
|
||||
tableData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
grantType: {
|
||||
type: String,
|
||||
default: 'type_relation',
|
||||
},
|
||||
typeRelationIds: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
addedRids: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columns: ['create', 'grant', 'delete'],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
windowHeight() {
|
||||
return this.$store.state.windowHeight
|
||||
},
|
||||
tableHeight() {
|
||||
if (this.isModal) {
|
||||
return (this.windowHeight - 104) / 2
|
||||
}
|
||||
return (this.windowHeight - 104) / 2 - 116
|
||||
},
|
||||
permMap() {
|
||||
return permMap()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCurrentRowClass,
|
||||
grantDepart() {
|
||||
this.$emit('grantDepart', this.grantType)
|
||||
},
|
||||
grantRole() {
|
||||
this.$emit('grantRole', this.grantType)
|
||||
},
|
||||
handleChange(e, col, row) {
|
||||
const first = this.typeRelationIds[0]
|
||||
const second = this.typeRelationIds[1]
|
||||
if (e.target.checked) {
|
||||
grantTypeRelation(first, second, row.rid, { perms: [col] }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
} else {
|
||||
revokeTypeRelation(first, second, row.rid, { perms: [col] }).catch(() => {
|
||||
this.$emit('getTableData')
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ci-relation-grant {
|
||||
padding: 10px 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -16,12 +16,8 @@
|
|||
<template v-for="(item, index) in preferenceSearchList.slice(0, 3)">
|
||||
<span
|
||||
v-if="item.name.length > 6"
|
||||
class="preference-search-tag"
|
||||
:class="['preference-search-tag', item.id === currentPreferenceSearch ? 'preference-search-tag-focus' : '']"
|
||||
:key="`${item.id}_${index}`"
|
||||
:style="{
|
||||
backgroundColor: item.id === currentPreferenceSearch ? '#2f54eb' : '',
|
||||
color: item.id === currentPreferenceSearch ? '#fff' : '',
|
||||
}"
|
||||
>
|
||||
<a-tooltip :title="item.name">
|
||||
<span @click="clickPreferenceSearch(item)">{{ `${item.name.slice(0, 6)}...` }}</span>
|
||||
|
@ -33,11 +29,7 @@
|
|||
<span
|
||||
v-else
|
||||
:key="`${item.id}_${index}`"
|
||||
class="preference-search-tag"
|
||||
:style="{
|
||||
backgroundColor: item.id === currentPreferenceSearch ? '#2f54eb' : '',
|
||||
color: item.id === currentPreferenceSearch ? '#fff' : '',
|
||||
}"
|
||||
:class="['preference-search-tag', item.id === currentPreferenceSearch ? 'preference-search-tag-focus' : '']"
|
||||
>
|
||||
<span @click="clickPreferenceSearch(item)">{{ item.name }}</span>
|
||||
<a-popconfirm :title="$t('cmdb.ciType.confirmDelete2')" @confirm="deletePreferenceSearch(item)">
|
||||
|
@ -193,6 +185,11 @@ export default {
|
|||
&:hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
&-focus {
|
||||
background-color: @primary-color;
|
||||
color: #FFFFFF !important;
|
||||
}
|
||||
}
|
||||
.preference-search-delete {
|
||||
color: #a9a9a9;
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
<a-icon
|
||||
type="search"
|
||||
slot="suffix"
|
||||
:style="{ color: fuzzySearch ? '#2f54eb' : '#d9d9d9', cursor: 'pointer' }"
|
||||
:class="['search-form-bar-input-icon', fuzzySearch ? 'search-form-bar-input-icon-focus' : '']"
|
||||
@click="emitRefresh"
|
||||
/>
|
||||
<a-tooltip slot="prefix" placement="bottom" :overlayStyle="{ maxWidth: '550px', whiteSpace: 'pre-line' }">
|
||||
|
@ -308,6 +308,16 @@ export default {
|
|||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 32px;
|
||||
|
||||
&-input-icon {
|
||||
cursor: pointer;
|
||||
color: #d9d9d9;
|
||||
|
||||
&-focus {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.search-form-bar-filter {
|
||||
.ops_display_wrapper(transparent);
|
||||
|
||||
|
|
|
@ -315,8 +315,9 @@ const cmdb_en = {
|
|||
ciGrantTip: `Filter conditions can be changed dynamically using {{}} referenced variables, currently user variables are supported, such as {{user.uid}},{{user.username}},{{user.email}},{{user.nickname}}`,
|
||||
searchInputTip: 'Please search for resource keywords',
|
||||
columnSearchInputTip: '192.168.1.1\n192.168.1.2\n192.168.1.3',
|
||||
rowSearchMode: 'Single Row Search',
|
||||
columnSearchMode: 'Multi Row Search',
|
||||
rowSearchMode: 'Single Row',
|
||||
columnSearchMode: 'Multi Row',
|
||||
columnSearchTip: 'Supports retrieval of short texts only',
|
||||
resourceSearch: 'Resource Search',
|
||||
recentSearch: 'Recent Search',
|
||||
myCollection: 'My Collection',
|
||||
|
|
|
@ -315,8 +315,9 @@ const cmdb_zh = {
|
|||
ciGrantTip: `筛选条件可使用{{}}引用变量实现动态变化,目前支持用户变量,如{{user.uid}},{{user.username}},{{user.email}},{{user.nickname}}`,
|
||||
searchInputTip: '请搜索资源关键字',
|
||||
columnSearchInputTip: '192.168.1.1\n192.168.1.2\n192.168.1.3',
|
||||
rowSearchMode: '单行搜索',
|
||||
columnSearchMode: '多行搜索',
|
||||
rowSearchMode: '单行',
|
||||
columnSearchMode: '多行',
|
||||
columnSearchTip: '仅支持检索短文本',
|
||||
resourceSearch: '资源搜索',
|
||||
recentSearch: '最近搜索',
|
||||
myCollection: '我的收藏',
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<p v-html="$t('cmdb.batch.drawTips1')"></p>
|
||||
<p v-html="$t('cmdb.batch.drawTips2')"></p>
|
||||
<div v-for="item in fileList" :key="item.name" class="cmdb-batch-upload-dragger-file">
|
||||
<span><a-icon type="file" :style="{ color: '#2F54EB', marginRight: '5px' }" />{{ item.name }}</span>
|
||||
<span><a-icon type="file" class="cmdb-batch-upload-dragger-file-icon"/>{{ item.name }}</span>
|
||||
<a-progress :status="progressStatus" :percent="percent" />
|
||||
</div>
|
||||
</a-upload-dragger>
|
||||
|
@ -92,12 +92,7 @@ export default {
|
|||
}
|
||||
.ant-upload.ant-upload-drag {
|
||||
border: none;
|
||||
background: linear-gradient(90deg, @text-color_5 50%, transparent 0) repeat-x,
|
||||
linear-gradient(90deg, @text-color_5 50%, transparent 0) repeat-x,
|
||||
linear-gradient(0deg, @text-color_5 50%, transparent 0) repeat-y,
|
||||
linear-gradient(0deg, @text-color_5 50%, transparent 0) repeat-y;
|
||||
background-size: 15px 1px, 15px 1px, 1px 15px, 1px 15px;
|
||||
background-position: 0 0, 0 100%, 0 0, 100% 0;
|
||||
background: ~'linear-gradient(90deg, @{text-color_5} 50%, transparent 0) repeat-x 0 0 / 15px 1px, linear-gradient(90deg, @{text-color_5} 50%, transparent 0) repeat-x 0 100% / 15px 1px, linear-gradient(0deg, @{text-color_5} 50%, transparent 0) repeat-y 0 0 / 1px 15px, linear-gradient(0deg, @{text-color_5} 50%, transparent 0) repeat-y 100% 0 / 1px 15px';
|
||||
.ant-upload-drag-container > i {
|
||||
font-size: 60px;
|
||||
}
|
||||
|
@ -106,13 +101,7 @@ export default {
|
|||
}
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(90deg, @primary-color_2 50%, transparent 0) repeat-x,
|
||||
linear-gradient(90deg, @primary-color_2 50%, transparent 0) repeat-x,
|
||||
linear-gradient(0deg, @primary-color_2 50%, transparent 0) repeat-y,
|
||||
linear-gradient(0deg, @primary-color_2 50%, transparent 0) repeat-y;
|
||||
background-size: 15px 1px, 15px 1px, 1px 15px, 1px 15px;
|
||||
background-position: 0 0, 0 100%, 0 0, 100% 0;
|
||||
background-color: @primary-color_7;
|
||||
background: ~'linear-gradient(90deg, @{primary-color_2} 50%, transparent 0) repeat-x 0 0 / 15px 1px, linear-gradient(90deg, @{primary-color_2} 50%, transparent 0) repeat-x 0 100% / 15px 1px, linear-gradient(0deg, @{primary-color_2} 50%, transparent 0) repeat-y 0 0 / 1px 15px, linear-gradient(0deg, @{primary-color_2} 50%, transparent 0) repeat-y 100% 0 / 1px 15px, @{primary-color_7}';
|
||||
}
|
||||
}
|
||||
.ant-upload.ant-upload-drag .ant-upload-drag-container {
|
||||
|
@ -139,6 +128,11 @@ export default {
|
|||
white-space: nowrap;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
color: @primary-color;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.cmdb-batch-upload-tips {
|
||||
width: 50%;
|
||||
|
|
|
@ -47,8 +47,8 @@
|
|||
<a-descriptions layout="horizontal" bordered size="small" :column="2">
|
||||
<a-descriptions-item v-for="item in propertyList" :key="item.property" :label="item.label">
|
||||
<ops-icon
|
||||
:style="{ color: property[item.property] ? '#7f97fa' : '', fontSize: '10px' }"
|
||||
:type="`ops-${item.property}-disabled`"
|
||||
:class="['attribute-card-footer-icon', property[item.property] ? 'attribute-card-footer-icon-mark' : '']"
|
||||
/>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label></a-descriptions-item>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<ops-icon
|
||||
v-for="item in propertyList.filter((p) => property[p.property])"
|
||||
:key="item.property"
|
||||
:style="{ color: '#7f97fa', fontSize: '10px' }"
|
||||
class="attribute-card-footer-icon attribute-card-footer-icon-mark"
|
||||
:type="`ops-${item.property}-disabled`"
|
||||
/>
|
||||
</a-space>
|
||||
|
@ -247,13 +247,13 @@ export default {
|
|||
.attribute-card {
|
||||
width: 172px;
|
||||
height: 75px;
|
||||
background: @primary-color_6;
|
||||
background-color: @primary-color_6;
|
||||
border-radius: 2px;
|
||||
position: relative;
|
||||
margin-bottom: 16px;
|
||||
transition: all 0.3s;
|
||||
&:hover {
|
||||
box-shadow: 0 4px 12px #4e5ea066;
|
||||
box-shadow: 0 4px 12px @primary-color_8;
|
||||
.attribute-card-operation {
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
@ -342,6 +342,15 @@ export default {
|
|||
padding: 2px 0 2px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.attribute-card-footer-icon {
|
||||
font-size: 10px;
|
||||
|
||||
&-mark {
|
||||
color: @primary-color_2;
|
||||
}
|
||||
}
|
||||
|
||||
.attribute-card-inherited {
|
||||
background: @primary-color_7;
|
||||
.attribute-card-footer {
|
||||
|
@ -356,10 +365,10 @@ export default {
|
|||
justify-content: center;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
background-color: inherit;
|
||||
background-color: inherit !important;
|
||||
&:hover {
|
||||
box-shadow: none;
|
||||
background-color: @primary-color_6;
|
||||
box-shadow: none !important;
|
||||
background-color: @primary-color_6 !important;
|
||||
}
|
||||
&:after {
|
||||
content: '';
|
||||
|
|
|
@ -140,7 +140,7 @@
|
|||
:type="ci.icon.split('$$')[0]"
|
||||
/>
|
||||
</template>
|
||||
<span :style="{ color: '#2f54eb' }" v-else>{{ ci.name[0].toUpperCase() }}</span>
|
||||
<span class="primary-color" v-else>{{ ci.name[0].toUpperCase() }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<span class="ci-types-left-detail-title">{{ ci.alias || ci.name }}</span>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
:title="$t('cmdb.ciType.choiceWebhookTips')"
|
||||
>
|
||||
<a-icon
|
||||
style="position:absolute;top:3px;left:-17px;color:#2f54eb;"
|
||||
class="tab-webhook-filter-icon"
|
||||
type="question-circle"
|
||||
theme="filled"
|
||||
/>
|
||||
|
@ -553,7 +553,7 @@ export default {
|
|||
|
||||
&-tag {
|
||||
background-color: #E1EFFF;
|
||||
color: #2F54EB;
|
||||
color: @primary-color;
|
||||
font-size: 10px;
|
||||
font-weight: 400;
|
||||
padding: 0 3px;
|
||||
|
@ -575,6 +575,13 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.tab-webhook-filter-icon {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: -17px;
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.script-tip {
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
|
|
|
@ -363,7 +363,7 @@ export default {
|
|||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: @primary-color;
|
||||
border: solid 3px #E2E7FC;
|
||||
border: solid 3px @primary-color_4;
|
||||
border-radius: 50%
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<vxe-column field="source_ci_type_name" :title="$t('cmdb.ciType.sourceCIType')"></vxe-column>
|
||||
<vxe-column field="relation_type" :title="$t('cmdb.ciType.relationType')">
|
||||
<template #default="{row}">
|
||||
<span style="color:#2f54eb" v-if="row.isParent">{{ $t('cmdb.ciType.isParent') }}</span>
|
||||
<span class="primary-color" v-if="row.isParent">{{ $t('cmdb.ciType.isParent') }}</span>
|
||||
{{ row.relation_type }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
|
@ -700,7 +700,7 @@ export default {
|
|||
}
|
||||
|
||||
/deep/ .relation-table-parent {
|
||||
background-color: #f5f8ff !important;
|
||||
background-color: @primary-color_5 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<vxe-column field="attr_ids" :title="$t('cmdb.ciType.attributes')" :edit-render="{}">
|
||||
<template #default="{ row }">
|
||||
<template v-for="(attr, index) in row.attr_ids">
|
||||
<span :key="attr" :style="{ color: '#2f54eb' }">{{ getDisplayName(attr) }}</span>
|
||||
<span :key="attr" class="primary-color">{{ getDisplayName(attr) }}</span>
|
||||
<span :key="`_${attr}`" v-if="index !== row.attr_ids.length - 1"> + </span>
|
||||
</template>
|
||||
</template>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
:type="ciType.icon.split('$$')[0]"
|
||||
/>
|
||||
</template>
|
||||
<span :style="{ color: '#2f54eb' }" v-else>{{ ciType.name[0].toUpperCase() }}</span>
|
||||
<span class="primary-color" v-else>{{ ciType.name[0].toUpperCase() }}</span>
|
||||
</div>
|
||||
<span :style="{ ...options.fontConfig }">{{ toThousands(data) }}</span>
|
||||
</div>
|
||||
|
|
|
@ -148,7 +148,7 @@
|
|||
:type="ciType.icon.split('$$')[0]"
|
||||
/>
|
||||
</template>
|
||||
<span :style="{ color: '#2f54eb' }" v-else>{{ ciType.name[0].toUpperCase() }}</span>
|
||||
<span class="primary-color" v-else>{{ ciType.name[0].toUpperCase() }}</span>
|
||||
</template>
|
||||
<span :style="{ color: '#000' }"> {{ form.name }}</span>
|
||||
</div>
|
||||
|
@ -800,7 +800,7 @@ export default {
|
|||
}
|
||||
}
|
||||
.chart-right-type-box-selected {
|
||||
background-color: #e5f1ff;
|
||||
background-color: @primary-color_3;
|
||||
}
|
||||
}
|
||||
.chart-width {
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
:type="getCiType(item).icon.split('$$')[0]"
|
||||
/>
|
||||
</template>
|
||||
<span :style="{ color: '#2f54eb' }" v-else>{{ getCiType(item).name[0].toUpperCase() }}</span>
|
||||
<span class="primary-color" v-else>{{ getCiType(item).name[0].toUpperCase() }}</span>
|
||||
</template>
|
||||
<span :style="{ color: item.options.chartType === 'count' ? item.options.fontColor : '#000' }">{{
|
||||
item.options.name
|
||||
|
|
|
@ -268,18 +268,18 @@ export default {
|
|||
margin-right: 2px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #3F75FF;
|
||||
color: #2F54EB;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
font-size: 12px;
|
||||
color: #3F75FF;
|
||||
color: #2F54EB;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #FFFFFF;
|
||||
box-shadow: 0px 22px 33px 0px rgba(41, 65, 126, 0.25);
|
||||
box-shadow: ~'0px 22px 33px 0px @{primary-color}15';
|
||||
z-index: 2;
|
||||
|
||||
.rack-grid-item-name {
|
||||
|
|
|
@ -58,15 +58,11 @@
|
|||
>
|
||||
<ops-icon
|
||||
:type="treeNodeData.icon"
|
||||
class="dcim-tree-node-icon"
|
||||
:style="{ color: treeNodeData.iconColor }"
|
||||
:class="['dcim-tree-node-icon', treeNodeData.dcimType === DCIM_TYPE.REGION ? 'primary-color' : '']"
|
||||
/>
|
||||
<a-tooltip :title="treeNodeData.title">
|
||||
<span
|
||||
class="dcim-tree-node-title"
|
||||
:style="{
|
||||
color: treeKey === treeNodeData.key ? '#2F54EB' : ''
|
||||
}"
|
||||
:class="['dcim-tree-node-title', treeKey === treeNodeData.key ? 'primary-color' : '']"
|
||||
>
|
||||
{{ treeNodeData.title }}
|
||||
</span>
|
||||
|
@ -164,6 +160,7 @@ export default {
|
|||
DCIM_TYPE.REGION,
|
||||
DCIM_TYPE.IDC
|
||||
],
|
||||
DCIM_TYPE,
|
||||
|
||||
viewDetailCITypeId: 0,
|
||||
viewDetailAttrObj: {},
|
||||
|
@ -365,6 +362,7 @@ export default {
|
|||
&-icon {
|
||||
font-size: 12px;
|
||||
flex-shrink: 0;
|
||||
color: #A5A9BC;
|
||||
}
|
||||
|
||||
&-title {
|
||||
|
|
|
@ -117,8 +117,8 @@
|
|||
}"
|
||||
@click="addDevice(index)"
|
||||
>
|
||||
<ops-icon
|
||||
type="monitor-add"
|
||||
<a-icon
|
||||
type="plus-circle"
|
||||
class="rack-container-main-list-gap-icon"
|
||||
/>
|
||||
<span
|
||||
|
@ -492,12 +492,13 @@ export default {
|
|||
&-icon {
|
||||
font-size: 12px;
|
||||
display: none;
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
&-text {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: rgba(0, 87, 255, 0.80);
|
||||
color: @primary-color;
|
||||
margin-left: 6px;
|
||||
display: none;
|
||||
}
|
||||
|
@ -508,7 +509,7 @@ export default {
|
|||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #D5DDEE;
|
||||
background-color: @primary-color_4;
|
||||
|
||||
.rack-container-main-list-gap-icon {
|
||||
display: inline-block;
|
||||
|
|
|
@ -165,7 +165,7 @@ export default {
|
|||
display: inline-block;
|
||||
width: 180px;
|
||||
height: 105px;
|
||||
box-shadow: 0px 2px 8px rgba(122, 140, 204, 0.25);
|
||||
box-shadow: 0px 2px 8px @primary-color_3;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
margin-bottom: 40px;
|
||||
|
@ -297,7 +297,7 @@ export default {
|
|||
|
||||
&, &.discovery-card-small {
|
||||
&:hover {
|
||||
box-shadow: 0px 6px 20px 0px rgba(122, 140, 204, 0.30);
|
||||
box-shadow: 0px 6px 20px 0px @primary-color_3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ export default {
|
|||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0px 6px 28px 0px rgba(122, 140, 204, 0.30);
|
||||
box-shadow: 0px 6px 28px 0px @primary-color_3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
class="setting-discovery-add"
|
||||
@click="handleOpenEditDrawer(null, 'add', DISCOVERY_CATEGORY_TYPE.PLUGIN)"
|
||||
>
|
||||
<a-icon type="plus-circle" theme="twoTone" />
|
||||
<a-icon class="setting-discovery-add-icon" type="plus-circle" />
|
||||
<span class="setting-discovery-add-text">
|
||||
{{ $t('cmdb.ad.addPlugin') }}
|
||||
</span>
|
||||
|
@ -380,6 +380,10 @@ export default {
|
|||
justify-content: center;
|
||||
cursor: pointer;
|
||||
|
||||
&-icon {
|
||||
color: @primary-color_9;
|
||||
}
|
||||
|
||||
&-text {
|
||||
color: @text-color_3;
|
||||
font-size: 12px;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
:type="ciType.icon.split('$$')[0]"
|
||||
/>
|
||||
</template>
|
||||
<span :style="{ color: '#2f54eb' }" v-else>{{ ciType.name[0].toUpperCase() }}</span>
|
||||
<span class="primary-color" v-else>{{ ciType.name[0].toUpperCase() }}</span>
|
||||
</span>
|
||||
<span :title="ciType.alias || ciType.name" class="cmdb-adc-side-name">{{ ciType.alias || ciType.name }}</span>
|
||||
</div>
|
||||
|
|
|
@ -26,10 +26,7 @@
|
|||
/>
|
||||
<a-tooltip :title="treeNodeData.title">
|
||||
<span
|
||||
class="ipam-tree-node-title"
|
||||
:style="{
|
||||
color: treeKey === treeNodeData.key ? '#2F54EB' : ''
|
||||
}"
|
||||
:class="['ipam-tree-node-title', treeKey === treeNodeData.key ? 'primary-color' : '']"
|
||||
>
|
||||
{{ treeNodeData.title }}
|
||||
</span>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<vxe-column
|
||||
field="relation_type_id"
|
||||
:title="$t('cmdb.custom_dashboard.relation')"
|
||||
:filters="[{ data: '' }]"
|
||||
:filters="relationTypeList"
|
||||
:filter-multiple="false"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
|
@ -144,7 +144,7 @@ export default {
|
|||
return {
|
||||
drawerVisible: false,
|
||||
tableData: [],
|
||||
relationTypeList: null,
|
||||
relationTypeList: [],
|
||||
type2attributes: {},
|
||||
tableAttrList: [],
|
||||
}
|
||||
|
@ -201,13 +201,6 @@ export default {
|
|||
async getRelationTypes() {
|
||||
const res = await getRelationTypes()
|
||||
this.relationTypeList = res.map((item) => ({ value: item.id, label: item.name }))
|
||||
const $table = this.$refs.xTable
|
||||
if ($table) {
|
||||
const nameColumn = $table.getColumnByField('relation_type_id')
|
||||
if (nameColumn) {
|
||||
$table.setFilter(nameColumn, this.relationTypeList)
|
||||
}
|
||||
}
|
||||
},
|
||||
// 转换关联关系
|
||||
handleConstraint(constraintId) {
|
||||
|
@ -359,5 +352,9 @@ export default {
|
|||
&-action {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/deep/ .ant-select-selection {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<span>{{ column.title }}</span>
|
||||
<a-popover trigger="click" placement="bottom">
|
||||
<a-icon class="filter" type="filter" theme="filled" />
|
||||
<a slot="content">
|
||||
<a class="filter-content" slot="content">
|
||||
<a-input
|
||||
:placeholder="$t('cmdb.history.userTips')"
|
||||
size="small"
|
||||
|
@ -453,4 +453,10 @@ export default {
|
|||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<span>{{ column.title }}</span>
|
||||
<a-popover trigger="click" placement="bottom">
|
||||
<a-icon class="filter" type="filter" theme="filled" />
|
||||
<a slot="content">
|
||||
<a class="filter-content" slot="content">
|
||||
<a-input
|
||||
:placeholder="$t('cmdb.history.userTips')"
|
||||
size="small"
|
||||
|
@ -47,7 +47,7 @@
|
|||
<span>{{ column.title }}</span>
|
||||
<a-popover trigger="click" placement="bottom">
|
||||
<a-icon class="filter" type="filter" theme="filled" />
|
||||
<a slot="content">
|
||||
<a class="filter-content" slot="content">
|
||||
<a-select
|
||||
v-model="queryParams.operate_type"
|
||||
:placeholder="$t('cmdb.history.filterOperate')"
|
||||
|
@ -445,4 +445,10 @@ export default {
|
|||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<span>{{ column.title }}</span>
|
||||
<a-popover trigger="click" placement="bottom">
|
||||
<a-icon class="filter" type="filter" theme="filled" />
|
||||
<a slot="content">
|
||||
<a class="filter-content" slot="content">
|
||||
<a-select
|
||||
v-model="queryParams.operate_type"
|
||||
:placeholder="$t('cmdb.history.filterOperate')"
|
||||
|
@ -563,4 +563,10 @@ export default {
|
|||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -654,11 +654,11 @@ export default {
|
|||
height: 155px;
|
||||
border-radius: @border-radius-box;
|
||||
background-color: #fff;
|
||||
box-shadow: 0px 2px 8px rgba(149, 160, 208, 0.25);
|
||||
box-shadow: ~'0px 2px 8px @{primary-color}15';
|
||||
margin: 0 20px 20px 0;
|
||||
padding: 12px;
|
||||
&:hover {
|
||||
box-shadow: 4px 25px 30px rgba(50, 89, 134, 0.25);
|
||||
box-shadow: ~'4px 25px 30px @{primary-color}15';
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.cmdb-preference-header {
|
||||
|
@ -733,10 +733,10 @@ export default {
|
|||
align-items: center;
|
||||
gap: 3px;
|
||||
font-size: 12px;
|
||||
color: rgba(0, 0, 0, 0.76);
|
||||
color: @text-color_1;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,11 @@
|
|||
<div class="search-condition-control">
|
||||
<treeselect
|
||||
:value="sourceCIType"
|
||||
class="custom-treeselect custom-treeselect-bgcAndBorder filter-content-ciTypes"
|
||||
class="custom-treeselect custom-treeselect-white filter-content-ciTypes"
|
||||
:style="{
|
||||
width: '100%',
|
||||
zIndex: '1000',
|
||||
'--custom-height': '32px',
|
||||
'--custom-bg-color': '#FFF',
|
||||
'--custom-multiple-lineHeight': '32px',
|
||||
}"
|
||||
:multiple="false"
|
||||
|
@ -699,14 +698,14 @@ export default {
|
|||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: #D9E4FA;
|
||||
background-color: @primary-color_4;
|
||||
|
||||
.search-condition-favor-name {
|
||||
color: #2F54EB;
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.search-condition-favor-close {
|
||||
color: #2F54EB;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -737,10 +736,10 @@ export default {
|
|||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #D9E4FA;
|
||||
background-color: @primary-color_4;
|
||||
|
||||
.search-condition-hide-icon {
|
||||
color: #2F54EB;
|
||||
color: @primary-color_4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -656,15 +656,15 @@ export default {
|
|||
|
||||
&:hover {
|
||||
.relation-search-expand-handle {
|
||||
background-color: #D9E4FA;
|
||||
background-color: @primary-color_4;
|
||||
}
|
||||
|
||||
.relation-search-expand-icon {
|
||||
color: #2F54EB;
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
.relation-search-expand-text {
|
||||
color: #2F54EB;
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -327,7 +327,7 @@ export default {
|
|||
&-header {
|
||||
width: 100%;
|
||||
height: 75px;
|
||||
background-color: #EBF0F9;
|
||||
background-color: @primary-color_3;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
@ -342,7 +342,7 @@ export default {
|
|||
right: -20px;
|
||||
top: 0px;
|
||||
transform: rotate(40deg);
|
||||
background: rgba(248, 249, 253, 0.60);
|
||||
background-color: @primary-color_5;
|
||||
}
|
||||
|
||||
&-line-2 {
|
||||
|
@ -352,7 +352,7 @@ export default {
|
|||
right: -110px;
|
||||
top: 0px;
|
||||
transform: rotate(40deg);
|
||||
background: rgba(248, 249, 253, 0.60);
|
||||
background-color: @primary-color_5;
|
||||
}
|
||||
|
||||
&-row {
|
||||
|
|
|
@ -431,7 +431,7 @@ export default {
|
|||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0px 2px 12px 0px rgba(147, 168, 223, 0.20);
|
||||
box-shadow: ~'0px 2px 12px 0px @{primary-color}15';
|
||||
|
||||
.list-card-collect {
|
||||
display: inline-block;
|
||||
|
|
|
@ -1,36 +1,48 @@
|
|||
<template>
|
||||
<div :class="['search-input', classType ? 'search-input-' + classType : '', { 'column-search-mode': isColumnSearch }]">
|
||||
<div :class="['search-input', classType ? 'search-input-' + classType : '']">
|
||||
<div class="search-area">
|
||||
<div v-show="!isColumnSearch" class="input-wrapper">
|
||||
<a-input
|
||||
:value="searchValue"
|
||||
class="search-input-component"
|
||||
:placeholder="$t('cmdb.ciType.searchInputTip')"
|
||||
@change="handleChangeSearchValue"
|
||||
@pressEnter="saveCondition(true, 'normal')"
|
||||
/>
|
||||
<a-input
|
||||
v-show="searchMode === SEARCH_MODE.NORMAL"
|
||||
:value="searchValue"
|
||||
class="search-input-component"
|
||||
:placeholder="$t('cmdb.ciType.searchInputTip')"
|
||||
@change="handleChangeSearchValue"
|
||||
@pressEnter="saveCondition(true)"
|
||||
>
|
||||
<a-icon
|
||||
class="search-icon"
|
||||
slot="prefix"
|
||||
type="search"
|
||||
@click="saveCondition(true, 'normal')"
|
||||
@click="saveCondition(true)"
|
||||
/>
|
||||
</div>
|
||||
</a-input>
|
||||
|
||||
<div v-show="isColumnSearch" class="textarea-wrapper">
|
||||
<div class="textarea-container">
|
||||
<a-textarea
|
||||
:value="searchValue"
|
||||
class="column-search-component"
|
||||
:rows="4"
|
||||
:placeholder="$t('cmdb.ciType.columnSearchInputTip')"
|
||||
@change="handleChangeColumnSearchValue"
|
||||
@pressEnter="handlePressEnter"
|
||||
/>
|
||||
<div
|
||||
v-show="searchMode === SEARCH_MODE.COLUMN"
|
||||
class="search-textarea-component"
|
||||
>
|
||||
<a-textarea
|
||||
:value="searchValue"
|
||||
:autosize="{
|
||||
minRows: 3,
|
||||
maxRows: 3,
|
||||
}"
|
||||
:placeholder="$t('cmdb.ciType.columnSearchInputTip')"
|
||||
@change="handleChangeSearchValue"
|
||||
/>
|
||||
<div class="search-textarea-icon-wrap">
|
||||
<a-icon
|
||||
class="search-icon"
|
||||
type="search"
|
||||
@click="saveCondition(true, 'column')"
|
||||
@click="saveCondition(true)"
|
||||
/>
|
||||
|
||||
<a-tooltip :title="$t('cmdb.ciType.columnSearchTip')">
|
||||
<a-icon
|
||||
type="info-circle"
|
||||
class="search-icon"
|
||||
/>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -46,11 +58,26 @@
|
|||
@saveCondition="saveCondition"
|
||||
/>
|
||||
|
||||
<div class="column-search-btn" @click="toggleColumnSearch">
|
||||
<a-icon class="column-search-btn-icon" type="menu" />
|
||||
<span class="column-search-btn-title">
|
||||
{{ isColumnSearch ? $t('cmdb.ciType.rowSearchMode') : $t('cmdb.ciType.columnSearchMode') }}
|
||||
<div class="search-mode-switch">
|
||||
<span
|
||||
v-for="(item) in searchModeList"
|
||||
:key="item.value"
|
||||
:class="['search-mode-switch-item', searchMode === item.value ? 'search-mode-switch-item-active' : '']"
|
||||
:style="{
|
||||
width: isZh ? '40px' : '65px'
|
||||
}"
|
||||
@click="updateSearchMode(item.value)"
|
||||
>
|
||||
{{ $t(item.label) }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
class="search-mode-switch-slide"
|
||||
:style="{
|
||||
left: searchMode === SEARCH_MODE.COLUMN ? (isZh ? '44px' : '69px') : '4px',
|
||||
width: isZh ? '40px' : '65px'
|
||||
}"
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,6 +95,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { SEARCH_MODE } from '../constants.js'
|
||||
import FilterPopover from './filterPopover.vue'
|
||||
|
||||
export default {
|
||||
|
@ -100,12 +128,31 @@ export default {
|
|||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isColumnSearch: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
searchMode: {
|
||||
type: String,
|
||||
default: SEARCH_MODE.NORMAL
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
SEARCH_MODE,
|
||||
searchModeList: [
|
||||
{
|
||||
value: SEARCH_MODE.NORMAL,
|
||||
label: 'cmdb.ciType.rowSearchMode'
|
||||
},
|
||||
{
|
||||
value: SEARCH_MODE.COLUMN,
|
||||
label: 'cmdb.ciType.columnSearchMode'
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isZh() {
|
||||
return this.$i18n.locale === 'zh'
|
||||
},
|
||||
|
||||
// 复制文字展示,与实际文本复制内容区别在于,未选择模型时不展示所有模型拼接数据
|
||||
copyText() {
|
||||
const regQ = /(?<=q=).+(?=&)|(?<=q=).+$/g
|
||||
|
@ -119,14 +166,15 @@ export default {
|
|||
textArray.push(exp)
|
||||
}
|
||||
if (this.searchValue) {
|
||||
let processedValue = this.searchValue
|
||||
if (this.isColumnSearch) {
|
||||
if (
|
||||
this.searchMode === SEARCH_MODE.COLUMN &&
|
||||
this.searchValue.includes('\n')
|
||||
) {
|
||||
const values = this.searchValue.split('\n').filter(v => v.trim())
|
||||
if (values.length) {
|
||||
processedValue = `(${values.join(';')})`
|
||||
}
|
||||
textArray.push(`(${values.join(';')})`)
|
||||
} else {
|
||||
textArray.push(`*${this.searchValue}*`)
|
||||
}
|
||||
textArray.push(`${!this.isColumnSearch ? '*' : ''}${processedValue}${!this.isColumnSearch ? '*' : ''}`)
|
||||
}
|
||||
|
||||
return textArray.length ? `q=${textArray.join(',')}` : ''
|
||||
|
@ -136,8 +184,8 @@ export default {
|
|||
updateAllAttributesList(value) {
|
||||
this.$emit('updateAllAttributesList', value)
|
||||
},
|
||||
saveCondition(isSubmit, searchType = 'normal') {
|
||||
this.$emit('saveCondition', isSubmit, searchType)
|
||||
saveCondition(isSubmit) {
|
||||
this.$emit('saveCondition', isSubmit)
|
||||
},
|
||||
handleChangeSearchValue(e) {
|
||||
const value = e.target.value
|
||||
|
@ -163,9 +211,21 @@ export default {
|
|||
ciTypeIds.push(...ids)
|
||||
})
|
||||
}
|
||||
const copyText = `${ciTypeIds?.length ? `_type:(${ciTypeIds.join(';')})` : ''}${exp ? `,${exp}` : ''}${
|
||||
searchValue ? `,${!this.isColumnSearch ? '*' : ''}${searchValue}${!this.isColumnSearch ? '*' : ''}` : ''
|
||||
}`
|
||||
|
||||
let copySearchValue = ''
|
||||
if (searchValue) {
|
||||
if (
|
||||
this.searchMode === SEARCH_MODE.COLUMN &&
|
||||
this.searchValue.includes('\n')
|
||||
) {
|
||||
const values = searchValue.split('\n').filter(v => v.trim())
|
||||
copySearchValue = `,(${values.join(';')})`
|
||||
} else {
|
||||
copySearchValue = `,*${searchValue}*`
|
||||
}
|
||||
}
|
||||
|
||||
const copyText = `${ciTypeIds?.length ? `_type:(${ciTypeIds.join(';')})` : ''}${exp ? `,${exp}` : ''}${copySearchValue}`
|
||||
|
||||
this.$copyText(copyText)
|
||||
.then(() => {
|
||||
|
@ -176,33 +236,8 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
toggleColumnSearch() {
|
||||
this.$emit('toggleSearchMode', !this.isColumnSearch)
|
||||
this.saveCondition(false, !this.isColumnSearch ? 'column' : 'normal')
|
||||
},
|
||||
|
||||
handleChangeColumnSearchValue(e) {
|
||||
const value = e.target.value
|
||||
this.changeFilter({
|
||||
name: 'searchValue',
|
||||
value
|
||||
})
|
||||
},
|
||||
|
||||
handlePressEnter(e) {
|
||||
if (this.isColumnSearch) {
|
||||
// 列搜索模式下,按下 Enter 键时阻止默认行为并插入换行符
|
||||
e.preventDefault()
|
||||
const value = this.searchValue || ''
|
||||
const cursorPosition = e.target.selectionStart
|
||||
const newValue = value.slice(0, cursorPosition) + '\n' + value.slice(cursorPosition)
|
||||
this.changeFilter({
|
||||
name: 'searchValue',
|
||||
value: newValue
|
||||
})
|
||||
} else {
|
||||
this.saveCondition(true, 'normal')
|
||||
}
|
||||
updateSearchMode(mode) {
|
||||
this.$emit('updateSearchMode', mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,115 +246,132 @@ export default {
|
|||
<style lang="less" scoped>
|
||||
.search-input {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.search-area {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
min-height: 48px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
|
||||
.search-input-component {
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
border-radius: 48px;
|
||||
width: 100%;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #d9d9d9;
|
||||
font-size: 14px;
|
||||
border-radius: 8px;
|
||||
|
||||
/deep/ input {
|
||||
height: 100%;
|
||||
padding-right: 40px;
|
||||
&:hover {
|
||||
/deep/ .ant-input {
|
||||
background-color: @primary-color_5;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .ant-input {
|
||||
border: none;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
border-radius: 48px;
|
||||
|
||||
&:focus {
|
||||
border: solid 1px @primary-color;
|
||||
background-color: #FFFFFF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-textarea-component {
|
||||
position: relative;
|
||||
|
||||
.search-textarea-icon-wrap {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 6px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
/deep/ .ant-input {
|
||||
background-color: @primary-color_5;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .ant-input {
|
||||
border: none;
|
||||
padding-left: 36px;
|
||||
resize: none;
|
||||
|
||||
&:focus {
|
||||
border: solid 1px @primary-color;
|
||||
background-color: #FFFFFF !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #2F54EB;
|
||||
color: @primary-color;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.textarea-wrapper {
|
||||
flex-grow: 1;
|
||||
.operation-area {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
height: 48px;
|
||||
transform: translateX(100%);
|
||||
|
||||
.textarea-container {
|
||||
.search-mode-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 32px;
|
||||
background-color: @primary-color_3;
|
||||
border-radius: 32px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-height: 200px;
|
||||
padding: 0 4px;
|
||||
margin-left: 14px;
|
||||
cursor: pointer;
|
||||
|
||||
.column-search-component {
|
||||
width: 100%;
|
||||
max-height: 200px;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #d9d9d9;
|
||||
font-size: 14px;
|
||||
border-radius: 8px;
|
||||
padding-right: 35px;
|
||||
resize: none;
|
||||
transition: all 0.3s;
|
||||
&-item {
|
||||
height: 24px;
|
||||
width: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: @text-color_2;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
|
||||
&:hover, &:focus {
|
||||
border-color: #40a9ff;
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||||
&-active {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
&-slide {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 12px;
|
||||
color: #2F54EB;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: left 0.2s;
|
||||
border-radius: 24px;
|
||||
background-color: #FFFFFF;
|
||||
height: 24px;
|
||||
top: 4px;
|
||||
width: 40px;
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operation-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.column-search-btn {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 13px;
|
||||
cursor: pointer;
|
||||
|
||||
&-icon {
|
||||
color: #2F54EB;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #2F54EB;
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.expression-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 20px;
|
||||
max-width: 30%;
|
||||
max-width: 100%;
|
||||
width: fit-content;
|
||||
margin-top: 8px;
|
||||
|
||||
&-text {
|
||||
width: 100%;
|
||||
|
@ -335,16 +387,9 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.search-input-component,
|
||||
.column-search-component {
|
||||
&:hover {
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: #40a9ff;
|
||||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||||
outline: none;
|
||||
&-after {
|
||||
.search-area {
|
||||
max-width: 420px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export const SEARCH_MODE = {
|
||||
NORMAL: 'normal',
|
||||
COLUMN: 'column'
|
||||
}
|
|
@ -15,11 +15,11 @@
|
|||
:searchValue="searchValue"
|
||||
:selectCITypeIds="selectCITypeIds"
|
||||
:expression="expression"
|
||||
:isColumnSearch="currentSearchType === 'column'"
|
||||
:searchMode="currentSearchMode"
|
||||
@changeFilter="changeFilter"
|
||||
@updateAllAttributesList="updateAllAttributesList"
|
||||
@saveCondition="saveCondition"
|
||||
@toggleSearchMode="handleToggleSearchMode"
|
||||
@updateSearchMode="updateSearchMode"
|
||||
/>
|
||||
<HistoryList
|
||||
:recentList="recentList"
|
||||
|
@ -48,11 +48,11 @@
|
|||
:searchValue="searchValue"
|
||||
:selectCITypeIds="selectCITypeIds"
|
||||
:expression="expression"
|
||||
:isColumnSearch="currentSearchType === 'column'"
|
||||
:searchMode="currentSearchMode"
|
||||
@changeFilter="changeFilter"
|
||||
@updateAllAttributesList="updateAllAttributesList"
|
||||
@saveCondition="saveCondition"
|
||||
@toggleSearchMode="handleToggleSearchMode"
|
||||
@updateSearchMode="updateSearchMode"
|
||||
/>
|
||||
<HistoryList
|
||||
:recentList="recentList"
|
||||
|
@ -127,6 +127,7 @@ import { getPreferenceSearch, savePreferenceSearch, getSubscribeAttributes, dele
|
|||
import { searchAttributes, getCITypeAttributesByTypeIds } from '@/modules/cmdb/api/CITypeAttr'
|
||||
import { searchCI } from '@/modules/cmdb/api/ci'
|
||||
import { getCITypes } from '@/modules/cmdb/api/CIType'
|
||||
import { SEARCH_MODE } from './constants.js'
|
||||
|
||||
import SearchInput from './components/searchInput.vue'
|
||||
import HistoryList from './components/historyList.vue'
|
||||
|
@ -176,7 +177,7 @@ export default {
|
|||
showInstanceDetail: false,
|
||||
detailCIId: -1,
|
||||
detailCITypeId: -1,
|
||||
currentSearchType: 'normal',
|
||||
currentSearchMode: SEARCH_MODE.NORMAL,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -245,9 +246,7 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
async saveCondition(isSubmit, searchType = 'normal') {
|
||||
this.currentSearchType = searchType
|
||||
|
||||
async saveCondition(isSubmit) {
|
||||
if (
|
||||
this.searchValue ||
|
||||
this.expression ||
|
||||
|
@ -261,7 +260,7 @@ export default {
|
|||
option.searchValue === this.searchValue &&
|
||||
option.expression === this.expression &&
|
||||
_.isEqual(option.ciTypeIds, this.selectCITypeIds) &&
|
||||
option.searchType === this.currentSearchType
|
||||
option.searchMode === this.currentSearchMode
|
||||
) {
|
||||
needDeleteList.push(item.id)
|
||||
} else {
|
||||
|
@ -288,7 +287,7 @@ export default {
|
|||
expression: this.expression,
|
||||
ciTypeIds: this.selectCITypeIds,
|
||||
ciTypeNames,
|
||||
searchType: this.currentSearchType
|
||||
searchMode: this.currentSearchMode
|
||||
},
|
||||
name: '__recent__'
|
||||
})
|
||||
|
@ -299,7 +298,7 @@ export default {
|
|||
this.isSearch = true
|
||||
this.currentPage = 1
|
||||
this.hideDetail()
|
||||
this.loadInstance(this.currentSearchType)
|
||||
this.loadInstance()
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -316,19 +315,11 @@ export default {
|
|||
this.getRecentList()
|
||||
},
|
||||
|
||||
async loadInstance(searchType = 'normal') {
|
||||
const { selectCITypeIds, expression } = this
|
||||
let { searchValue } = this
|
||||
async loadInstance() {
|
||||
const { selectCITypeIds, expression, searchValue } = this
|
||||
const regQ = /(?<=q=).+(?=&)|(?<=q=).+$/g
|
||||
const exp = expression.match(regQ) ? expression.match(regQ)[0] : null
|
||||
|
||||
if (searchType === 'column' && searchValue) {
|
||||
const values = searchValue.split('\n').filter(v => v.trim())
|
||||
if (values.length) {
|
||||
searchValue = `(${values.join(';')})`
|
||||
}
|
||||
}
|
||||
|
||||
const ciTypeIds = [...selectCITypeIds]
|
||||
if (!ciTypeIds.length) {
|
||||
this.CITypeGroup.forEach((item) => {
|
||||
|
@ -337,10 +328,21 @@ export default {
|
|||
})
|
||||
}
|
||||
|
||||
let querySearchValue = ''
|
||||
if (searchValue) {
|
||||
if (
|
||||
this.currentSearchMode === SEARCH_MODE.COLUMN &&
|
||||
searchValue.includes('\n')
|
||||
) {
|
||||
const values = searchValue.split('\n').filter(v => v.trim())
|
||||
querySearchValue = `,(${values.join(';')})`
|
||||
} else {
|
||||
querySearchValue = `,*${searchValue}*`
|
||||
}
|
||||
}
|
||||
|
||||
const res = await searchCI({
|
||||
q: `${ciTypeIds?.length ? `_type:(${ciTypeIds.join(';')})` : ''}${exp ? `,${exp}` : ''}${
|
||||
searchValue ? `,${searchType === 'normal' ? '*' : ''}${searchValue}${searchType === 'normal' ? '*' : ''}` : ''
|
||||
}`,
|
||||
q: `${ciTypeIds?.length ? `_type:(${ciTypeIds.join(';')})` : ''}${exp ? `,${exp}` : ''}${querySearchValue}`,
|
||||
count: this.pageSize,
|
||||
page: this.currentPage,
|
||||
sort: '_type'
|
||||
|
@ -406,6 +408,7 @@ export default {
|
|||
}
|
||||
this.ciTabList = ciTabList
|
||||
|
||||
// 处理引用属性
|
||||
const allAttr = []
|
||||
subscribedRes.map((item) => {
|
||||
allAttr.push(...item.attributes)
|
||||
|
@ -493,21 +496,21 @@ export default {
|
|||
this.searchValue = data?.searchValue || ''
|
||||
this.expression = data?.expression || ''
|
||||
this.selectCITypeIds = data?.ciTypeIds || []
|
||||
this.currentSearchType = data?.searchType || 'normal'
|
||||
this.currentSearchMode = data?.searchMode || 'normal'
|
||||
|
||||
this.hideDetail()
|
||||
this.loadInstance(this.currentSearchType)
|
||||
this.loadInstance()
|
||||
},
|
||||
|
||||
handlePageSizeChange(_, pageSize) {
|
||||
this.pageSize = pageSize
|
||||
this.currentPage = 1
|
||||
this.loadInstance(this.currentSearchType)
|
||||
this.loadInstance()
|
||||
},
|
||||
|
||||
changePage(page) {
|
||||
this.currentPage = page
|
||||
this.loadInstance(this.currentSearchType)
|
||||
this.loadInstance()
|
||||
},
|
||||
|
||||
changeFilter(data) {
|
||||
|
@ -552,8 +555,8 @@ export default {
|
|||
this.showDetail(data)
|
||||
},
|
||||
|
||||
handleToggleSearchMode(isColumn) {
|
||||
this.currentSearchType = isColumn ? 'column' : 'normal'
|
||||
updateSearchMode(mode) {
|
||||
this.currentSearchMode = mode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -567,7 +570,7 @@ export default {
|
|||
|
||||
&-before {
|
||||
width: 100%;
|
||||
max-width: 725px;
|
||||
max-width: 718px;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
padding-top: 100px;
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
:type="topo.icon.split('$$')[0]"
|
||||
/>
|
||||
</template>
|
||||
<span :style="{ color: '#2f54eb' }" v-else>{{ topo.name[0].toUpperCase() }}</span>
|
||||
<span class="primary-color" v-else>{{ topo.name[0].toUpperCase() }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<span class="topo-left-detail-title">{{ topo.alias || topo.name }}</span>
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
:type="ciType.icon.split('$$')[0]"
|
||||
/>
|
||||
</template>
|
||||
<span :style="{ color: '#2f54eb' }" v-else>{{ ciType.name[0].toUpperCase() }}</span>
|
||||
<span class="primary-color" v-else>{{ ciType.name[0].toUpperCase() }}</span>
|
||||
</span>
|
||||
<span class="tree-views-left-header-name">{{ ciType.alias || ciType.name }}</span>
|
||||
<div class="actions">
|
||||
|
|
|
@ -824,6 +824,10 @@ body {
|
|||
color: @primary-color !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown__item.hover {
|
||||
background-color: @primary-color_5;
|
||||
}
|
||||
|
||||
.ant-tabs-nav .ant-tabs-tab {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
@ -969,7 +973,7 @@ body {
|
|||
// 白色背景
|
||||
.custom-treeselect-white {
|
||||
.custom-vue-treeselect__control(
|
||||
#fff,
|
||||
~'#fff !important',
|
||||
1px solid #d9d9d9,
|
||||
none,
|
||||
@primary-color
|
||||
|
@ -1064,7 +1068,7 @@ body {
|
|||
// }
|
||||
.vxe-body--row {
|
||||
&.row--stripe {
|
||||
background-color: rgba(240, 245, 255, 0.4) !important;
|
||||
background-color: @primary-color_6 !important;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1) !important;
|
||||
border-radius: 5px !important;
|
||||
> td {
|
||||
|
@ -1097,6 +1101,7 @@ body {
|
|||
|
||||
&:focus {
|
||||
background-color: @primary-color_7;
|
||||
border: solid 1px @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1110,15 +1115,24 @@ body {
|
|||
color: #333;
|
||||
cursor: default;
|
||||
}
|
||||
.ant-input:focus,
|
||||
.ant-input-number:focus,
|
||||
.ant-input-number-focused {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.ant-pagination-options-quick-jumper input:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
// vxe-table checkbox 选中 highlight
|
||||
.vxe-table--render-default .vxe-body--row.row--checked,
|
||||
.vxe-table--render-default .vxe-body--row.row--radio {
|
||||
background: aliceblue !important;
|
||||
background: @primary-color_5 !important;
|
||||
}
|
||||
.vxe-table--render-default .vxe-body--row.row--hover.row--checked,
|
||||
.vxe-table--render-default .vxe-body--row.row--hover.row--radio {
|
||||
background: lightskyblue !important;
|
||||
background: @primary-color_4 !important;
|
||||
}
|
||||
|
||||
// vxe-table 颜色
|
||||
|
@ -1179,6 +1193,15 @@ body {
|
|||
border-color: @primary-color !important;
|
||||
}
|
||||
|
||||
.vxe-table--render-default .vxe-body--row.row--hover,
|
||||
.vxe-table--render-default .vxe-body--row.row--hover.row--stripe {
|
||||
background-color: @primary-color_7;
|
||||
}
|
||||
|
||||
.vxe-select-option:not(.is--disabled).is--hover {
|
||||
background-color: @primary-color_5;
|
||||
}
|
||||
|
||||
//批量操作
|
||||
.ops-list-batch-action {
|
||||
display: inline-block;
|
||||
|
@ -1262,7 +1285,7 @@ body {
|
|||
}
|
||||
|
||||
.ant-btn-primary:not(.ant-btn-background-ghost) {
|
||||
.btn-wave-hover(#3F75FF);
|
||||
.btn-wave-hover(@primary-color_9);
|
||||
}
|
||||
|
||||
// button
|
||||
|
@ -1296,6 +1319,35 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.ops-select-bg {
|
||||
.ant-select-selection {
|
||||
background-color: @primary-color_7;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.ant-select-selection {
|
||||
background-color: @primary-color_5;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-select-focused {
|
||||
.ant-select-selection {
|
||||
background-color: @primary-color_7;
|
||||
border: solid 1px @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-select-selection {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
// date picker
|
||||
.ant-calendar-today .ant-calendar-date {
|
||||
color: @primary-color;
|
||||
border-color: @primary-color;
|
||||
}
|
||||
|
||||
//dropdown
|
||||
.ops-dropdown {
|
||||
.ant-dropdown-menu-item:hover,
|
||||
|
@ -1305,6 +1357,11 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
// radio
|
||||
.ant-radio-input:focus + .ant-radio-inner {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
//modal
|
||||
.ant-modal-content {
|
||||
.ant-modal-close-x {
|
||||
|
@ -1396,6 +1453,14 @@ body {
|
|||
.el-input-number--small .el-input-number__decrease,
|
||||
.el-input-number--small .el-input-number__increase {
|
||||
width: 28px;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
|
||||
&:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled) {
|
||||
border-color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-input-number--small {
|
||||
|
@ -1466,3 +1531,16 @@ body {
|
|||
.ant-form-explain{
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.ant-message-info .anticon,
|
||||
.ant-message-loading .anticon {
|
||||
color: @primary-color_9;
|
||||
}
|
||||
|
||||
.primary-color {
|
||||
color: @primary-color !important;
|
||||
}
|
||||
|
||||
.primary-bg-color {
|
||||
background-color: @primary-color;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
@primary-color_6: #f9fbff;
|
||||
@primary-color_7: #f7f8fa;
|
||||
@primary-color_8: #b1c9ff;
|
||||
@primary-color_9: #3F75FF;
|
||||
|
||||
@link-color: @primary-color;
|
||||
|
||||
|
@ -73,7 +74,8 @@
|
|||
|
||||
.btn-wave-hover(
|
||||
@hoverBgColor,
|
||||
@bgZIndex: 0
|
||||
@bgZIndex: 0,
|
||||
@duration: 0.3s
|
||||
) {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
@ -99,10 +101,10 @@
|
|||
transform: scale(0) translate(-50%, -50%);
|
||||
transform-origin: left top;
|
||||
|
||||
-webkit-transition: -webkit-transform 0.3s ease-out;
|
||||
transition: -webkit-transform 0.3s ease-out;
|
||||
transition: transform 0.3s ease-out;
|
||||
transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;
|
||||
-webkit-transition: -webkit-transform @duration ease-out;
|
||||
transition: -webkit-transform @duration ease-out;
|
||||
transition: transform @duration ease-out;
|
||||
transition: transform @duration ease-out, -webkit-transform @duration ease-out;
|
||||
}
|
||||
|
||||
&:not([disabled]):hover {
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
/>
|
||||
</div>
|
||||
<!-- 筛选框 -->
|
||||
<div class="Screening-box" v-if="activeGroupIndex === 1" style="background-color: rgb(240, 245, 255)">
|
||||
<div class="Screening-box" v-if="activeGroupIndex === 1">
|
||||
<a-popover
|
||||
@visibleChange="visibleChange"
|
||||
trigger="click"
|
||||
|
@ -1166,7 +1166,7 @@ export default {
|
|||
.Screening-box {
|
||||
margin-left: 10px;
|
||||
display: inline-block;
|
||||
.ops_display_wrapper(#fff);
|
||||
.ops_display_wrapper(@primary-color_5);
|
||||
.screening-box-scene-icon {
|
||||
color: @primary-color;
|
||||
font-size: 12px;
|
||||
|
|
|
@ -340,7 +340,7 @@ export default {
|
|||
& > a {
|
||||
padding: 2px 8px;
|
||||
&:hover {
|
||||
background-color: #f0faff;
|
||||
background-color: @primary-color_5;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue