feat(ui): add SplitPane calcBasedParent prop

This commit is contained in:
songlh 2024-09-09 10:44:58 +08:00
parent 478e9519e8
commit ef8ddeebe7
14 changed files with 413 additions and 192 deletions

View File

@ -54,6 +54,42 @@
<div class="content unicode" style="display: block;"> <div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe9c6;</span>
<div class="name">oneterm-connect</div>
<div class="code-name">&amp;#xe9c6;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9c7;</span>
<div class="name">oneterm-session</div>
<div class="code-name">&amp;#xe9c7;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9c8;</span>
<div class="name">oneterm-assets</div>
<div class="code-name">&amp;#xe9c8;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9c3;</span>
<div class="name">oneterm-RDP</div>
<div class="code-name">&amp;#xe9c3;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9c4;</span>
<div class="name">oneterm-SSH</div>
<div class="code-name">&amp;#xe9c4;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe9c5;</span>
<div class="name">oneterm-VNC</div>
<div class="code-name">&amp;#xe9c5;</div>
</li>
<li class="dib"> <li class="dib">
<span class="icon iconfont">&#xe9c2;</span> <span class="icon iconfont">&#xe9c2;</span>
<div class="name">caise-websphere</div> <div class="name">caise-websphere</div>
@ -5772,9 +5808,9 @@
<pre><code class="language-css" <pre><code class="language-css"
>@font-face { >@font-face {
font-family: 'iconfont'; font-family: 'iconfont';
src: url('iconfont.woff2?t=1725351982733') format('woff2'), src: url('iconfont.woff2?t=1725846934130') format('woff2'),
url('iconfont.woff?t=1725351982733') format('woff'), url('iconfont.woff?t=1725846934130') format('woff'),
url('iconfont.ttf?t=1725351982733') format('truetype'); url('iconfont.ttf?t=1725846934130') format('truetype');
} }
</code></pre> </code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3> <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@ -5800,6 +5836,60 @@
<div class="content font-class"> <div class="content font-class">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont oneterm-connect1"></span>
<div class="name">
oneterm-connect
</div>
<div class="code-name">.oneterm-connect1
</div>
</li>
<li class="dib">
<span class="icon iconfont oneterm-session1"></span>
<div class="name">
oneterm-session
</div>
<div class="code-name">.oneterm-session1
</div>
</li>
<li class="dib">
<span class="icon iconfont oneterm-assets"></span>
<div class="name">
oneterm-assets
</div>
<div class="code-name">.oneterm-assets
</div>
</li>
<li class="dib">
<span class="icon iconfont a-oneterm-ssh1"></span>
<div class="name">
oneterm-RDP
</div>
<div class="code-name">.a-oneterm-ssh1
</div>
</li>
<li class="dib">
<span class="icon iconfont a-oneterm-ssh2"></span>
<div class="name">
oneterm-SSH
</div>
<div class="code-name">.a-oneterm-ssh2
</div>
</li>
<li class="dib">
<span class="icon iconfont oneterm-rdp"></span>
<div class="name">
oneterm-VNC
</div>
<div class="code-name">.oneterm-rdp
</div>
</li>
<li class="dib"> <li class="dib">
<span class="icon iconfont caise-websphere"></span> <span class="icon iconfont caise-websphere"></span>
<div class="name"> <div class="name">
@ -14377,6 +14467,54 @@
<div class="content symbol"> <div class="content symbol">
<ul class="icon_lists dib-box"> <ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#oneterm-connect1"></use>
</svg>
<div class="name">oneterm-connect</div>
<div class="code-name">#oneterm-connect1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#oneterm-session1"></use>
</svg>
<div class="name">oneterm-session</div>
<div class="code-name">#oneterm-session1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#oneterm-assets"></use>
</svg>
<div class="name">oneterm-assets</div>
<div class="code-name">#oneterm-assets</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#a-oneterm-ssh1"></use>
</svg>
<div class="name">oneterm-RDP</div>
<div class="code-name">#a-oneterm-ssh1</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#a-oneterm-ssh2"></use>
</svg>
<div class="name">oneterm-SSH</div>
<div class="code-name">#a-oneterm-ssh2</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#oneterm-rdp"></use>
</svg>
<div class="name">oneterm-VNC</div>
<div class="code-name">#oneterm-rdp</div>
</li>
<li class="dib"> <li class="dib">
<svg class="icon svg-icon" aria-hidden="true"> <svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#caise-websphere"></use> <use xlink:href="#caise-websphere"></use>

View File

