Merge pull request #652 from veops/dev_ui_241211

feat: update style
This commit is contained in:
Leo Song 2024-12-11 15:48:23 +08:00 committed by GitHub
commit 6bd3de8951
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
39 changed files with 1010 additions and 774 deletions

View File

@ -11,10 +11,19 @@
.ant-input { .ant-input {
box-shadow: none; box-shadow: none;
border: none;
background-color: #F7F8FA;
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
border-radius: 30px;
&:focus {
border: solid 1px #B1C9FF;
}
}
.cmdb-side-menu-search-focused {
.ant-input {
border: solid 1px #B1C9FF;
}
} }
.ant-input-suffix { .ant-input-suffix {

View File

@ -92,7 +92,7 @@ export default {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
this.$confirm({ this.$confirm({
title: this.$t('alert'), title: this.$t('warning'),
content: this.$t('cmdb.preference.confirmcancelSub2', { name: menu.meta.title }), content: this.$t('cmdb.preference.confirmcancelSub2', { name: menu.meta.title }),
onOk() { onOk() {
const citypeId = menu.meta.typeId const citypeId = menu.meta.typeId
@ -313,10 +313,7 @@ export default {
<Item class={styles['cmdb-side-menu-search']}> <Item class={styles['cmdb-side-menu-search']}>
<a-input <a-input
ref="cmdbSideMenuSearchInputRef" ref="cmdbSideMenuSearchInputRef"
class={styles['cmdb-side-menu-search-input']} class={`ops-input ${this.$route.name === 'cmdb_resource_search' ? 'cmdb-side-menu-search-focused' : ''}`}
style={{
border: this.$route.name === 'cmdb_resource_search' ? 'solid 1px #B1C9FF' : ''
}}
placeholder={this.$t('cmdbSearch')} placeholder={this.$t('cmdbSearch')}
onPressEnter={(e) => { onPressEnter={(e) => {
this.jumpCMDBSearch(e.target.value) this.jumpCMDBSearch(e.target.value)

View File

@ -1,121 +1,121 @@
<template> <template>
<vxe-table v-bind="$attrs" v-on="new$listeners" ref="xTable"> <vxe-table v-bind="$attrs" v-on="new$listeners" ref="xTable">
<slot></slot> <slot></slot>
<template #empty> <template #empty>
<slot name="empty"> <slot name="empty">
<div :style="{ paddingTop: '10px' }"> <div :style="{ paddingTop: '10px' }">
<img :style="{ width: '140px', height: '90px' }" :src="require('@/assets/data_empty.png')" /> <img :style="{ width: '140px', height: '120px' }" :src="require('@/assets/data_empty.png')" />
<div>{{ $t('noData') }}</div> <div>{{ $t('noData') }}</div>
</div> </div>
</slot> </slot>
</template> </template>
<template #loading> <template #loading>
<slot name="loading"></slot> <slot name="loading"></slot>
</template> </template>
</vxe-table> </vxe-table>
</template> </template>
<script> <script>
import _ from 'lodash' import _ from 'lodash'
// 该组件使用方法与vxe-table一致但调用它的方法时需先调用getVxetableRef()获取到vxe-table实体 // 该组件使用方法与vxe-table一致但调用它的方法时需先调用getVxetableRef()获取到vxe-table实体
export default { export default {
name: 'OpsTable', name: 'OpsTable',
data() { data() {
return { return {
// isShifting: false, // isShifting: false,
// lastIndex: -1, // lastIndex: -1,
lastSelected: [], lastSelected: [],
currentSelected: [], currentSelected: [],
} }
}, },
computed: { computed: {
new$listeners() { new$listeners() {
if (!Object.keys(this.$listeners).length) { if (!Object.keys(this.$listeners).length) {
return this.$listeners return this.$listeners
} }
return Object.assign(this.$listeners, { return Object.assign(this.$listeners, {
// 在这里覆盖原有的change事件 // 在这里覆盖原有的change事件
// 'checkbox-change': this.selectChangeEvent, // 'checkbox-change': this.selectChangeEvent,
'checkbox-range-change': this.checkboxRangeChange, 'checkbox-range-change': this.checkboxRangeChange,
'checkbox-range-start': this.checkboxRangeStart, 'checkbox-range-start': this.checkboxRangeStart,
'checkbox-range-end': this.checkboxRangeEnd, 'checkbox-range-end': this.checkboxRangeEnd,
}) })
}, },
}, },
mounted() { mounted() {
// window.onkeydown = (e) => { // window.onkeydown = (e) => {
// if (e.key === 'Shift') { // if (e.key === 'Shift') {
// this.isShifting = true // this.isShifting = true
// } // }
// } // }
// window.onkeyup = (e) => { // window.onkeyup = (e) => {
// if (e.key === 'Shift') { // if (e.key === 'Shift') {
// this.isShifting = false // this.isShifting = false
// this.lastIndex = -1 // this.lastIndex = -1
// } // }
// } // }
}, },
beforeDestroy() { beforeDestroy() {
// window.onkeydown = '' // window.onkeydown = ''
// window.onkeyup = '' // window.onkeyup = ''
}, },
methods: { methods: {
getVxetableRef() { getVxetableRef() {
return this.$refs.xTable return this.$refs.xTable
}, },
// selectChangeEvent(e) { // selectChangeEvent(e) {
// const xTable = this.$refs.xTable // const xTable = this.$refs.xTable
// const { lastIndex } = this // const { lastIndex } = this
// const currentIndex = e.rowIndex // const currentIndex = e.rowIndex
// const { tableData } = xTable.getTableData() // const { tableData } = xTable.getTableData()
// if (lastIndex > -1 && this.isShifting) { // if (lastIndex > -1 && this.isShifting) {
// let start = lastIndex // let start = lastIndex
// let end = currentIndex // let end = currentIndex
// if (lastIndex > currentIndex) { // if (lastIndex > currentIndex) {
// start = currentIndex // start = currentIndex
// end = lastIndex // end = lastIndex
// } // }
// const rangeData = tableData.slice(start, end + 1) // const rangeData = tableData.slice(start, end + 1)
// xTable.setCheckboxRow(rangeData, true) // xTable.setCheckboxRow(rangeData, true)
// } // }
// this.lastIndex = currentIndex // this.lastIndex = currentIndex
// this.$emit('checkbox-change', { ...e, records: xTable.getCheckboxRecords() }) // this.$emit('checkbox-change', { ...e, records: xTable.getCheckboxRecords() })
// }, // },
checkboxRangeStart(e) { checkboxRangeStart(e) {
const xTable = this.$refs.xTable const xTable = this.$refs.xTable
const lastSelected = xTable.getCheckboxRecords() const lastSelected = xTable.getCheckboxRecords()
const selectedReserve = xTable.getCheckboxReserveRecords() const selectedReserve = xTable.getCheckboxReserveRecords()
this.lastSelected = [...lastSelected, ...selectedReserve] this.lastSelected = [...lastSelected, ...selectedReserve]
this.$emit('checkbox-range-start', e) this.$emit('checkbox-range-start', e)
}, },
checkboxRangeChange(e) { checkboxRangeChange(e) {
const xTable = this.$refs.xTable const xTable = this.$refs.xTable
xTable.setCheckboxRow(this.lastSelected, true) xTable.setCheckboxRow(this.lastSelected, true)
this.currentSelected = e.records this.currentSelected = e.records
// this.lastSelected = [...new Set([...this.lastSelected, ...e.records])] // this.lastSelected = [...new Set([...this.lastSelected, ...e.records])]
this.$emit('checkbox-range-change', { this.$emit('checkbox-range-change', {
...e, ...e,
records: [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()], records: [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()],
}) })
}, },
checkboxRangeEnd(e) { checkboxRangeEnd(e) {
const xTable = this.$refs.xTable const xTable = this.$refs.xTable
const isAllSelected = this.currentSelected.every((item) => { const isAllSelected = this.currentSelected.every((item) => {
const _idx = this.lastSelected.findIndex((ele) => _.isEqual(ele, item)) const _idx = this.lastSelected.findIndex((ele) => _.isEqual(ele, item))
return _idx > -1 return _idx > -1
}) })
if (isAllSelected) { if (isAllSelected) {
xTable.setCheckboxRow(this.currentSelected, false) xTable.setCheckboxRow(this.currentSelected, false)
} }
this.currentSelected = [] this.currentSelected = []
this.lastSelected = [] this.lastSelected = []
this.$emit('checkbox-range-end', { this.$emit('checkbox-range-end', {
...e, ...e,
records: [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()], records: [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()],
}) })
}, },
}, },
} }
</script> </script>
<style lang="less"></style> <style lang="less"></style>

View File

@ -195,11 +195,11 @@ export default {
background-color: #fff; background-color: #fff;
height: calc(100vh - 64px); height: calc(100vh - 64px);
margin-bottom: -24px; margin-bottom: -24px;
padding: 24px; padding: 20px;
.acl-resource-types-header { .acl-resource-types-header {
width: 100%; width: 100%;
display: inline-flex; display: inline-flex;
margin-bottom: 15px; margin-bottom: 20px;
align-items: center; align-items: center;
} }
} }

View File

@ -358,11 +358,11 @@ export default {
background-color: #fff; background-color: #fff;
height: calc(100vh - 64px); height: calc(100vh - 64px);
margin-bottom: -24px; margin-bottom: -24px;
padding: 12px 24px 24px 24px; padding: 8px 20px 20px 20px;
.acl-resources-header { .acl-resources-header {
width: 100%; width: 100%;
display: inline-flex; display: inline-flex;
margin-bottom: 15px; margin-bottom: 20px;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
.ant-switch { .ant-switch {

View File

@ -291,11 +291,11 @@ export default {
background-color: #fff; background-color: #fff;
height: calc(100vh - 64px); height: calc(100vh - 64px);
margin-bottom: -24px; margin-bottom: -24px;
padding: 24px; padding: 20px;
.acl-roles-header { .acl-roles-header {
width: 100%; width: 100%;
display: inline-flex; display: inline-flex;
margin-bottom: 15px; margin-bottom: 20px;
align-items: center; align-items: center;
.ant-checkbox-wrapper { .ant-checkbox-wrapper {
margin-left: auto; margin-left: auto;

View File

@ -326,11 +326,11 @@ export default {
background-color: #fff; background-color: #fff;
height: calc(100vh - 64px); height: calc(100vh - 64px);
margin-bottom: -24px; margin-bottom: -24px;
padding: 24px; padding: 20px;
.acl-trigger-header { .acl-trigger-header {
width: 100%; width: 100%;
display: inline-flex; display: inline-flex;
margin-bottom: 15px; margin-bottom: 20px;
align-items: center; align-items: center;
} }
} }

View File

@ -1,371 +1,370 @@
<template> <template>
<div class="cmdb-grant" :style="{ }"> <div class="cmdb-grant" :style="{ }">
<template v-if="cmdbGrantType.includes('ci_type')"> <template v-if="cmdbGrantType.includes('ci_type')">
<div class="cmdb-grant-title">{{ $t('cmdb.components.ciTypeGrant') }}</div> <div class="cmdb-grant-title">{{ $t('cmdb.components.ciTypeGrant') }}</div>
<CiTypeGrant <CiTypeGrant
:CITypeId="CITypeId" :CITypeId="CITypeId"
:tableData="tableData" :tableData="tableData"
grantType="ci_type" grantType="ci_type"
@grantDepart="grantDepart" @grantDepart="grantDepart"
@grantRole="grantRole" @grantRole="grantRole"
@getTableData="getTableData" @getTableData="getTableData"
ref="grant_ci_type" ref="grant_ci_type"
:addedRids="addedRids" :addedRids="addedRids"
/> />
</template> </template>
<template <template
v-if=" v-if="
cmdbGrantType.includes('ci_type,ci') || (cmdbGrantType.includes('ci') && !cmdbGrantType.includes('ci_type')) cmdbGrantType.includes('ci_type,ci') || (cmdbGrantType.includes('ci') && !cmdbGrantType.includes('ci_type'))
" "
> >
<div class="cmdb-grant-title">{{ $t('cmdb.components.ciGrant') }}</div> <div class="cmdb-grant-title">{{ $t('cmdb.components.ciGrant') }}</div>
<CiTypeGrant <CiTypeGrant
:CITypeId="CITypeId" :CITypeId="CITypeId"
:tableData="tableData" :tableData="tableData"
grantType="ci" grantType="ci"
@grantDepart="grantDepart" @grantDepart="grantDepart"
@grantRole="grantRole" @grantRole="grantRole"
@getTableData="getTableData" @getTableData="getTableData"
@openReadGrantModal="openReadGrantModal" @openReadGrantModal="openReadGrantModal"
ref="grant_ci" ref="grant_ci"
:addedRids="addedRids" :addedRids="addedRids"
/> />
</template> </template>
<template v-if="cmdbGrantType.includes('type_relation')"> <template v-if="cmdbGrantType.includes('type_relation')">
<div class="cmdb-grant-title">{{ $t('cmdb.components.relationGrant') }}</div> <div class="cmdb-grant-title">{{ $t('cmdb.components.relationGrant') }}</div>
<TypeRelationGrant <TypeRelationGrant
:typeRelationIds="typeRelationIds" :typeRelationIds="typeRelationIds"
:tableData="tableData" :tableData="tableData"
grantType="type_relation" grantType="type_relation"
@grantDepart="grantDepart" @grantDepart="grantDepart"
@grantRole="grantRole" @grantRole="grantRole"
@getTableData="getTableData" @getTableData="getTableData"
ref="grant_type_relation" ref="grant_type_relation"
:addedRids="addedRids" :addedRids="addedRids"
/> />
</template> </template>
<template v-if="cmdbGrantType.includes('relation_view')"> <template v-if="cmdbGrantType.includes('relation_view')">
<div class="cmdb-grant-title">{{ resourceTypeName }}{{ $t('cmdb.components.perm') }}</div> <div class="cmdb-grant-title">{{ resourceTypeName }}{{ $t('cmdb.components.perm') }}</div>
<RelationViewGrant <RelationViewGrant
:resourceTypeName="resourceTypeName" :resourceTypeName="resourceTypeName"
:tableData="tableData" :tableData="tableData"
grantType="relation_view" grantType="relation_view"
@grantDepart="grantDepart" @grantDepart="grantDepart"
@grantRole="grantRole" @grantRole="grantRole"
@getTableData="getTableData" @getTableData="getTableData"
ref="grant_relation_view" ref="grant_relation_view"
:addedRids="addedRids" :addedRids="addedRids"
/> />
</template> </template>
<template v-if="cmdbGrantType.includes('TopologyView')"> <template v-if="cmdbGrantType.includes('TopologyView')">
<div class="cmdb-grant-title">{{ resourceTypeName }}{{ $t('cmdb.components.perm') }}</div> <div class="cmdb-grant-title">{{ resourceTypeName }}{{ $t('cmdb.components.perm') }}</div>
<TopologyViewGrant <TopologyViewGrant
:resourceTypeName="resourceTypeName" :resourceTypeName="resourceTypeName"
:tableData="tableData" :tableData="tableData"
:viewId="CITypeId" :viewId="CITypeId"
grantType="TopologyView" grantType="TopologyView"
@grantDepart="grantDepart" @grantDepart="grantDepart"
@grantRole="grantRole" @grantRole="grantRole"
@getTableData="getTableData" @getTableData="getTableData"
ref="grantTopologyView" ref="grantTopologyView"
:addedRids="addedRids" :addedRids="addedRids"
/> />
</template> </template>
<GrantModal ref="grantModal" @handleOk="handleOk" /> <GrantModal ref="grantModal" @handleOk="handleOk" />
<ReadGrantModal ref="readGrantModal" :CITypeId="CITypeId" @updateTableDataRead="updateTableDataRead" /> <ReadGrantModal ref="readGrantModal" :CITypeId="CITypeId" @updateTableDataRead="updateTableDataRead" />
</div> </div>
</template> </template>
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import CiTypeGrant from './ciTypeGrant.vue' import CiTypeGrant from './ciTypeGrant.vue'
import TypeRelationGrant from './typeRelationGrant.vue' import TypeRelationGrant from './typeRelationGrant.vue'
import { searchResource } from '@/modules/acl/api/resource' import { searchResource } from '@/modules/acl/api/resource'
import { getResourcePerms } from '@/modules/acl/api/permission' import { getResourcePerms } from '@/modules/acl/api/permission'
import GrantModal from './grantModal.vue' import GrantModal from './grantModal.vue'
import ReadGrantModal from './readGrantModal' import ReadGrantModal from './readGrantModal'
import RelationViewGrant from './relationViewGrant.vue' import RelationViewGrant from './relationViewGrant.vue'
import TopologyViewGrant from './topologyViewGrant.vue' import TopologyViewGrant from './topologyViewGrant.vue'
import { getCITypeGroupById, ciTypeFilterPermissions } from '../../api/CIType' import { getCITypeGroupById, ciTypeFilterPermissions } from '../../api/CIType'
export default { export default {
name: 'GrantComp', name: 'GrantComp',
components: { CiTypeGrant, TypeRelationGrant, RelationViewGrant, TopologyViewGrant, GrantModal, ReadGrantModal }, components: { CiTypeGrant, TypeRelationGrant, RelationViewGrant, TopologyViewGrant, GrantModal, ReadGrantModal },
props: { props: {
CITypeId: { CITypeId: {
type: Number, type: Number,
default: null, default: null,
}, },
resourceTypeName: { resourceTypeName: {
type: String, type: String,
default: '', default: '',
}, },
resourceType: { resourceType: {
type: String, type: String,
default: 'CIType', default: 'CIType',
}, },
app_id: { app_id: {
type: String, type: String,
default: 'cmdb', default: 'cmdb',
}, },
cmdbGrantType: { cmdbGrantType: {
type: String, type: String,
default: 'ci_type,ci', default: 'ci_type,ci',
}, },
typeRelationIds: { typeRelationIds: {
type: Array, type: Array,
default: null, default: null,
}, },
isModal: { isModal: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
}, },
inject: ['resource_type'], inject: ['resource_type'],
data() { data() {
return { return {
tableData: [], tableData: [],
grantType: '', grantType: '',
resource_id: null, resource_id: null,
attrGroup: [], attrGroup: [],
filerPerimissions: {}, filerPerimissions: {},
loading: false, loading: false,
addedRids: [], // added rid this time addedRids: [], // added rid this time
} }
}, },
computed: { computed: {
...mapState({ ...mapState({
allEmployees: (state) => state.user.allEmployees, allEmployees: (state) => state.user.allEmployees,
allDepartments: (state) => state.user.allDepartments, allDepartments: (state) => state.user.allDepartments,
}), }),
child_resource_type() { child_resource_type() {
return this.resource_type() return this.resource_type()
}, },
windowHeight() { windowHeight() {
return this.$store.state.windowHeight return this.$store.state.windowHeight
}, },
}, },
provide() { provide() {
return { return {
attrGroup: () => { attrGroup: () => {
return this.attrGroup return this.attrGroup
}, },
filerPerimissions: () => { filerPerimissions: () => {
return this.filerPerimissions return this.filerPerimissions
}, },
loading: () => { loading: () => {
return this.loading return this.loading
}, },
isModal: this.isModal, isModal: this.isModal,
} }
}, },
watch: { watch: {
resourceTypeName: { resourceTypeName: {
immediate: true, immediate: true,
handler() { handler() {
this.init() this.init()
}, },
}, },
CITypeId: { CITypeId: {
immediate: true, immediate: true,
handler() { handler() {
if (this.CITypeId && this.cmdbGrantType.includes('ci')) { if (this.CITypeId && this.cmdbGrantType.includes('ci')) {
this.getFilterPermissions() this.getFilterPermissions()
this.getAttrGroup() this.getAttrGroup()
} }
}, },
}, },
}, },
mounted() {}, mounted() {},
methods: { methods: {
getAttrGroup() { getAttrGroup() {
getCITypeGroupById(this.CITypeId, { need_other: true }).then((res) => { getCITypeGroupById(this.CITypeId, { need_other: true }).then((res) => {
this.attrGroup = res this.attrGroup = res
}) })
}, },
getFilterPermissions() { getFilterPermissions() {
ciTypeFilterPermissions(this.CITypeId).then((res) => { ciTypeFilterPermissions(this.CITypeId).then((res) => {
this.filerPerimissions = res this.filerPerimissions = res
}) })
}, },
async init() { async init() {
const _find = this.child_resource_type.groups.find((item) => item.name === this.resourceType) const _find = this.child_resource_type.groups.find((item) => item.name === this.resourceType)
const resource_type_id = _find?.id ?? 0 const resource_type_id = _find?.id ?? 0
const res = await searchResource({ const res = await searchResource({
app_id: this.app_id, app_id: this.app_id,
resource_type_id, resource_type_id,
page_size: 9999, page_size: 9999,
}) })
const _tempFind = res.resources.find((item) => item.name === this.resourceTypeName) const _tempFind = res.resources.find((item) => item.name === this.resourceTypeName)
console.log(this.resourceTypeName) console.log(this.resourceTypeName)
this.resource_id = _tempFind?.id || 0 this.resource_id = _tempFind?.id || 0
this.getTableData() this.getTableData()
}, },
async getTableData() { async getTableData() {
this.loading = true this.loading = true
const _tableData = await getResourcePerms(this.resource_id, { need_users: 0 }) const _tableData = await getResourcePerms(this.resource_id, { need_users: 0 })
const perms = [] const perms = []
for (const key in _tableData) { for (const key in _tableData) {
const obj = {} const obj = {}
obj.name = key obj.name = key
_tableData[key].perms.forEach((perm) => { _tableData[key].perms.forEach((perm) => {
obj[`${perm.name}`] = true obj[`${perm.name}`] = true
obj.rid = perm?.rid ?? null obj.rid = perm?.rid ?? null
}) })
perms.push(obj) perms.push(obj)
} }
this.tableData = perms this.tableData = perms
this.loading = false this.loading = false
}, },
// Grant the department in common-setting and get the roleid from it // Grant the department in common-setting and get the roleid from it
grantDepart(grantType) { grantDepart(grantType) {
this.$refs.grantModal.open('depart') this.$refs.grantModal.open('depart')
this.grantType = grantType this.grantType = grantType
}, },
// Grant the oldest role permissions // Grant the oldest role permissions
grantRole(grantType) { grantRole(grantType) {
this.$refs.grantModal.open('role') this.$refs.grantModal.open('role')
this.grantType = grantType this.grantType = grantType
}, },
handleOk(params, type) { handleOk(params, type) {
const { grantType } = this const { grantType } = this
let rids let rids
if (type === 'depart') { if (type === 'depart') {
rids = [ rids = [
...params.department.map((rid) => { ...params.department.map((rid) => {
const _find = this.allDepartments.find((dep) => dep.acl_rid === rid) const _find = this.allDepartments.find((dep) => dep.acl_rid === rid)
return { rid, name: _find?.department_name ?? rid } return { rid, name: _find?.department_name ?? rid }
}), }),
...params.user.map((rid) => { ...params.user.map((rid) => {
const _find = this.allEmployees.find((dep) => dep.acl_rid === rid) const _find = this.allEmployees.find((dep) => dep.acl_rid === rid)
return { rid, name: _find?.nickname ?? rid } return { rid, name: _find?.nickname ?? rid }
}), }),
] ]
} }
if (type === 'role') { if (type === 'role') {
rids = [ rids = [
...params.map((role) => { ...params.map((role) => {
return { rid: role.id, name: role.name } return { rid: role.id, name: role.name }
}), }),
] ]
} }
if (grantType === 'ci_type') { if (grantType === 'ci_type') {
this.tableData.unshift( this.tableData.unshift(
...rids.map(({ rid, name }) => { ...rids.map(({ rid, name }) => {
const _find = this.tableData.find((item) => item.rid === rid) const _find = this.tableData.find((item) => item.rid === rid)
return { return {
rid, rid,
name, name,
conifg: false, conifg: false,
grant: false, grant: false,
..._find, ..._find,
} }
}) })
) )
} }
if (grantType === 'ci') { if (grantType === 'ci') {
this.tableData.unshift( this.tableData.unshift(
...rids.map(({ rid, name }) => { ...rids.map(({ rid, name }) => {
const _find = this.tableData.find((item) => item.rid === rid) const _find = this.tableData.find((item) => item.rid === rid)
return { return {
rid, rid,
name, name,
read_attr: false, read_attr: false,
read_ci: false, read_ci: false,
create: false, create: false,
update: false, update: false,
delete: false, delete: false,
..._find, ..._find,
} }
}) })
) )
} }
if (grantType === 'type_relation') { if (grantType === 'type_relation') {
this.tableData.unshift( this.tableData.unshift(
...rids.map(({ rid, name }) => { ...rids.map(({ rid, name }) => {
return { return {
rid, rid,
name, name,
create: false, create: false,
grant: false, grant: false,
delete: false, delete: false,
} }
}) })
) )
} }
if (grantType === 'relation_view') { if (grantType === 'relation_view') {
this.tableData.unshift( this.tableData.unshift(
...rids.map(({ rid, name }) => { ...rids.map(({ rid, name }) => {
return { return {
rid, rid,
name, name,
read: false, read: false,
grant: false, grant: false,
} }
}) })
) )
} }
if (grantType === 'TopologyView') { if (grantType === 'TopologyView') {
this.tableData.unshift( this.tableData.unshift(
...rids.map(({ rid, name }) => { ...rids.map(({ rid, name }) => {
return { return {
rid, rid,
name, name,
read: false, read: false,
update: false, update: false,
delete: false, delete: false,
grant: false, grant: false,
} }
}) })
) )
} }
this.addedRids = rids this.addedRids = rids
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
this.$refs[`grant_${grantType}`].$refs.xTable.elemStore['main-body-wrapper'].scrollTo(0, 0) this.$refs[`grant_${grantType}`].$refs.xTable.elemStore['main-body-wrapper'].scrollTo(0, 0)
}, 300) }, 300)
}) })
}, },
openReadGrantModal(col, row) { openReadGrantModal(col, row) {
this.$refs.readGrantModal.open(col, row) this.$refs.readGrantModal.open(col, row)
}, },
updateTableDataRead(row, hasRead) { updateTableDataRead(row, hasRead) {
const _idx = this.tableData.findIndex((item) => item.rid === row.rid) const _idx = this.tableData.findIndex((item) => item.rid === row.rid)
this.$set(this.tableData, _idx, { ...this.tableData[_idx], read: hasRead }) this.$set(this.tableData, _idx, { ...this.tableData[_idx], read: hasRead })
this.getFilterPermissions() this.getFilterPermissions()
}, },
}, },
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.cmdb-grant { .cmdb-grant {
position: relative; position: relative;
padding: 0 20px; padding: 0 20px;
overflow: auto; overflow: auto;
.cmdb-grant-title { .cmdb-grant-title {
border-left: 4px solid @primary-color; border-left: 4px solid @primary-color;
padding-left: 10px; padding-left: 10px;
} }
} }
</style> </style>
<style lang="less"> <style lang="less">
.cmdb-grant {
.cmdb-grant { .grant-button {
.grant-button { padding: 6px 8px;
padding: 6px 8px; color: @primary-color;
color: @primary-color; background-color: @primary-color_5;
background-color: @primary-color_5; border-radius: 2px;
border-radius: 2px; cursor: pointer;
cursor: pointer; margin: 15px 0;
margin: 15px 0; display: inline-block;
display: inline-block; transition: all 0.3s;
transition: all 0.3s; z-index: 1;
&:hover {
box-shadow: 2px 3px 4px @primary-color_5; .btn-wave-hover(@primary-color_4, -1);
} }
} }
} </style>
</style>

View File

@ -1,122 +1,118 @@
<template> <template>
<a-modal :visible="visible" @cancel="handleCancel" @ok="handleOK" :title="$t('revoke')"> <a-modal :visible="visible" @cancel="handleCancel" @ok="handleOK" :title="$t('revoke')">
<a-form-model :model="form" :label-col="{ span: 4 }" :wrapper-col="{ span: 16 }"> <a-form-model :model="form" :label-col="{ span: 4 }" :wrapper-col="{ span: 16 }">
<a-form-model-item :label="$t('user')"> <a-form-model-item :label="$t('user')">
<EmployeeTreeSelect <EmployeeTreeSelect
class="custom-treeselect custom-treeselect-bgcAndBorder" class="custom-treeselect custom-treeselect-white"
:style="{ :style="{
'--custom-height': '32px', '--custom-height': '32px',
lineHeight: '32px', lineHeight: '32px',
'--custom-bg-color': '#fff', '--custom-multiple-lineHeight': '18px',
'--custom-border': '1px solid #d9d9d9', }"
'--custom-multiple-lineHeight': '18px', :multiple="true"
}" v-model="form.users"
:multiple="true" :placeholder="$t('cmdb.serviceTree.userPlaceholder')"
v-model="form.users" :idType="2"
:placeholder="$t('cmdb.serviceTree.userPlaceholder')" departmentKey="acl_rid"
:idType="2" employeeKey="acl_rid"
departmentKey="acl_rid" />
employeeKey="acl_rid" </a-form-model-item>
/> <a-form-model-item :label="$t('role')">
</a-form-model-item> <treeselect
<a-form-model-item :label="$t('role')"> v-model="form.roles"
<treeselect :multiple="true"
v-model="form.roles" :options="filterAllRoles"
:multiple="true" class="custom-treeselect custom-treeselect-white"
:options="filterAllRoles" :style="{
class="custom-treeselect custom-treeselect-bgcAndBorder" '--custom-height': '32px',
:style="{ lineHeight: '32px',
'--custom-height': '32px', '--custom-multiple-lineHeight': '18px',
lineHeight: '32px', }"
'--custom-bg-color': '#fff', :limit="10"
'--custom-border': '1px solid #d9d9d9', :limitText="(count) => `+ ${count}`"
'--custom-multiple-lineHeight': '18px', :normalizer="
}" (node) => {
:limit="10" return {
:limitText="(count) => `+ ${count}`" id: node.id,
:normalizer=" label: node.name,
(node) => { }
return { }
id: node.id, "
label: node.name, appendToBody
} zIndex="1050"
} :placeholder="$t('cmdb.serviceTree.rolePlaceholder')"
" @search-change="searchRole"
appendToBody />
zIndex="1050" </a-form-model-item>
:placeholder="$t('cmdb.serviceTree.rolePlaceholder')" </a-form-model>
@search-change="searchRole" </a-modal>
/> </template>
</a-form-model-item>
</a-form-model> <script>
</a-modal> import EmployeeTreeSelect from '@/views/setting/components/employeeTreeSelect.vue'
</template> import { getAllDepAndEmployee } from '@/api/company'
import { searchRole } from '@/modules/acl/api/role'
<script>
import EmployeeTreeSelect from '@/views/setting/components/employeeTreeSelect.vue' export default {
import { getAllDepAndEmployee } from '@/api/company' name: 'RevokeModal',
import { searchRole } from '@/modules/acl/api/role' components: { EmployeeTreeSelect },
data() {
export default { return {
name: 'RevokeModal', visible: false,
components: { EmployeeTreeSelect }, form: {
data() { users: undefined,
return { roles: undefined,
visible: false, },
form: { allTreeDepAndEmp: [],
users: undefined, allRoles: [],
roles: undefined, filterAllRoles: [],
}, }
allTreeDepAndEmp: [], },
allRoles: [], provide() {
filterAllRoles: [], return {
} provide_allTreeDepAndEmp: () => {
}, return this.allTreeDepAndEmp
provide() { },
return { }
provide_allTreeDepAndEmp: () => { },
return this.allTreeDepAndEmp mounted() {
}, this.getAllDepAndEmployee()
} this.loadRoles()
}, },
mounted() { methods: {
this.getAllDepAndEmployee() async loadRoles() {
this.loadRoles() const res = await searchRole({ page_size: 9999, app_id: 'cmdb', is_all: true })
}, this.allRoles = res.roles
methods: { this.filterAllRoles = this.allRoles.slice(0, 100)
async loadRoles() { },
const res = await searchRole({ page_size: 9999, app_id: 'cmdb', is_all: true }) getAllDepAndEmployee() {
this.allRoles = res.roles getAllDepAndEmployee({ block: 0 }).then((res) => {
this.filterAllRoles = this.allRoles.slice(0, 100) this.allTreeDepAndEmp = res
}, })
getAllDepAndEmployee() { },
getAllDepAndEmployee({ block: 0 }).then((res) => { open() {
this.allTreeDepAndEmp = res this.visible = true
}) this.$nextTick(() => {
}, this.form = {
open() { users: undefined,
this.visible = true roles: undefined,
this.$nextTick(() => { }
this.form = { })
users: undefined, },
roles: undefined, handleCancel() {
} this.visible = false
}) },
}, searchRole(searchQuery) {
handleCancel() { this.filterAllRoles = this.allRoles
this.visible = false .filter((item) => item.name.toLowerCase().includes(searchQuery.toLowerCase()))
}, .slice(0, 100)
searchRole(searchQuery) { },
this.filterAllRoles = this.allRoles handleOK() {
.filter((item) => item.name.toLowerCase().includes(searchQuery.toLowerCase())) this.$emit('handleRevoke', this.form)
.slice(0, 100) this.handleCancel()
}, },
handleOK() { },
this.$emit('handleRevoke', this.form) }
this.handleCancel() </script>
},
}, <style></style>
}
</script>
<style></style>

View File

@ -3,12 +3,10 @@
:disabled="disabled" :disabled="disabled"
ref="cmdb_type_select" ref="cmdb_type_select"
:disable-branch-nodes="true" :disable-branch-nodes="true"
class="custom-treeselect custom-treeselect-bgcAndBorder" class="custom-treeselect custom-treeselect-white"
:style="{ :style="{
'--custom-height': '30px', '--custom-height': '30px',
lineHeight: '30px', lineHeight: '30px'
'--custom-bg-color': '#fff',
'--custom-border': '1px solid #d9d9d9',
}" }"
v-model="currenCiType" v-model="currenCiType"
:multiple="multiple" :multiple="multiple"

View File

@ -35,8 +35,8 @@
:key="`${item.id}_${index}`" :key="`${item.id}_${index}`"
class="preference-search-tag" class="preference-search-tag"
:style="{ :style="{
backgroundColor: item.id === currentPreferenceSearch ? '#2f54eb' : '#fafafa', backgroundColor: item.id === currentPreferenceSearch ? '#2f54eb' : '',
color: item.id === currentPreferenceSearch ? '#fff' : '#000000a6', color: item.id === currentPreferenceSearch ? '#fff' : '',
}" }"
> >
<span @click="clickPreferenceSearch(item)">{{ item.name }}</span> <span @click="clickPreferenceSearch(item)">{{ item.name }}</span>
@ -189,6 +189,10 @@ export default {
> i { > i {
font-size: 12px; font-size: 12px;
} }
&:hover {
color: @primary-color;
}
} }
.preference-search-delete { .preference-search-delete {
color: #a9a9a9; color: #a9a9a9;

View File

@ -5,13 +5,11 @@
<a-space> <a-space>
<treeselect <treeselect
v-if="type === 'resourceSearch'" v-if="type === 'resourceSearch'"
class="custom-treeselect custom-treeselect-bgcAndBorder" class="custom-treeselect"
:style="{ :style="{
width: '200px', width: '200px',
marginRight: '10px', marginRight: '10px',
'--custom-height': '32px', '--custom-height': '32px',
'--custom-bg-color': '#fff',
'--custom-border': '1px solid #d9d9d9',
'--custom-multiple-lineHeight': '16px', '--custom-multiple-lineHeight': '16px',
}" }"
v-model="currenCiType" v-model="currenCiType"

View File

@ -135,9 +135,15 @@ export default {
border: 1px solid #f3f4f6; border: 1px solid #f3f4f6;
} }
.authorization-input { .authorization-input {
border: none; border: 1px solid transparent;
&:focus { &:focus {
box-shadow: none; box-shadow: none;
border-color: @primary-color;
}
&:hover {
border-color: @primary-color;
} }
} }
} }

View File

@ -29,7 +29,7 @@
<tr v-for="(item, index) in headers" :key="item.id"> <tr v-for="(item, index) in headers" :key="item.id">
<td><a-input class="headers-input" v-model="item.key" :placeholder="$t('cmdb.components.param', { param: `${index + 1}` })" /></td> <td><a-input class="headers-input" v-model="item.key" :placeholder="$t('cmdb.components.param', { param: `${index + 1}` })" /></td>
<td><a-input class="headers-input" v-model="item.value" :placeholder="$t('cmdb.components.value', { value: `${index + 1}` })" /></td> <td><a-input class="headers-input" v-model="item.value" :placeholder="$t('cmdb.components.value', { value: `${index + 1}` })" /></td>
<td> <td class="headers-delete">
<a style="color:red"> <a style="color:red">
<ops-icon type="icon-xianxing-delete" @click="deleteParam(index)" /> <ops-icon type="icon-xianxing-delete" @click="deleteParam(index)" />
</a> </a>
@ -92,10 +92,20 @@ export default {
border: 1px solid #f3f4f6; border: 1px solid #f3f4f6;
} }
.headers-input { .headers-input {
border: none; border: 1px solid transparent;
&:focus { &:focus {
box-shadow: none; box-shadow: none;
border-color: @primary-color;
} }
&:hover {
border-color: @primary-color;
}
}
.headers-delete {
text-align: center;
} }
} }
</style> </style>

View File

@ -3,12 +3,10 @@
<a-input-group compact> <a-input-group compact>
<treeselect <treeselect
:disable-branch-nodes="true" :disable-branch-nodes="true"
class="custom-treeselect custom-treeselect-bgcAndBorder" class="custom-treeselect custom-treeselect-white"
:style="{ :style="{
'--custom-height': '30px', '--custom-height': '30px',
lineHeight: '30px', lineHeight: '30px',
'--custom-bg-color': '#fff',
'--custom-border': '1px solid #d9d9d9',
display: 'inline-block', display: 'inline-block',
width: '100px', width: '100px',
}" }"

View File

@ -23,7 +23,7 @@
<tr v-for="(item, index) in parameters" :key="item.id"> <tr v-for="(item, index) in parameters" :key="item.id">
<td><a-input class="parameters-input" v-model="item.key" :placeholder="$t('cmdb.components.param', { param: `${index + 1}` })" /></td> <td><a-input class="parameters-input" v-model="item.key" :placeholder="$t('cmdb.components.param', { param: `${index + 1}` })" /></td>
<td><a-input class="parameters-input" v-model="item.value" :placeholder="$t('cmdb.components.value', { value: `${index + 1}` })" /></td> <td><a-input class="parameters-input" v-model="item.value" :placeholder="$t('cmdb.components.value', { value: `${index + 1}` })" /></td>
<td> <td class="parameters-delete">
<a style="color:red"> <a style="color:red">
<ops-icon type="icon-xianxing-delete" @click="deleteParam(index)" /> <ops-icon type="icon-xianxing-delete" @click="deleteParam(index)" />
</a> </a>
@ -91,10 +91,20 @@ export default {
border: 1px solid #f3f4f6; border: 1px solid #f3f4f6;
} }
.parameters-input { .parameters-input {
border: none; border: 1px solid transparent;
&:focus { &:focus {
box-shadow: none; box-shadow: none;
border-color: @primary-color;
} }
&:hover {
border-color: @primary-color;
}
}
.parameters-delete {
text-align: center;
} }
} }
</style> </style>

View File

@ -104,6 +104,16 @@ export default {
.cmdb-batch-upload-tips { .cmdb-batch-upload-tips {
color: @primary-color; color: @primary-color;
} }
&: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;
}
} }
.ant-upload.ant-upload-drag .ant-upload-drag-container { .ant-upload.ant-upload-drag .ant-upload-drag-container {
vertical-align: baseline; vertical-align: baseline;

View File

@ -9,22 +9,18 @@
" "
:title="$t('cmdb.ci.attributeDesc')" :title="$t('cmdb.ci.attributeDesc')"
width="72%" width="72%"
:bodyStyle="{ height: '100vh' }" :bodyStyle="{ height: '100vh', paddingTop: '16px' }"
> >
<vxe-toolbar> <a-input
<template #buttons> v-model="searchKey"
<a-input :style="{ display: 'inline-block', width: '244px', marginBottom: '16px' }"
v-model="searchKey" class="ops-input ops-input-radius"
:style="{ display: 'inline-block', width: '244px' }" type="search"
class="ops-input ops-input-radius" :placeholder="$t('cmdb.ci.tips5')"
type="search" @keyup="searchAttributes"
:placeholder="$t('cmdb.ci.tips5')" >
@keyup="searchAttributes" <a-icon type="search" slot="suffix" />
> </a-input>
<a-icon type="search" slot="suffix" />
</a-input>
</template>
</vxe-toolbar>
<a-spin :spinning="loading"> <a-spin :spinning="loading">
<vxe-table <vxe-table

View File

@ -33,8 +33,8 @@
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="tab_3"> <a-tab-pane key="tab_3">
<span slot="tab"><a-icon type="clock-circle" />{{ $t('cmdb.ci.history') }}</span> <span slot="tab"><a-icon type="clock-circle" />{{ $t('cmdb.ci.history') }}</span>
<div :style="{ padding: '24px', height: '100%' }"> <div :style="{ padding: '16px 24px 24px', height: '100%' }">
<a-space :style="{ 'margin-bottom': '10px', display: 'flex' }"> <a-space :style="{ marginBottom: '16px', display: 'flex' }">
<a-button type="primary" class="ops-button-ghost" ghost @click="handleRollbackCI()"> <a-button type="primary" class="ops-button-ghost" ghost @click="handleRollbackCI()">
<ops-icon type="shishizhuangtai" />{{ $t('cmdb.ci.rollback') }} <ops-icon type="shishizhuangtai" />{{ $t('cmdb.ci.rollback') }}
</a-button> </a-button>
@ -180,7 +180,7 @@ export default {
ci_types: [], ci_types: [],
hasPermission: true, hasPermission: true,
itsmInstalled: true, itsmInstalled: true,
tableHeight: this.attributeHistoryTableHeight || (this.$store.state.windowHeight - 120), tableHeight: this.attributeHistoryTableHeight || (this.$store.state.windowHeight - 130),
initQueryLoading: true, initQueryLoading: true,
} }
}, },

View File

@ -61,16 +61,20 @@ export default {
justify-content: center; justify-content: center;
font-size: 12px; font-size: 12px;
font-weight: 400; font-weight: 400;
color: #4E5969; color: @text-color_2;
background-color: #F7F8FA; background-color: @primary-color_7;
width: 105px; width: 105px;
height: 32px; height: 32px;
cursor: pointer; cursor: pointer;
&-active { &-active {
border: solid 1px #B1C9FF; border: solid 1px @primary-color_8;
background-color: #E1EFFF; background-color: @primary-color_4;
color: #2F54EB; color: @primary-color;
}
&:hover {
color: @primary-color;
} }
} }
} }

