mirror of
https://github.com/veops/cmdb.git
synced 2025-08-08 21:47:06 +08:00
feat:ui 全面升级 (#444)
This commit is contained in:
@@ -178,7 +178,7 @@
|
||||
<div v-else :style="{ width: '175px' }"></div>
|
||||
<template v-if="!disabled">
|
||||
<a-tooltip :title="$t('copy')">
|
||||
<a class="operation" @click="handleCopyRule(item)"><ops-icon type="icon-xianxing-copy"/></a>
|
||||
<a class="operation" @click="handleCopyRule(item)"><ops-icon type="veops-copy"/></a>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="$t('delete')">
|
||||
<a class="operation" @click="handleDeleteRule(item)"><ops-icon type="icon-xianxing-delete"/></a>
|
||||
|
@@ -759,6 +759,52 @@ export const multicolorIconList = [
|
||||
value: 'caise-redis',
|
||||
label: 'redis'
|
||||
}]
|
||||
}, {
|
||||
value: 'cloud',
|
||||
label: '云',
|
||||
list: [{
|
||||
value: 'AWS',
|
||||
label: 'AWS'
|
||||
}, {
|
||||
value: 'Azure',
|
||||
label: 'Azure'
|
||||
}, {
|
||||
value: 'Google_Cloud_Platform',
|
||||
label: 'Google Cloud Platform'
|
||||
}, {
|
||||
value: 'Alibaba_Cloud',
|
||||
label: '阿里云'
|
||||
}, {
|
||||
value: 'Huawei_Cloud',
|
||||
label: '华为云'
|
||||
}, {
|
||||
value: 'Tencent_Cloud',
|
||||
label: '腾讯云'
|
||||
}, {
|
||||
value: 'UCloud',
|
||||
label: 'UCloud'
|
||||
}, {
|
||||
value: 'Ctyun',
|
||||
label: '天翼云'
|
||||
}, {
|
||||
value: 'ECloud',
|
||||
label: '移动云'
|
||||
}, {
|
||||
value: 'JDCloud',
|
||||
label: '京东云'
|
||||
}, {
|
||||
value: 'Bytecloud',
|
||||
label: '字节云'
|
||||
}, {
|
||||
value: 'OpenStack',
|
||||
label: 'OpenStack'
|
||||
}, {
|
||||
value: 'ZStack',
|
||||
label: 'ZStack'
|
||||
}, {
|
||||
value: 'Nutanix',
|
||||
label: 'Nutanix'
|
||||
}]
|
||||
}, {
|
||||
value: 'system',
|
||||
label: '操作系统',
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a-layout-sider
|
||||
:class="['sider', isDesktop() ? null : 'shadow', theme, fixSiderbar ? 'ant-fixed-sidemenu' : null]"
|
||||
width="200px"
|
||||
width="220px"
|
||||
:collapsible="collapsible"
|
||||
v-model="collapsed"
|
||||
:trigger="null"
|
||||
@@ -15,6 +15,7 @@
|
||||
@select="onSelect"
|
||||
style="padding: 16px 0px;"
|
||||
></s-menu>
|
||||
<!-- <OpsDocs :collapsed="collapsed" /> -->
|
||||
</a-layout-sider>
|
||||
</template>
|
||||
|
||||
@@ -22,10 +23,13 @@
|
||||
import Logo from '@/components/tools/Logo'
|
||||
import SMenu from './index'
|
||||
import { mixin, mixinDevice } from '@/utils/mixin'
|
||||
// import OpsDocs from '@/modules/docs/index.vue'
|
||||
|
||||
export default {
|
||||
name: 'SideMenu',
|
||||
components: { Logo, SMenu },
|
||||
components: { Logo, SMenu,
|
||||
// OpsDocs
|
||||
},
|
||||
mixins: [mixin, mixinDevice],
|
||||
props: {
|
||||
mode: {
|
||||
|
@@ -1,121 +1,49 @@
|
||||
<template>
|
||||
<vxe-table v-bind="$attrs" v-on="new$listeners" ref="xTable">
|
||||
<slot></slot>
|
||||
<template #empty>
|
||||
<slot name="empty">
|
||||
<div :style="{ paddingTop: '10px' }">
|
||||
<img :style="{ width: '100px', height: '90px' }" :src="require('@/assets/data_empty.png')" />
|
||||
<div>{{ $t('noData') }}</div>
|
||||
</div>
|
||||
</slot>
|
||||
</template>
|
||||
<template #loading>
|
||||
<slot name="loading"></slot>
|
||||
</template>
|
||||
</vxe-table>
|
||||
<span>
|
||||
<ops-icon :type="getPropertyIcon(attr)" />
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
// 该组件使用方法与vxe-table一致,但调用它的方法时,需先调用getVxetableRef()获取到vxe-table实体
|
||||
export default {
|
||||
name: 'OpsTable',
|
||||
data() {
|
||||
return {
|
||||
// isShifting: false,
|
||||
// lastIndex: -1,
|
||||
lastSelected: [],
|
||||
currentSelected: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
new$listeners() {
|
||||
if (!Object.keys(this.$listeners).length) {
|
||||
return this.$listeners
|
||||
}
|
||||
return Object.assign(this.$listeners, {
|
||||
// 在这里覆盖原有的change事件
|
||||
// 'checkbox-change': this.selectChangeEvent,
|
||||
'checkbox-range-change': this.checkboxRangeChange,
|
||||
'checkbox-range-start': this.checkboxRangeStart,
|
||||
'checkbox-range-end': this.checkboxRangeEnd,
|
||||
})
|
||||
name: 'ValueTypeIcon',
|
||||
props: {
|
||||
attr: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// window.onkeydown = (e) => {
|
||||
// if (e.key === 'Shift') {
|
||||
// this.isShifting = true
|
||||
// }
|
||||
// }
|
||||
// window.onkeyup = (e) => {
|
||||
// if (e.key === 'Shift') {
|
||||
// this.isShifting = false
|
||||
// this.lastIndex = -1
|
||||
// }
|
||||
// }
|
||||
},
|
||||
beforeDestroy() {
|
||||
// window.onkeydown = ''
|
||||
// window.onkeyup = ''
|
||||
},
|
||||
methods: {
|
||||
getVxetableRef() {
|
||||
return this.$refs.xTable
|
||||
},
|
||||
// selectChangeEvent(e) {
|
||||
// const xTable = this.$refs.xTable
|
||||
// const { lastIndex } = this
|
||||
// const currentIndex = e.rowIndex
|
||||
// const { tableData } = xTable.getTableData()
|
||||
// if (lastIndex > -1 && this.isShifting) {
|
||||
// let start = lastIndex
|
||||
// let end = currentIndex
|
||||
// if (lastIndex > currentIndex) {
|
||||
// start = currentIndex
|
||||
// end = lastIndex
|
||||
// }
|
||||
// const rangeData = tableData.slice(start, end + 1)
|
||||
// xTable.setCheckboxRow(rangeData, true)
|
||||
// }
|
||||
// this.lastIndex = currentIndex
|
||||
// this.$emit('checkbox-change', { ...e, records: xTable.getCheckboxRecords() })
|
||||
// },
|
||||
checkboxRangeStart(e) {
|
||||
const xTable = this.$refs.xTable
|
||||
const lastSelected = xTable.getCheckboxRecords()
|
||||
const selectedReserve = xTable.getCheckboxReserveRecords()
|
||||
this.lastSelected = [...lastSelected, ...selectedReserve]
|
||||
this.$emit('checkbox-range-start', e)
|
||||
},
|
||||
checkboxRangeChange(e) {
|
||||
const xTable = this.$refs.xTable
|
||||
xTable.setCheckboxRow(this.lastSelected, true)
|
||||
this.currentSelected = e.records
|
||||
// this.lastSelected = [...new Set([...this.lastSelected, ...e.records])]
|
||||
this.$emit('checkbox-range-change', {
|
||||
...e,
|
||||
records: [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()],
|
||||
})
|
||||
},
|
||||
checkboxRangeEnd(e) {
|
||||
const xTable = this.$refs.xTable
|
||||
const isAllSelected = this.currentSelected.every((item) => {
|
||||
const _idx = this.lastSelected.findIndex((ele) => _.isEqual(ele, item))
|
||||
return _idx > -1
|
||||
})
|
||||
if (isAllSelected) {
|
||||
xTable.setCheckboxRow(this.currentSelected, false)
|
||||
getPropertyIcon(attr) {
|
||||
switch (attr.value_type) {
|
||||
case '0':
|
||||
return 'duose-shishu'
|
||||
case '1':
|
||||
return 'duose-fudianshu'
|
||||
case '2':
|
||||
if (attr.is_password) {
|
||||
return 'duose-password'
|
||||
}
|
||||
if (attr.is_link) {
|
||||
return 'duose-link'
|
||||
}
|
||||
return 'duose-wenben'
|
||||
case '3':
|
||||
return 'duose-datetime'
|
||||
case '4':
|
||||
return 'duose-date'
|
||||
case '5':
|
||||
return 'duose-time'
|
||||
case '6':
|
||||
return 'duose-json'
|
||||
case '7':
|
||||
return 'duose-password'
|
||||
case '8':
|
||||
return 'duose-link'
|
||||
}
|
||||
this.currentSelected = []
|
||||
this.lastSelected = []
|
||||
this.$emit('checkbox-range-end', {
|
||||
...e,
|
||||
records: [...xTable.getCheckboxRecords(), ...xTable.getCheckboxReserveRecords()],
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
||||
<style></style>
|
||||
|
@@ -64,7 +64,7 @@ export default {
|
||||
},
|
||||
triggerColor: {
|
||||
type: String,
|
||||
default: '#f0f2f5',
|
||||
default: '#f7f8fa',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
|
@@ -35,7 +35,7 @@ export default {
|
||||
},
|
||||
triggerColor: {
|
||||
type: String,
|
||||
default: '#F0F5FF',
|
||||
default: '#f7f8fa',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
@@ -52,22 +52,22 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import '~@/style/static.less';
|
||||
|
||||
.two-column-layout {
|
||||
margin-bottom: -24px;
|
||||
width: 100%;
|
||||
.two-column-layout-sidebar {
|
||||
height: 100%;
|
||||
padding: 15px 7px;
|
||||
border-radius: 15px;
|
||||
overflow-y: auto;
|
||||
background-color: #fff;
|
||||
}
|
||||
.two-column-layout-main {
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
background-color: #fff;
|
||||
overflow-y: auto;
|
||||
border-radius: 15px;
|
||||
border-radius: @border-radius-box;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -11,9 +11,9 @@
|
||||
:key="route.name"
|
||||
@click="() => handleClick(route)"
|
||||
>
|
||||
{{ route.meta.title }}
|
||||
{{ $t(route.meta.title) }}
|
||||
</span>
|
||||
<!-- <a-popover v-model="visible" placement="bottom" trigger="click" overlayClassName="top-menu-dropdown">
|
||||
<a-popover v-model="visible" placement="bottom" trigger="click" overlayClassName="top-menu-dropdown">
|
||||
<template slot="content">
|
||||
<div class="title">
|
||||
更多应用
|
||||
@@ -36,20 +36,31 @@
|
||||
</div>
|
||||
</template>
|
||||
<span class="top-menu-icon"><gridSvg /></span>
|
||||
</a-popover> -->
|
||||
</a-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import store from '@/store'
|
||||
import { gridSvg, top_agent, top_acl } from '@/core/icons'
|
||||
import { getPreference } from '@/modules/cmdb/api/preference'
|
||||
export default {
|
||||
name: 'TopMenu',
|
||||
components: { gridSvg, top_agent, top_acl },
|
||||
data() {
|
||||
return {
|
||||
defaultShowRouteName: ['cmdb', 'acl'],
|
||||
defaultUnShowRouteName: [],
|
||||
defaultShowRouteName: [
|
||||
'dag',
|
||||
'cmdb',
|
||||
'itsm',
|
||||
'ticket',
|
||||
'monitor',
|
||||
'calendar',
|
||||
'datainsight',
|
||||
'fullscreen',
|
||||
'oneterm',
|
||||
],
|
||||
defaultUnShowRouteName: ['acl', 'agent'],
|
||||
routes: store.getters.appRoutes.filter((i) => !(i.meta || {}).hiddenInTopMenu),
|
||||
current: store.getters.appRoutes[0].name,
|
||||
visible: false,
|
||||
@@ -78,10 +89,20 @@ export default {
|
||||
this.current = this.$route.matched[0].name
|
||||
},
|
||||
methods: {
|
||||
handleClick(route) {
|
||||
async handleClick(route) {
|
||||
this.visible = false
|
||||
if (route.name !== this.current) {
|
||||
this.$router.push(route.redirect)
|
||||
if (route.name === 'cmdb') {
|
||||
const preference = await getPreference()
|
||||
const lastTypeId = window.localStorage.getItem('ops_ci_typeid') || undefined
|
||||
if (lastTypeId && preference.some((item) => item.id === Number(lastTypeId))) {
|
||||
this.$router.push(`/cmdb/instances/types/${lastTypeId}`)
|
||||
} else {
|
||||
this.$router.push('/cmdb/dashboard')
|
||||
}
|
||||
} else {
|
||||
this.$router.push(route.redirect)
|
||||
}
|
||||
// this.current = route.name
|
||||
}
|
||||
},
|
||||
@@ -110,33 +131,21 @@ export default {
|
||||
line-height: @layout-header-icon-height;
|
||||
border-radius: 4px !important;
|
||||
display: inline-flex;
|
||||
align-items: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
> span {
|
||||
cursor: pointer;
|
||||
padding: 4px 10px;
|
||||
margin: 0 5px;
|
||||
border-radius: 4px;
|
||||
color: @layout-header-font-color;
|
||||
height: @layout-header-height;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
&:hover {
|
||||
background: linear-gradient(0deg, rgba(0, 80, 201, 0.2) 0%, rgba(174, 207, 255, 0.06) 86.76%);
|
||||
color: @layout-header-font-selected-color;
|
||||
border-radius: 3px 3px 0px 0px;
|
||||
}
|
||||
}
|
||||
> span:hover,
|
||||
.top-menu-selected {
|
||||
background: linear-gradient(0deg, rgba(0, 80, 201, 0.2) 0%, rgba(174, 207, 255, 0.06) 86.76%);
|
||||
font-weight: bold;
|
||||
color: @layout-header-font-selected-color;
|
||||
border-radius: 3px 3px 0px 0px;
|
||||
border-bottom: 3px solid @layout-header-font-selected-color;
|
||||
&:hover {
|
||||
background: linear-gradient(0deg, rgba(0, 80, 201, 0.2) 0%, rgba(174, 207, 255, 0.06) 86.76%);
|
||||
color: @layout-header-font-selected-color;
|
||||
border-radius: 3px 3px 0px 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user