@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 3857903 */ font-family: "iconfont"; /* Project id 3857903 */
src: url('iconfont.woff2?t=1725351982733') format('woff2'), src: url('iconfont.woff2?t=1725846934130') format('woff2'),
url('iconfont.woff?t=1725351982733') format('woff'), url('iconfont.woff?t=1725846934130') format('woff'),
url('iconfont.ttf?t=1725351982733') format('truetype'); url('iconfont.ttf?t=1725846934130') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,30 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.oneterm-connect1:before {
content: "\e9c6";
}
.oneterm-session1:before {
content: "\e9c7";
}
.oneterm-assets:before {
content: "\e9c8";
}
.a-oneterm-ssh1:before {
content: "\e9c3";
}
.a-oneterm-ssh2:before {
content: "\e9c4";
}
.oneterm-rdp:before {
content: "\e9c5";
}
.caise-websphere:before { .caise-websphere:before {
content: "\e9c2"; content: "\e9c2";
} }

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,48 @@
"css_prefix_text": "", "css_prefix_text": "",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "41735717",
"name": "oneterm-connect",
"font_class": "oneterm-connect1",
"unicode": "e9c6",
"unicode_decimal": 59846
},
{
"icon_id": "41735716",
"name": "oneterm-session",
"font_class": "oneterm-session1",
"unicode": "e9c7",
"unicode_decimal": 59847
},
{
"icon_id": "41735703",
"name": "oneterm-assets",
"font_class": "oneterm-assets",
"unicode": "e9c8",
"unicode_decimal": 59848
},
{
"icon_id": "41725683",
"name": "oneterm-RDP",
"font_class": "a-oneterm-ssh1",
"unicode": "e9c3",
"unicode_decimal": 59843
},
{
"icon_id": "41725684",
"name": "oneterm-SSH",
"font_class": "a-oneterm-ssh2",
"unicode": "e9c4",
"unicode_decimal": 59844
},
{
"icon_id": "41725685",
"name": "oneterm-VNC",
"font_class": "oneterm-rdp",
"unicode": "e9c5",
"unicode_decimal": 59845
},
{ {
"icon_id": "41724497", "icon_id": "41724497",
"name": "caise-websphere", "name": "caise-websphere",

Binary file not shown.

View File

@ -1,183 +1,187 @@
<template> <template>
<div ref="splitPane" class="split-pane" :class="direction + ' ' + appName" :style="{ flexDirection: direction }"> <div ref="splitPane" class="split-pane" :class="direction + ' ' + appName" :style="{ flexDirection: direction }">
<div class="pane pane-one" ref="one" :style="lengthType + ':' + paneLengthValue1"> <div class="pane pane-one" ref="one" :style="lengthType + ':' + paneLengthValue1">
<slot name="one"></slot> <slot name="one"></slot>
</div> </div>
<div class="spliter-wrap"> <div class="spliter-wrap">
<a-button <a-button
v-show="collapsable" v-show="collapsable"
:icon="isExpanded ? 'left' : 'right'" :icon="isExpanded ? 'left' : 'right'"
class="collapse-btn" class="collapse-btn"
@click="handleExpand" @click="handleExpand"
></a-button> ></a-button>
<div <div
class="pane-trigger" class="pane-trigger"
@mousedown="handleMouseDown" @mousedown="handleMouseDown"
:style="{ backgroundColor: triggerColor, width: `${triggerLength}px` }" :style="{ backgroundColor: triggerColor, width: `${triggerLength}px` }"
></div> ></div>
</div> </div>
<div class="pane pane-two" ref="two" :style="lengthType + ':' + paneLengthValue2"> <div class="pane pane-two" ref="two" :style="lengthType + ':' + paneLengthValue2">
<slot name="two"></slot> <slot name="two"></slot>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: 'SplitPane', name: 'SplitPane',
props: { props: {
direction: { direction: {
type: String, type: String,
default: 'row', default: 'row',
}, },
min: { min: {
type: Number, type: Number,
default: 10, default: 10,
}, },
max: { max: {
type: Number, type: Number,
default: 90, default: 90,
}, },
paneLengthPixel: { paneLengthPixel: {
type: Number, type: Number,
default: 220, default: 220,
}, },
triggerLength: { triggerLength: {
type: Number, type: Number,
default: 8, default: 8,
}, },
appName: { appName: {
type: String, type: String,
default: 'viewer', default: 'viewer',
}, },
collapsable: { collapsable: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
triggerColor: { triggerColor: {
type: String, type: String,
default: '#f7f8fa', default: '#f7f8fa',
}, },
}, calcBasedParent: {
data() { type: Boolean,
return { defualt: false
triggerLeftOffset: 0, // 鼠标距滑动器左()侧偏移量 }
isExpanded: localStorage.getItem(`${this.appName}-isExpanded`) },
? JSON.parse(localStorage.getItem(`${this.appName}-isExpanded`)) data() {
: false, return {
parentContainer: null, triggerLeftOffset: 0, // 鼠标距滑动器左()侧偏移量
} isExpanded: localStorage.getItem(`${this.appName}-isExpanded`)
}, ? JSON.parse(localStorage.getItem(`${this.appName}-isExpanded`))
computed: { : false,
lengthType() { parentContainer: null,
return this.direction === 'row' ? 'width' : 'height' }
}, },
computed: {
minLengthType() { lengthType() {
return this.direction === 'row' ? 'minWidth' : 'minHeight' return this.direction === 'row' ? 'width' : 'height'
}, },
paneLengthValue1() { minLengthType() {
return `calc(${this.paneLengthPercent}% - ${this.triggerLength / 2 + 'px'})` return this.direction === 'row' ? 'minWidth' : 'minHeight'
}, },
paneLengthValue2() { paneLengthValue1() {
const rest = 100 - this.paneLengthPercent return `calc(${this.paneLengthPercent}% - ${this.triggerLength / 2 + 'px'})`
return `calc(${rest}% - ${this.triggerLength / 2 + 'px'})` },
},
paneLengthValue2() {
paneLengthPercent() { const rest = 100 - this.paneLengthPercent
const clientRectWidth = this.parentContainer return `calc(${rest}% - ${this.triggerLength / 2 + 'px'})`
? this.parentContainer.clientWidth },
: document.documentElement.getBoundingClientRect().width
return (this.paneLengthPixel / clientRectWidth) * 100 paneLengthPercent() {
}, const clientRectWidth = this.parentContainer && this.calcBasedParent
}, ? this.parentContainer.clientWidth
: document.documentElement.getBoundingClientRect().width
watch: { return (this.paneLengthPixel / clientRectWidth) * 100
isExpanded(newValue) { },
if (newValue) { },
document.querySelector(`.${this.appName} .pane-two`).style.display = 'none'
} else { watch: {
document.querySelector(`.${this.appName} .pane-two`).style.display = '' isExpanded(newValue) {
} if (newValue) {
}, document.querySelector(`.${this.appName} .pane-two`).style.display = 'none'
}, } else {
document.querySelector(`.${this.appName} .pane-two`).style.display = ''
mounted() { }
const paneLengthPixel = localStorage.getItem(`${this.appName}-paneLengthPixel`) },
if (paneLengthPixel) { },
this.$emit('update:paneLengthPixel', Number(paneLengthPixel))
} mounted() {
this.parentContainer = document.querySelector(`.${this.appName}`) const paneLengthPixel = localStorage.getItem(`${this.appName}-paneLengthPixel`)
if (this.isExpanded) { if (paneLengthPixel) {
document.querySelector(`.${this.appName} .pane-two`).style.display = 'none' this.$emit('update:paneLengthPixel', Number(paneLengthPixel))
} else { }
document.querySelector(`.${this.appName} .pane-two`).style.display = '' this.parentContainer = document.querySelector(`.${this.appName}`)
} if (this.isExpanded) {
}, document.querySelector(`.${this.appName} .pane-two`).style.display = 'none'
} else {
methods: { document.querySelector(`.${this.appName} .pane-two`).style.display = ''
// 按下滑动器 }
handleMouseDown(e) { },
document.addEventListener('mousemove', this.handleMouseMove)
document.addEventListener('mouseup', this.handleMouseUp) methods: {
if (this.direction === 'row') { // 按下滑动器
this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left handleMouseDown(e) {
} else { document.addEventListener('mousemove', this.handleMouseMove)
this.triggerLeftOffset = e.pageY - e.srcElement.getBoundingClientRect().top document.addEventListener('mouseup', this.handleMouseUp)
} if (this.direction === 'row') {
}, this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left
} else {
// 按下滑动器后移动鼠标 this.triggerLeftOffset = e.pageY - e.srcElement.getBoundingClientRect().top
handleMouseMove(e) { }
this.isExpanded = false },
this.$emit('expand', this.isExpanded)
const clientRect = this.$refs.splitPane.getBoundingClientRect() // 按下滑动器后移动鼠标
let paneLengthPixel = 0 handleMouseMove(e) {
this.isExpanded = false
if (this.direction === 'row') { this.$emit('expand', this.isExpanded)
const offset = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2 const clientRect = this.$refs.splitPane.getBoundingClientRect()
paneLengthPixel = offset let paneLengthPixel = 0
} else {
const offset = e.pageY - clientRect.top - this.triggerLeftOffset + this.triggerLength / 2 if (this.direction === 'row') {
paneLengthPixel = offset const offset = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
} paneLengthPixel = offset
} else {
if (paneLengthPixel < this.min) { const offset = e.pageY - clientRect.top - this.triggerLeftOffset + this.triggerLength / 2
paneLengthPixel = this.min paneLengthPixel = offset
} }
if (paneLengthPixel > this.max) {
paneLengthPixel = this.max if (paneLengthPixel < this.min) {
} paneLengthPixel = this.min
}
this.$emit('update:paneLengthPixel', paneLengthPixel) if (paneLengthPixel > this.max) {
paneLengthPixel = this.max
localStorage.setItem(`${this.appName}-paneLengthPixel`, paneLengthPixel) }
},
this.$emit('update:paneLengthPixel', paneLengthPixel)
// 松开滑动器
handleMouseUp() { localStorage.setItem(`${this.appName}-paneLengthPixel`, paneLengthPixel)
document.removeEventListener('mousemove', this.handleMouseMove) },
},
// 松开滑动器
handleExpand() { handleMouseUp() {
this.isExpanded = !this.isExpanded document.removeEventListener('mousemove', this.handleMouseMove)
this.$emit('expand', this.isExpanded) },
localStorage.setItem(`${this.appName}-isExpanded`, this.isExpanded)
}, handleExpand() {
}, this.isExpanded = !this.isExpanded
} this.$emit('expand', this.isExpanded)
</script> localStorage.setItem(`${this.appName}-isExpanded`, this.isExpanded)
},
<style scoped lang="less"> },
@import './index.less'; }
</style> </script>
<style scoped lang="less">
@import './index.less';
</style>

View File

@ -6,7 +6,8 @@
:paneLengthPixel.sync="paneLengthPixel" :paneLengthPixel.sync="paneLengthPixel"
:appName="appName" :appName="appName"
:triggerColor="triggerColor" :triggerColor="triggerColor"
:triggerLength="18" :triggerLength="triggerLength"
:calcBasedParent="calcBasedParent"
> >
<template #one> <template #one>
<div class="two-column-layout-sidebar"> <div class="two-column-layout-sidebar">
@ -37,6 +38,14 @@ export default {
type: String, type: String,
default: '#f7f8fa', default: '#f7f8fa',
}, },
triggerLength: {
type: Number,
default: 18
},
calcBasedParent: {
type: Boolean,
defualt: false
}
}, },
data() { data() {
return { return {

View File

@ -13,6 +13,7 @@
:paneLengthPixel.sync="paneLengthPixel" :paneLengthPixel.sync="paneLengthPixel"
appName="cmdb-ci-types" appName="cmdb-ci-types"
:triggerLength="18" :triggerLength="18"
calcBasedParent
> >
<template #one> <template #one>
<div class="ci-types-left"> <div class="ci-types-left">

View File

@ -1,5 +1,5 @@
<template> <template>
<TwoColumnLayout appName="cmdb-adc"> <TwoColumnLayout appName="cmdb-adc" calcBasedParent>
<template #one> <template #one>
<div class="cmdb-adc-group" v-for="group in ci_types_list" :key="group.id"> <div class="cmdb-adc-group" v-for="group in ci_types_list" :key="group.id">
<p> <p>

View File

@ -7,6 +7,7 @@
:paneLengthPixel.sync="paneLengthPixel" :paneLengthPixel.sync="paneLengthPixel"
:appName="`cmdb-relation-views-${viewId}`" :appName="`cmdb-relation-views-${viewId}`"
:triggerLength="18" :triggerLength="18"
calcBasedParent
> >
<template #one> <template #one>
<div class="relation-views-left" :style="{ height: `${windowHeight - 64}px` }"> <div class="relation-views-left" :style="{ height: `${windowHeight - 64}px` }">

View File

@ -15,6 +15,7 @@
:paneLengthPixel.sync="paneLengthPixel" :paneLengthPixel.sync="paneLengthPixel"
appName="cmdb-topo-views" appName="cmdb-topo-views"
:triggerLength="18" :triggerLength="18"
calcBasedParent
> >
<template #one> <template #one>
<a-input <a-input

View File

@ -10,6 +10,7 @@
:paneLengthPixel.sync="paneLengthPixel" :paneLengthPixel.sync="paneLengthPixel"
appName="cmdb-tree-views" appName="cmdb-tree-views"
:triggerLength="18" :triggerLength="18"
calcBasedParent
> >
<template #one> <template #one>
<div class="tree-views-left" :style="{ height: `${windowHeight - 64}px` }"> <div class="tree-views-left" :style="{ height: `${windowHeight - 64}px` }">