View File

@ -154,6 +154,17 @@ export default {
margin-left: 6px; margin-left: 6px;
} }
&:hover {
background-color: @primary-color_5;
.attr-ad-tab-edit {
display: inline-block;
}
.attr-ad-tab-delete {
display: inline-block;
}
}
&_active { &_active {
border: solid 1px @primary-color_8; border: solid 1px @primary-color_8;
background-color: @primary-color_6; background-color: @primary-color_6;
@ -161,14 +172,9 @@ export default {
.attr-ad-tab-name { .attr-ad-tab-name {
color: @primary-color; color: @primary-color;
} }
}
&:hover { &:hover {
.attr-ad-tab-edit { background-color: @primary-color_6;
display: inline-block;
}
.attr-ad-tab-delete {
display: inline-block;
} }
} }
} }
@ -178,6 +184,11 @@ export default {
background-color: @primary-color_7; background-color: @primary-color_7;
font-size: 12px; font-size: 12px;
color: @text-color_4; color: @text-color_4;
&:hover {
background-color: @primary-color_5;
color: @primary-color;
}
} }
} }
</style> </style>

View File

@ -3,12 +3,14 @@
<div class="attr-ad-header attr-ad-header-margin">{{ $t('cmdb.ciType.configCheckTitle') }}</div> <div class="attr-ad-header attr-ad-header-margin">{{ $t('cmdb.ciType.configCheckTitle') }}</div>
<div class="attr-ad-content"> <div class="attr-ad-content">
<div class="ad-test-title-info">{{ $t('cmdb.ciType.checkTestTip') }}</div> <div class="ad-test-title-info">{{ $t('cmdb.ciType.checkTestTip') }}</div>
<div <a-button
class="ad-test-btn" type="primary"
class="ops-button-ghost ad-test-btn"
ghost
@click="showCheckModal" @click="showCheckModal"
> >
{{ $t('cmdb.ciType.checkTestBtn') }} {{ $t('cmdb.ciType.checkTestBtn') }}
</div> </a-button>
<div class="ad-test-btn-info">{{ $t('cmdb.ciType.checkTestTip2') }}</div> <div class="ad-test-btn-info">{{ $t('cmdb.ciType.checkTestTip2') }}</div>
<!-- <div <!-- <div
class="ad-test-btn" class="ad-test-btn"
@ -140,15 +142,6 @@ export default {
.ad-test-btn { .ad-test-btn {
margin-top: 30px; margin-top: 30px;
padding: 5px 12px;
background-color: #F4F9FF;
border: solid 1px @primary-color_8;
display: inline-block;
cursor: pointer;
color: @link-color;
font-size: 12px;
font-weight: 400;
} }
.ad-test-btn-info { .ad-test-btn-info {

View File

@ -1194,7 +1194,7 @@ export default {
.selected { .selected {
background-color: @primary-color_3; background-color: @primary-color_3;
.ci-types-left-detail-title { .ci-types-left-detail-title {
font-weight: 700; color: @primary-color;
} }
} }
} }

View File

@ -61,13 +61,11 @@
:disable-branch-nodes="true" :disable-branch-nodes="true"
:class="{ :class="{
'custom-treeselect': true, 'custom-treeselect': true,
'custom-treeselect-bgcAndBorder': true, 'custom-treeselect-white': true,
}" }"
:style="{ :style="{
'--custom-height': '32px', '--custom-height': '32px',
lineHeight: '32px', lineHeight: '32px',
'--custom-bg-color': '#fff',
'--custom-border': '1px solid #d9d9d9',
'--custom-multiple-lineHeight': '14px', '--custom-multiple-lineHeight': '14px',
}" }"
v-model="choice_other.type_ids" v-model="choice_other.type_ids"

View File

@ -198,13 +198,11 @@
:disable-branch-nodes="true" :disable-branch-nodes="true"
:class="{ :class="{
'custom-treeselect': true, 'custom-treeselect': true,
'custom-treeselect-bgcAndBorder': true, 'custom-treeselect-white': true,
}" }"
:style="{ :style="{
'--custom-height': '32px', '--custom-height': '32px',
lineHeight: '32px', lineHeight: '32px',
'--custom-bg-color': '#fff',
'--custom-border': '1px solid #d9d9d9',
'--custom-multiple-lineHeight': '14px', '--custom-multiple-lineHeight': '14px',
}" }"
v-model="selectedBot" v-model="selectedBot"

View File

@ -195,12 +195,14 @@
</template> </template>
</div> </div>
<a-form-model-item <a-form-model-item
:label="$t('cmdb.custom_dashboard.showIcon')"
prop="showIcon" prop="showIcon"
:label-col="{ span: 5 }" :label-col="{ span: 0 }"
:wrapper-col="{ span: 18 }" :wrapper-col="{ span: 23 }"
> >
<a-switch v-model="form.showIcon"></a-switch> <div class="chart-left-show-icon">
<span class="chart-left-show-icon-label">{{ $t('cmdb.custom_dashboard.showIcon') }}:</span>
<a-switch v-model="form.showIcon"></a-switch>
</div>
</a-form-model-item> </a-form-model-item>
</a-form-model> </a-form-model>
</div> </div>
@ -733,6 +735,9 @@ export default {
width: 92%; width: 92%;
position: relative; position: relative;
padding: 12px; padding: 12px;
margin-top: 4px;
display: inline-block;
.chart-left-preview-operation { .chart-left-preview-operation {
color: #86909c; color: #86909c;
position: absolute; position: absolute;
@ -753,12 +758,26 @@ export default {
background-position-x: center; background-position-x: center;
background-position-y: center; background-position-y: center;
} }
&-show-icon {
display: flex;
align-items: center;
&-label {
flex-shrink: 0;
margin-right: 8px;
}
}
} }
.chart-right { .chart-right {
width: 50%; width: 50%;
h4 { h4 {
font-weight: 700; font-weight: 700;
color: #000; color: #000;
&:not(:first-child) {
margin-top: 14px;
}
} }
.chart-right-type { .chart-right-type {
display: flex; display: flex;
@ -797,7 +816,7 @@ export default {
<style lang="less"> <style lang="less">
.chart-wrapper { .chart-wrapper {
.ant-form-item { .ant-form-item {
margin-bottom: 0; margin-bottom: 8px;
} }
} }
</style> </style>

View File

@ -170,6 +170,7 @@ export default {
position: relative; position: relative;
margin-bottom: 40px; margin-bottom: 40px;
margin-right: 40px; margin-right: 40px;
cursor: pointer;
&-inner { &-inner {
position: absolute; position: absolute;
@ -294,6 +295,12 @@ export default {
} }
} }
&, &.discovery-card-small {
&:hover {
box-shadow: 0px 6px 20px 0px rgba(122, 140, 204, 0.30);
}
}
&-http { &-http {
width: 263px; width: 263px;
height: 142px; height: 142px;
@ -305,6 +312,10 @@ export default {
max-width: 30px !important; max-width: 30px !important;
} }
} }
&:hover {
box-shadow: 0px 6px 28px 0px rgba(122, 140, 204, 0.30);
}
} }
} }
.discovery-card-small { .discovery-card-small {
@ -312,7 +323,7 @@ export default {
height: 80px; height: 80px;
cursor: pointer; cursor: pointer;
} }
.discovery-card-small:hover,
.discovery-card-small-selected { .discovery-card-small-selected {
.discovery-top { .discovery-top {
background-color: #f0f1f5; background-color: #f0f1f5;

View File

@ -25,18 +25,24 @@
:fileList="[]" :fileList="[]"
:beforeUpload="beforeUpload" :beforeUpload="beforeUpload"
> >
<a class="setting-discovery-header-action-btn"> <a-button
type="primary"
class="ops-button-ghost"
ghost
>
<a-icon type="upload" /> <a-icon type="upload" />
{{ $t('cmdb.ad.upload') }} {{ $t('cmdb.ad.upload') }}
</a> </a-button>
</a-upload> </a-upload>
<a <a-button
type="primary"
class="ops-button-ghost"
ghost
@click="download" @click="download"
class="setting-discovery-header-action-btn"
> >
<a-icon type="download" /> <a-icon type="download" />
{{ $t('cmdb.ad.download') }} {{ $t('cmdb.ad.download') }}
</a> </a-button>
</div> </div>
</div> </div>
<div <div

View File

@ -46,10 +46,15 @@
<span @click="batchDelete">{{ $t('delete') }}</span> <span @click="batchDelete">{{ $t('delete') }}</span>
<span>{{ $t('cmdb.ci.selectRows', { rows: selectedCount }) }}</span> <span>{{ $t('cmdb.ci.selectRows', { rows: selectedCount }) }}</span>
</span> </span>
<div @click="clickLog" class="discovery-ci-log"> <a-button
type="primary"
ghost
class="ops-button-ghost discovery-ci-log"
@click="clickLog"
>
<ops-icon type="a-cmdb-log1" /> <ops-icon type="a-cmdb-log1" />
<span>{{ $t('cmdb.ad.log') }}</span> <span>{{ $t('cmdb.ad.log') }}</span>
</div> </a-button>
</div> </div>
<ops-table <ops-table
show-overflow show-overflow
@ -458,16 +463,7 @@ export default {
} }
.discovery-ci-log { .discovery-ci-log {
cursor: pointer;
background-color: #F4F9FF;
border: solid 1px @primary-color_8;
color: @primary-color;
font-size: 12px;
padding: 5px 12px;
margin-left: auto; margin-left: auto;
display: flex;
align-items: center;
gap: 6px;
} }
.checkbox-hover-table { .checkbox-hover-table {

View File

@ -1,5 +1,5 @@
<template> <template>
<div> <div class="operation-history">
<a-card :bordered="false"> <a-card :bordered="false">
<a-tabs default-active-key="1"> <a-tabs default-active-key="1">
<a-tab-pane key="1" :tab="$t('cmdb.history.ciChange')"> <a-tab-pane key="1" :tab="$t('cmdb.history.ciChange')">
@ -40,4 +40,10 @@ export default {
} }
</script> </script>
<style></style> <style lang="less" scoped>
.operation-history {
/deep/ .ant-tabs-tab {
padding-top: 0px;
}
}
</style>

View File

@ -1,6 +1,11 @@
<template> <template>
<div> <div>
<a-form :colon="false"> <a-form
:colon="false"
:labelCol="{ span:4 }"
:wrapperCol="{ span:20 }"
labelAlign="left"
>
<a-row :gutter="24"> <a-row :gutter="24">
<a-col <a-col
:sm="24" :sm="24"
@ -10,12 +15,7 @@
v-for="attr in attrList.slice(0,3)" v-for="attr in attrList.slice(0,3)"
:key="attr.name" :key="attr.name"
> >
<a-form-item <a-form-item :label="attr.alias || attr.name">
:label="attr.alias || attr.name "
:labelCol="{span:4}"
:wrapperCol="{span:20}"
labelAlign="right"
>
<a-select <a-select
v-model="queryParams[attr.name]" v-model="queryParams[attr.name]"
:placeholder="$t('cmdb.history.pleaseSelect')" :placeholder="$t('cmdb.history.pleaseSelect')"
@ -57,12 +57,7 @@
:key="'expand_' + item.name" :key="'expand_' + item.name"
v-for="item in attrList.slice(3)" v-for="item in attrList.slice(3)"
> >
<a-form-item <a-form-item :label="item.alias || item.name">
:label="item.alias || item.name"
:label-col="{ span: 4 }"
:wrapper-col="{ span: 20 }"
labelAlign="right"
>
<a-select <a-select
v-model="queryParams[item.name]" v-model="queryParams[item.name]"
:placeholder="$t('cmdb.history.pleaseSelect')" :placeholder="$t('cmdb.history.pleaseSelect')"
@ -97,7 +92,7 @@
</template> </template>
</a-row> </a-row>
<a-row> <a-row>
<a-col :span="24" :style="{ textAlign: 'right' , marginBottom: '10px' }"> <a-col :span="24" :style="{ textAlign: 'right', marginBottom: '20px', marginTop: '-4px'}">
<a-button type="primary" html-type="submit" @click="handleSearch"> <a-button type="primary" html-type="submit" @click="handleSearch">
{{ $t('query') }} {{ $t('query') }}
</a-button> </a-button>

View File

@ -114,7 +114,11 @@
:placeholder="$t('cmdb.preference.searchPlaceholder')" :placeholder="$t('cmdb.preference.searchPlaceholder')"
/> />
<div v-for="group in filterCiTypeData" :key="group.id"> <div v-for="group in filterCiTypeData" :key="group.id">
<p @click="changeGroupExpand(group)" :style="{ display: 'inline-block', cursor: 'pointer' }"> <p
@click="changeGroupExpand(group)"
:style="{ display: 'inline-block', cursor: 'pointer' }"
class="cmdb-preference-right-group-title"
>
<a-icon :type="expandKeys.includes(group.id) ? 'caret-down' : 'caret-right'" />{{ group.name }}({{ <a-icon :type="expandKeys.includes(group.id) ? 'caret-down' : 'caret-right'" />{{ group.name }}({{
group.ci_types ? group.ci_types.length : 0 group.ci_types ? group.ci_types.length : 0
}}) }})
@ -624,6 +628,16 @@ export default {
flex: 1; flex: 1;
height: 100%; height: 100%;
padding-top: 24px; padding-top: 24px;
&-group-title {
width: 300px;
margin-bottom: 20px;
&:hover {
color: @primary-color;
}
}
.cmdb-preference-content { .cmdb-preference-content {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@ -1697,6 +1697,10 @@ export default {
background-color: #fff; background-color: #fff;
padding: 20px; padding: 20px;
border-radius: @border-radius-box; border-radius: @border-radius-box;
.ant-tabs-tab {
padding-top: 0px;
}
} }
} }
</style> </style>

View File

@ -19,13 +19,11 @@
> >
<treeselect <treeselect
:value="selectCITypeIds" :value="selectCITypeIds"
class="custom-treeselect custom-treeselect-bgcAndBorder filter-content-ciTypes" class="custom-treeselect custom-treeselect-white filter-content-ciTypes"
:style="{ :style="{
width: '400px', width: '400px',
zIndex: '1000', zIndex: '1000',
'--custom-height': '32px', '--custom-height': '32px',
'--custom-bg-color': '#FFF',
'--custom-border': '1px solid #d9d9d9',
'--custom-multiple-lineHeight': '32px', '--custom-multiple-lineHeight': '32px',
}" }"
:multiple="true" :multiple="true"

View File

@ -78,21 +78,3 @@ export default {
} }
} }
</script> </script>
<style lang="less" scoped>
.save-condition-modal {
/deep/ .ant-modal-close-x {
width: 48px;
height: 48px;
line-height: 48px;
}
/deep/ .ant-modal-body {
padding: 24px 18px;
}
/deep/ .ant-modal-footer {
padding: 10px 18px 18px;
}
}
</style>

View File

@ -512,15 +512,31 @@ export default {
padding: 14px 18px; padding: 14px 18px;
width: 500px; width: 500px;
} }
/deep/ .filter-content-ciTypes {
&:not(.vue-treeselect--disabled):not(.vue-treeselect--focused) {
.vue-treeselect__control {
border: solid 1px transparent;
&:hover {
border-color: @primary-color;
}
}
}
}
} }
&-input { &-input {
width: 100%; width: 100%;
/deep/ .ant-input { /deep/ .ant-input {
border: none; border: solid 1px transparent;
box-shadow: none; box-shadow: none;
cursor: pointer; cursor: pointer;
&:hover {
border-color: @primary-color;
}
} }
&-suffix { &-suffix {
@ -532,8 +548,12 @@ export default {
width: 100%; width: 100%;
/deep/ .ant-select-selection { /deep/ .ant-select-selection {
border: none; border: solid 1px transparent;
box-shadow: none; box-shadow: none;
&:hover {
border-color: @primary-color;
}
} }
} }

View File

@ -164,8 +164,12 @@ export default {
/deep/ & > input { /deep/ & > input {
height: 100%; height: 100%;
margin-left: 10px; margin-left: 10px;
border: none; border: solid 1px transparent;
box-shadow: none; box-shadow: none;
&:focus {
border-color: @primary-color;
}
} }
} }

View File

@ -116,6 +116,10 @@ body {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
margin-right: 10px; margin-right: 10px;
&:hover {
color: @primary-color;
}
} }
.topmenu { .topmenu {
@ -560,7 +564,7 @@ body {
top: 10px; top: 10px;
border-radius: 5px; border-radius: 5px;
&:hover { &:hover {
background: #c1bfbf; color: @primary-color;
} }
.anticon { .anticon {
margin-right: 0; margin-right: 0;
@ -661,7 +665,7 @@ body {
margin-right: 5px !important; margin-right: 5px !important;
} }
&:hover { &:hover {
background-color: #e7e7e7; background-color: @primary-color_5;
} }
} }
} }
@ -869,6 +873,10 @@ body {
align-items: center; align-items: center;
height: 30px; height: 30px;
} }
&:hover {
border-color: #597ef7 !important;
}
} }
.vue-treeselect__placeholder, .vue-treeselect__placeholder,
.vue-treeselect__single-value { .vue-treeselect__single-value {
@ -885,15 +893,46 @@ body {
border-radius: 2px !important; border-radius: 2px !important;
border-color: #e4e7ed; border-color: #e4e7ed;
} }
&:hover {
border-color: #597ef7 !important;
}
} }
.custom-vue-treeselect__control(@bgColor:@primary-color_7,@border:none) { .custom-vue-treeselect__control(
background-color: @bgColor; @bgColor: @primary-color_7,
border: @border; @border: none,
} @hoverBgColor: none,
.custom-treeselect { @hoverBorderColor: none,
) {
.vue-treeselect__control {
background-color: @bgColor;
border: @border;
}
.mixin(@borderColor) when (iscolor(@borderColor)) {
border-color: @borderColor !important;
}
&:not(.vue-treeselect--disabled):not(.vue-treeselect--focused) {
.vue-treeselect__control {
&:hover {
background-color: if(iscolor(@hoverBgColor), @hoverBgColor, @bgColor);
.mixin(@hoverBorderColor)
}
}
}
}
.custom-treeselect {
.custom-vue-treeselect__control(
@primary-color_7,
none,
@primary-color_5,
none
);
.vue-treeselect__control { .vue-treeselect__control {
.custom-vue-treeselect__control();
height: var(--custom-height) !important; height: var(--custom-height) !important;
border-radius: 2px !important; border-radius: 2px !important;
} }
@ -909,12 +948,34 @@ body {
.vue-treeselect__limit-tip-text { .vue-treeselect__limit-tip-text {
margin: 0; margin: 0;
} }
&.vue-treeselect--focused {
.vue-treeselect__control {
border: 1px solid @primary-color;
}
}
} }
// 自定义背景颜色和border // 自定义背景颜色和border
.custom-treeselect-bgcAndBorder .vue-treeselect__control { .custom-treeselect-bgcAndBorder {
.custom-vue-treeselect__control(var(--custom-bg-color), var(--custom-border)); .custom-vue-treeselect__control(
var(--custom-bg-color),
var(--custom-border),
var(--custom-hover-bg-color),
var(--custom-hover-border-color)
);
} }
// 白色背景
.custom-treeselect-white {
.custom-vue-treeselect__control(
#fff,
1px solid #d9d9d9,
none,
@primary-color
);
}
// 自定义背景颜色和border // 自定义背景颜色和border
.custom-treeselect.vue-treeselect--multi { .custom-treeselect.vue-treeselect--multi {
.vue-treeselect__multi-value, .vue-treeselect__multi-value,
@ -1025,6 +1086,20 @@ body {
background-color: @primary-color_7; background-color: @primary-color_7;
border: none; border: none;
} }
&,
.ant-input,
.ant-time-picker-input {
&:not([disabled]) {
&:hover {
background-color: @primary-color_5;
}
&:focus {
background-color: @primary-color_7;
}
}
}
} }
.ops-input.ant-input { .ops-input.ant-input {
background-color: @primary-color_7; background-color: @primary-color_7;
@ -1163,13 +1238,31 @@ body {
} }
// button // button
.ops-button-ghost.ant-btn-background-ghost.ant-btn-primary { .ops-button-ghost {
background-color: @primary-color_5!important; position: relative;
border-color: @primary-color_8; overflow: hidden;
&.ant-btn-background-ghost.ant-btn-primary {
border-color: @primary-color_8;
background-color: @primary-color_5 !important;
box-shadow: none;
.btn-wave-hover(@primary-color_4);
&[disabled] {
border-color: #d9d9d9;
background-color: @primary-color_7!important;
}
&:not([disabled]):hover {
color: #3F75FF;
border-color: transparent;
}
}
} }
.ops-button-ghost.ant-btn-background-ghost.ant-btn-primary[disabled] {
border-color: #d9d9d9; .ant-btn-primary:not(.ant-btn-background-ghost) {
background-color: @primary-color_7!important; .btn-wave-hover(#3F75FF);
} }
// button // button
@ -1214,15 +1307,25 @@ body {
//modal //modal
.ant-modal-content { .ant-modal-content {
.ant-modal-close-x {
width: 56px;
height: 56px;
line-height: 56px;
}
.ant-modal-header { .ant-modal-header {
border-bottom: none; border-bottom: none;
padding: 22px 22px;
.ant-modal-title { .ant-modal-title {
padding-left: 10px; padding-left: 10px;
border-left: 4px solid @primary-color; border-left: 4px solid @primary-color;
} }
} }
.ant-modal-footer { .ant-modal-footer {
border-top: none; border-top: none;
padding: 16px 22px 22px;
} }
} }

View File

@ -70,3 +70,46 @@
background-color: @primary-color_3; background-color: @primary-color_3;
color: @primary-color; color: @primary-color;
} }
.btn-wave-hover(
@hoverBgColor,
@bgZIndex: 0
) {
position: relative;
overflow: hidden;
& > * {
position: relative;
z-index: 1;
}
&:not([disabled])::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
z-index: @bgZIndex;
width: 100%;
aspect-ratio: 1/1;
border-radius: 50%;
background-color: @hoverBgColor;
-webkit-transform: scale(0) translate(-50%, -50%);
-ms-transform: scale(0) translate(-50%, -50%);
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;
}
&:not([disabled]):hover {
&::after {
-webkit-transform: scale(2) translate(-50%, -50%);
-ms-transform: scale(2) translate(-50%, -50%);
transform: scale(2) translate(-50%, -50%);
}
}
}