Merge pull request #564 from veops/dev_ui_ad_0624

feat: update ad ui
This commit is contained in:
Leo Song 2024-06-24 14:26:33 +08:00 committed by GitHub
commit 20f1e82ffa
17 changed files with 316 additions and 46 deletions

View File

@ -54,6 +54,24 @@
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe962;</span>
<div class="name">cmdb-enterprise_edition</div>
<div class="code-name">&amp;#xe962;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe961;</span>
<div class="name">ops-KVM</div>
<div class="code-name">&amp;#xe961;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe960;</span>
<div class="name">cmdb-vcenter</div>
<div class="code-name">&amp;#xe960;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe95f;</span>
<div class="name">cmdb-manual_warehousing</div>
@ -5178,9 +5196,9 @@
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1718872392430') format('woff2'),
url('iconfont.woff?t=1718872392430') format('woff'),
url('iconfont.ttf?t=1718872392430') format('truetype');
src: url('iconfont.woff2?t=1719208046306') format('woff2'),
url('iconfont.woff?t=1719208046306') format('woff'),
url('iconfont.ttf?t=1719208046306') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -5206,6 +5224,33 @@
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont cmdb-enterprise_edition"></span>
<div class="name">
cmdb-enterprise_edition
</div>
<div class="code-name">.cmdb-enterprise_edition
</div>
</li>
<li class="dib">
<span class="icon iconfont ops-KVM"></span>
<div class="name">
ops-KVM
</div>
<div class="code-name">.ops-KVM
</div>
</li>
<li class="dib">
<span class="icon iconfont cmdb-vcenter"></span>
<div class="name">
cmdb-vcenter
</div>
<div class="code-name">.cmdb-vcenter
</div>
</li>
<li class="dib">
<span class="icon iconfont cmdb-manual_warehousing"></span>
<div class="name">
@ -12892,6 +12937,30 @@
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#cmdb-enterprise_edition"></use>
</svg>
<div class="name">cmdb-enterprise_edition</div>
<div class="code-name">#cmdb-enterprise_edition</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#ops-KVM"></use>
</svg>
<div class="name">ops-KVM</div>
<div class="code-name">#ops-KVM</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#cmdb-vcenter"></use>
</svg>
<div class="name">cmdb-vcenter</div>
<div class="code-name">#cmdb-vcenter</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#cmdb-manual_warehousing"></use>

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3857903 */
src: url('iconfont.woff2?t=1718872392430') format('woff2'),
url('iconfont.woff?t=1718872392430') format('woff'),
url('iconfont.ttf?t=1718872392430') format('truetype');
src: url('iconfont.woff2?t=1719208046306') format('woff2'),
url('iconfont.woff?t=1719208046306') format('woff'),
url('iconfont.ttf?t=1719208046306') format('truetype');
}
.iconfont {
@ -13,6 +13,18 @@
-moz-osx-font-smoothing: grayscale;
}
.cmdb-enterprise_edition:before {
content: "\e962";
}
.ops-KVM:before {
content: "\e961";
}
.cmdb-vcenter:before {
content: "\e960";
}
.cmdb-manual_warehousing:before {
content: "\e95f";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,27 @@
"css_prefix_text": "",
"description": "",
"glyphs": [
{
"icon_id": "40834860",
"name": "cmdb-enterprise_edition",
"font_class": "cmdb-enterprise_edition",
"unicode": "e962",
"unicode_decimal": 59746
},
{
"icon_id": "40832458",
"name": "ops-KVM",
"font_class": "ops-KVM",
"unicode": "e961",
"unicode_decimal": 59745
},
{
"icon_id": "40822644",
"name": "cmdb-vcenter",
"font_class": "cmdb-vcenter",
"unicode": "e960",
"unicode_decimal": 59744
},
{
"icon_id": "40795271",
"name": "cmdb-manual_warehousing",

Binary file not shown.

View File

@ -45,9 +45,9 @@ export function getHttpAttributes(name, params) {
})
}
export function getSnmpAttributes(name) {
export function getSnmpAttributes(type, name) {
return axios({
url: `/v0.1/adr/snmp/${name}/attributes`,
url: `/v0.1/adr/${type}/${name}/attributes`,
method: 'GET',
})
}

View File

@ -3,19 +3,25 @@
<div class="http-ad-category-preview" v-if="currentCate">
<div class="category-side">
<div
v-for="category in categories"
v-for="(category, categoryIndex) in categories"
:key="category.category"
class="category-side-item"
>
<div class="category-side-title">{{ category.category }}</div>
<div class="category-side-children">
<div
v-for="item in category.items"
v-for="(item, itemIndex) in category.items"
:key="item"
:class="['category-side-children-item', item === currentCate ? 'category-side-children-item_active' : '']"
@click="clickCategory(item)"
>
{{ item }}
<span
class="category-side-children-item-corporate"
v-if="ruleType === 'private_cloud' || (ruleType === 'http' && (categoryIndex !== 0 || itemIndex !== 0))"
>
</span>
</div>
</div>
</div>
@ -35,19 +41,25 @@
/>
<div class="category-main">
<div
v-for="category in filterCategories"
v-for="(category, categoryIndex) in filterCategories"
:key="category.category"
class="category-item"
>
<div class="category-title">{{ category.category }}</div>
<div class="category-children">
<div
v-for="item in category.items"
v-for="(item, itemIndex) in category.items"
:key="item"
:class="['category-children-item', item === currentCate ? 'category-children-item_active' : '']"
@click="clickCategory(item)"
>
{{ item }}
<div
class="corporate-flag"
v-if="ruleType === 'private_cloud' || (ruleType === 'http' && (categoryIndex !== 0 || itemIndex !== 0))"
>
<span class="corporate-flag-text"></span>
</div>
</div>
</div>
</div>
@ -81,6 +93,10 @@ export default {
type: Array,
default: () => [],
},
ruleType: {
type: String,
default: 'http',
},
},
data() {
return {
@ -150,6 +166,11 @@ export default {
font-weight: 400;
cursor: pointer;
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
&:hover {
background-color: @layout-sidebar-selected-color;
@ -160,6 +181,20 @@ export default {
background-color: @layout-sidebar-selected-color;
color: @layout-header-font-selected-color;
}
&-corporate {
flex-shrink: 0;
width: 18px;
height: 18px;
background-color: #E1EFFF;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 50%;
color: #2F54EB;
font-size: 12px;
}
}
}
}
@ -201,6 +236,7 @@ export default {
font-weight: 400;
cursor: pointer;
position: relative;
&:hover {
background-color: @layout-sidebar-selected-color;
@ -219,5 +255,29 @@ export default {
.corporate-tip {
margin-top: 20px;
}
.corporate-flag {
position: absolute;
top: 0;
right: 0;
z-index: 4;
width: 38px;
height: 28px;
border-left: 38px solid transparent;
border-top: 28px solid @primary-color_4;
&-text {
width: 37px;
position: absolute;
top: -28px;
right: 3px;
text-align: right;
color: @primary-color;
font-size: 10px;
font-weight: 400;
}
}
}
</style>

View File

@ -1,14 +1,15 @@
<template>
<div class="http-snmp-ad">
<HttpADCategory
v-if="!isEdit && ruleType === 'http'"
v-if="!isEdit && isCloud"
:categories="categories"
:currentCate="currentCate"
:tableData="tableData"
:ruleType="ruleType"
@clickCategory="setCurrentCate"
/>
<template v-else>
<a-select v-if="ruleType === 'http'" :style="{ marginBottom: '10px' }" v-model="currentCate">
<a-select v-if="isCloud" :style="{ marginBottom: '10px' }" v-model="currentCate">
<a-select-option v-for="cate in categoriesSelect" :key="cate" :value="cate">{{ cate }}</a-select-option>
</a-select>
<AttrMapTable
@ -89,8 +90,13 @@ export default {
腾讯云: { name: 'tencentcloud' },
华为云: { name: 'huaweicloud' },
AWS: { name: 'aws' },
VCenter: { name: 'vcenter' },
KVM: { name: 'kvm' },
}
},
isCloud() {
return ['http', 'private_cloud'].includes(this.ruleType)
}
},
watch: {
currentCate: {
@ -113,8 +119,8 @@ export default {
this.currentCate = ''
this.$nextTick(() => {
const { ruleType, ruleName } = newVal
if (['snmp'].includes(ruleType) && ruleName) {
getSnmpAttributes(ruleName).then((res) => {
if (['snmp', 'components'].includes(ruleType) && ruleName) {
getSnmpAttributes(ruleType, ruleName).then((res) => {
if (this.isEdit) {
this.formatTableData(res)
} else {
@ -122,7 +128,8 @@ export default {
}
})
}
if (ruleType === 'http' && ruleName) {
if (this.isCloud && ruleName) {
getHttpCategories(this.httpMap[`${this.ruleName}`].name).then((res) => {
this.categories = res
const categoriesSelect = []

View File

@ -480,6 +480,8 @@ const cmdb_en = {
snmp: 'Network Devices',
http: 'Public Clouds',
plugin: 'Plugin',
component: 'Databases & Middleware',
privateCloud: 'Private Clouds',
rule: 'AutoDiscovery Rules',
timeout: 'Timeout error',
mode: 'Mode',

View File

@ -479,7 +479,8 @@ const cmdb_zh = {
agent: '服务器',
snmp: '网络设备',
http: '公有云',
plugin: '插件',
component: '数据库 & 中间件',
privateCloud: '私有云',
rule: '自动发现规则',
timeout: '超时错误',
mode: '模式',

View File

@ -104,22 +104,51 @@
</a-form-model-item>
</a-form-model>
<template v-if="adrType === 'http'">
<div class="attr-ad-header attr-ad-header-margin">{{ $t('cmdb.ciType.cloudAccessKey') }}</div>
<div class="public-cloud-info">{{ $t('cmdb.ciType.cloudAccessKeyTip') }}</div>
<a-form-model
:model="form2"
labelAlign="left"
:labelCol="labelCol"
:wrapperCol="{ span: 6 }"
class="attr-ad-form"
>
<a-form-model-item label="key">
<a-input-password v-model="form2.key" />
</a-form-model-item>
<a-form-model-item label="secret">
<a-input-password v-model="form2.secret" />
</a-form-model-item>
</a-form-model>
<template v-if="isVCenter">
<div class="attr-ad-header">私有云</div>
<a-form-model
:model="privateCloudForm"
labelAlign="left"
:labelCol="labelCol"
:wrapperCol="{ span: 6 }"
class="attr-ad-form"
>
<a-form-model-item label="地址">
<a-input v-model="privateCloudForm.host" />
</a-form-model-item>
<a-form-model-item label="账号">
<a-input v-model="privateCloudForm.account" />
</a-form-model-item>
<a-form-model-item label="密码">
<a-input-password v-model="privateCloudForm.password" />
</a-form-model-item>
<a-form-model-item label="是否证书验证">
<a-switch v-model="privateCloudForm.insecure" />
</a-form-model-item>
<a-form-model-item label="虚拟平台名">
<a-input v-model="privateCloudForm.vcenterName" />
</a-form-model-item>
</a-form-model>
</template>
<template v-else>
<div class="attr-ad-header">{{ $t('cmdb.ciType.cloudAccessKey') }}</div>
<!-- <div class="public-cloud-info">{{ $t('cmdb.ciType.cloudAccessKeyTip') }}</div> -->
<a-form-model
:model="form2"
labelAlign="left"
:labelCol="labelCol"
:wrapperCol="{ span: 6 }"
class="attr-ad-form"
>
<a-form-model-item label="key">
<a-input-password v-model="form2.key" />
</a-form-model-item>
<a-form-model-item label="secret">
<a-input-password v-model="form2.secret" />
</a-form-model-item>
</a-form-model>
</template>
</template>
<AttrADTest
@ -199,6 +228,13 @@ export default {
key: '',
secret: '',
},
privateCloudForm: {
host: '',
account: '',
password: '',
insecure: false,
vcenterName: '',
},
interval: 'cron', // interval cron
cron: '',
intervalValue: 3,
@ -214,6 +250,7 @@ export default {
form3: this.$form.createForm(this, { name: 'snmp_form' }),
cronVisible: false,
uniqueKey: '',
isVCenter: false,
}
},
computed: {
@ -264,11 +301,34 @@ export default {
this.uniqueKey = _find?.unique_key ?? ''
if (this.adrType === 'http') {
const { category = undefined, key = '', secret = '' } = _findADT?.extra_option ?? {}
this.form2 = {
key,
secret,
const {
category = undefined,
key = '',
secret = '',
host = '',
account = '',
password = '',
insecure = false,
vcenterName = ''
} = _findADT?.extra_option ?? {}
if (_find?.name === 'VCenter') {
this.isVCenter = true
this.privateCloudForm = {
host,
account,
password,
insecure,
vcenterName,
}
} else {
this.isVCenter = false
this.form2 = {
key,
secret,
}
}
this.$refs.httpSnmpAd.setCurrentCate(category)
}
if (this.adrType === 'snmp') {
@ -332,7 +392,7 @@ export default {
if (this.adrType === 'http') {
params = {
extra_option: {
...this.form2,
...(this.isVCenter ? this.privateCloudForm : this.form2),
category: this.$refs.httpSnmpAd.currentCate,
},
}

View File

@ -2,5 +2,7 @@ export const DISCOVERY_CATEGORY_TYPE = {
AGENT: 'agent',
SNMP: 'snmp',
HTTP: 'http',
PLUGIN: 'plugin'
PLUGIN: 'plugin',
COMPONENT: 'components',
PRIVATE_CLOUD: 'private_cloud'
}

View File

@ -53,11 +53,12 @@
:key="index"
v-if="index < 2"
class="discovery-resources-item"
:style="{ maxWidth: rule.resources.length >= 2 ? '70px' : '160px' }"
>
{{ item }}
</span>
</template>
<span v-if="rule.resources.length >= 2" class="discovery-resources-item">
<span v-if="rule.resources.length > 2" class="discovery-resources-item">
<ops-icon type="veops-more" />
</span>
</div>
@ -234,6 +235,7 @@ export default {
color: @text-color_3;
font-size: 12px;
font-weight: 400;
flex-shrink: 0;
}
&-right {
@ -249,7 +251,6 @@ export default {
color: @text-color_3;
font-size: 11px;
font-weight: 400;
max-width: 95px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;

View File

@ -171,7 +171,7 @@ export default {
},
computed: {
title() {
if ([DISCOVERY_CATEGORY_TYPE.HTTP, DISCOVERY_CATEGORY_TYPE.SNMP, DISCOVERY_CATEGORY_TYPE.AGENT].includes(this.adType)) {
if ([DISCOVERY_CATEGORY_TYPE.HTTP, DISCOVERY_CATEGORY_TYPE.SNMP, DISCOVERY_CATEGORY_TYPE.AGENT, DISCOVERY_CATEGORY_TYPE.PRIVATE_CLOUD, DISCOVERY_CATEGORY_TYPE.COMPONENT].includes(this.adType)) {
return this.ruleData.name
}
if (this.type === 'edit') {
@ -202,7 +202,7 @@ export default {
return
}
this.$nextTick(() => {
if (adType === DISCOVERY_CATEGORY_TYPE.AGENT) {
if ([DISCOVERY_CATEGORY_TYPE.HTTP, DISCOVERY_CATEGORY_TYPE.SNMP, DISCOVERY_CATEGORY_TYPE.PRIVATE_CLOUD].includes(adType)) {
this.tableData = data?.attributes ?? []
return
}

View File

@ -39,7 +39,10 @@
</a>
</div>
</div>
<div class="setting-discovery-body">
<div
class="setting-discovery-body"
:style="{ height: !isSelected ? `${windowHeight - 155}px` : '' }"
>
<template v-if="!showNullData">
<div v-for="{ type, label } in typeCategory" :key="type">
<template v-if="filterCategoryChildren[type] && (filterCategoryChildren[type].children.length || (showAddPlugin && type === DISCOVERY_CATEGORY_TYPE.PLUGIN))">
@ -79,6 +82,7 @@
</template>
<script>
import { mapState } from 'vuex'
import _ from 'lodash'
import { getDiscovery, deleteDiscovery } from '../../api/discovery'
import { DISCOVERY_CATEGORY_TYPE } from './constants.js'
@ -103,16 +107,27 @@ export default {
}
},
computed: {
...mapState({
windowHeight: (state) => state.windowHeight,
}),
typeCategory() {
return [
{
type: DISCOVERY_CATEGORY_TYPE.HTTP,
label: this.$t('cmdb.ad.http'),
},
{
type: DISCOVERY_CATEGORY_TYPE.PRIVATE_CLOUD,
label: this.$t('cmdb.ad.privateCloud'),
},
{
type: DISCOVERY_CATEGORY_TYPE.AGENT,
label: this.$t('cmdb.ad.agent'),
},
{
type: DISCOVERY_CATEGORY_TYPE.COMPONENT,
label: this.$t('cmdb.ad.component'),
},
{
type: DISCOVERY_CATEGORY_TYPE.SNMP,
label: this.$t('cmdb.ad.snmp'),
@ -162,10 +177,18 @@ export default {
type: DISCOVERY_CATEGORY_TYPE.HTTP,
children: []
},
[DISCOVERY_CATEGORY_TYPE.PRIVATE_CLOUD]: {
type: DISCOVERY_CATEGORY_TYPE.PRIVATE_CLOUD,
children: []
},
[DISCOVERY_CATEGORY_TYPE.AGENT]: {
type: DISCOVERY_CATEGORY_TYPE.AGENT,
children: []
},
[DISCOVERY_CATEGORY_TYPE.COMPONENT]: {
type: DISCOVERY_CATEGORY_TYPE.COMPONENT,
children: []
},
[DISCOVERY_CATEGORY_TYPE.SNMP]: {
type: DISCOVERY_CATEGORY_TYPE.SNMP,
children: []
@ -179,6 +202,12 @@ export default {
this.typeCategory.forEach(({ type }) => {
let categoryChildren = []
switch (type) {
case DISCOVERY_CATEGORY_TYPE.PRIVATE_CLOUD:
categoryChildren = res.filter((list) => list?.option?.category === 'private_cloud' && list?.type === 'http')
break
case DISCOVERY_CATEGORY_TYPE.HTTP:
categoryChildren = res.filter((list) => list?.option?.category !== 'private_cloud' && list?.type === 'http')
break
case DISCOVERY_CATEGORY_TYPE.PLUGIN:
categoryChildren = res.filter((list) => list.is_plugin)
break
@ -269,6 +298,8 @@ export default {
display: flex;
align-items: center;
gap: 14px;
flex-shrink: 0;
margin-left: 20px;
&-btn {
display: flex;
@ -284,6 +315,7 @@ export default {
&-search {
width: 254px;
flex-shrink: 0;
}
&-radio {
@ -291,6 +323,7 @@ export default {
align-items: center;
margin-left: 15px;
gap: 15px;
overflow: auto;
&-item {
padding: 4px 14px;
@ -298,6 +331,7 @@ export default {
font-weight: 400;
line-height: 24px;
cursor: pointer;
flex-shrink: 0;
&_active {
background-color: @primary-color_3;
@ -312,6 +346,7 @@ export default {
box-shadow: 0px 0px 4px 0px rgba(158, 171, 190, 0.25);
padding: 20px;
margin-top: 24px;
overflow: auto;
.setting-discovery-add {
height: 105px;