NEZ-2498 feat:terminal select asset样式调整
This commit is contained in:
@@ -96,6 +96,64 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.webshell-selectAsset{
|
||||
.el-dialog__header{
|
||||
box-sizing: border-box;
|
||||
height: 48px;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
border-bottom: 1px solid $--web-ssh-border-bottom-color2;
|
||||
.el-dialog__headerbtn{
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.header-el-dropdown{
|
||||
width: 86px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border: 1px solid $--border-color-light;
|
||||
border-right: none;
|
||||
box-sizing: border-box;
|
||||
padding: 0 8px;
|
||||
.el-dropdown-link{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
& span:first-of-type{
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
i.el-icon--right{
|
||||
margin-left: 0;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
.header-el-dropdown+.el-input{
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
.el-dialog__footer{
|
||||
padding: 15px 20px;
|
||||
border-top: 1px solid $--web-ssh-border-bottom-color2;
|
||||
.footer__btn{
|
||||
margin: 0;
|
||||
&.webshell-btn-disable{
|
||||
background: $--background-color-base;
|
||||
color: $--web-ssh-color-text-disable;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
.footer__btn--light{
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.webTerminal{
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
.selectTable{
|
||||
.selectTable-search-input{
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
.el-input{
|
||||
position: relative;
|
||||
flex: 1;
|
||||
input{
|
||||
border: 1px solid $--border-color-light;
|
||||
box-sizing: border-box;
|
||||
padding-right: 36px;
|
||||
}
|
||||
.el-input__suffix{
|
||||
right: 0;
|
||||
.el-input__suffix-inner{
|
||||
width: 36px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-table {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
th,tr,td{
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
th.is-leaf{
|
||||
border-bottom: none;
|
||||
}
|
||||
th.gutter {
|
||||
display: table-cell !important;
|
||||
}
|
||||
&::before {
|
||||
height: 0px;
|
||||
}
|
||||
&::after {
|
||||
width: 0;
|
||||
}
|
||||
.el-table__fixed:before {
|
||||
height: 0;
|
||||
}
|
||||
&.el-table--enable-row-hover .el-table__body tr:hover>td{
|
||||
background-color: $--table-row-hover-background-color;
|
||||
}
|
||||
.el-table__row.row-selected{
|
||||
background-color: $--table-row-hover-background-color;
|
||||
color: #FA901C;
|
||||
}
|
||||
}
|
||||
.pagination{
|
||||
padding: 5px 0;
|
||||
border-top: 1px solid $--select-table-border-color;
|
||||
}
|
||||
}
|
||||
@@ -120,6 +120,7 @@
|
||||
@import './page/tool/trace.scss';
|
||||
|
||||
@import './common/v-selectpagenew/selectpage.scss';
|
||||
@import './common/selectTable.scss';
|
||||
@import './common/paramBpx/paramBox.scss';
|
||||
@import './common/picker/picker.scss';
|
||||
@import './common/threshold/threshold.scss';
|
||||
|
||||
@@ -235,6 +235,11 @@ $--alert-rule-color: $--background-color-base;
|
||||
/* webSSH */
|
||||
$--web-ssh-background-color: $--background-color-disabled;
|
||||
$--web-ssh-border-bottom-color: $--background-color-copy;
|
||||
$--web-ssh-border-bottom-color2: #19191C;
|
||||
$--web-ssh-color-text-disable: #666666;
|
||||
|
||||
/* selectTable */
|
||||
$--select-table-border-color:rgba(0,0,0,0.18);
|
||||
|
||||
/* 图表弹框 */
|
||||
$--chart-background-color: $--background-color-empty;
|
||||
|
||||
@@ -231,6 +231,11 @@ $--alert-rule-color: $--overview-icon-color;
|
||||
/* webSSH */
|
||||
$--web-ssh-background-color: $--color-text-label;
|
||||
$--web-ssh-border-bottom-color: transparent;
|
||||
$--web-ssh-border-bottom-color2: #E7EAED;
|
||||
$--web-ssh-color-text-disable: #BEBEBE;
|
||||
|
||||
/* selectTable */
|
||||
$--select-table-border-color:rgba(0,0,0,0.03);
|
||||
|
||||
/* 图表弹框 */
|
||||
$--chart-background-color: #dde4ed;
|
||||
|
||||
@@ -88,43 +88,38 @@
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<!--弹窗-->
|
||||
<el-dialog :modal-append-to-body='false' :show-close="true" :visible.sync="assetShow" @close="closeAssetCustom" class="nz-dialog" width="620px">
|
||||
<div slot="title">{{$t('webshell.connect')}}</div>
|
||||
<div >
|
||||
<el-form label-width="120px" size="small" :model="assetContent" label-position = "top" :rules="rules" ref="assetConnect" v-my-loading="assetLoading" >
|
||||
<el-form-item :label='$t("overall.asset")' prop="assetId" class="flex">
|
||||
<el-dialog :modal-append-to-body='false' :show-close="true" :visible.sync="assetShow" @close="closeAssetCustom" class="nz-dialog webshell-selectAsset" width="620px">
|
||||
<div slot="title">{{$t('webshell.selAsset')}}</div>
|
||||
<selectTable ref="selectTable" v-model="assetContent.assetId" :params="selectPageParams" :columns="columns" :tableFormat="tableFormat" api="asset/asset" value-key="id" search-key="manageIp">
|
||||
<template v-slot:searchLeft>
|
||||
<el-dropdown trigger="click" class="header-el-dropdown">
|
||||
<span class="el-dropdown-link">
|
||||
<span>{{selectValue}}</span>
|
||||
<span><i class="el-icon-arrow-down el-icon--right"></i></span>
|
||||
</span>
|
||||
<el-dropdown-menu style="width: 118px" class="el-dropdown__width right-box-select-top right-public-box-dropdown-top" placement="bottom-end" slot="dropdown">
|
||||
<el-dropdown-menu style="width: 80px" class="el-dropdown__width right-box-select-top right-public-box-dropdown-top" placement="bottom-end" slot="dropdown">
|
||||
<el-dropdown-item
|
||||
@click.native="selectAssetAuth(item.label, item.value)"
|
||||
v-for="item in searchMetrics"
|
||||
:key="item.value"><i class="nz-icon" :class="item.icon" style="margin-right: 5px"/>{{item.label}}</el-dropdown-item>
|
||||
:key="item.value"
|
||||
style="padding:0px 10px"
|
||||
>
|
||||
<i class="nz-icon" :class="item.icon" style="margin-right: 5px"/>{{item.label}}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<v-selectpage
|
||||
ref="selectPage"
|
||||
style="flex: 1"
|
||||
data="asset/asset"
|
||||
:params="selectPageParams"
|
||||
:tb-columns="columns"
|
||||
key-field="id"
|
||||
show-field="manageIp"
|
||||
search-field="manageIp"
|
||||
v-model="assetContent.assetId"
|
||||
size="small"
|
||||
:language="language"
|
||||
:placeholder="$t('dashboard.panel.chartForm.selectAsset')"
|
||||
id="box-input-asset-id"
|
||||
:result-format="resultFormat"></v-selectpage>
|
||||
<button :disabled="prevent_opt.save" class="nz-btn nz-btn-size-normal nz-btn-style-normal" type="button" @click.prevent="connect">Connect</button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</selectTable>
|
||||
<div slot="footer">
|
||||
<button class="footer__btn footer__btn--light" @click="assetShow=false">
|
||||
<span>{{$t('overall.cancel')}}</span>
|
||||
</button>
|
||||
<button class="footer__btn" :class="{'webshell-btn-disable':!assetContent.assetId}" :disabled="prevent_opt.save||!assetContent.assetId" @click.prevent="connect">
|
||||
<span>{{$t('webshell.connect')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 自定义连接 start -->
|
||||
<el-dialog :modal-append-to-body='false' :show-close="true" :visible.sync="customShow" @close="closeAssetCustom" class="nz-dialog" width="620px" destroy-on-close>
|
||||
<div slot="title">{{$t('webshell.connect')}}</div>
|
||||
<div >
|
||||
@@ -185,16 +180,19 @@
|
||||
</el-form>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<!-- 自定义连接 end -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import terminal from './consoleNew'
|
||||
import selectTable from '@/components/common/selectTable'
|
||||
import { host, port } from '@/components/common/js/validate'
|
||||
export default {
|
||||
name: 'webSSH',
|
||||
components: {
|
||||
terminal
|
||||
terminal,
|
||||
selectTable
|
||||
},
|
||||
computed: {
|
||||
language () { return this.$store.getters.getLanguage },
|
||||
@@ -217,8 +215,8 @@ export default {
|
||||
label: 'SSH'
|
||||
},
|
||||
{
|
||||
value: 'Telnet',
|
||||
label: 'Telnet'
|
||||
value: 'TELNET',
|
||||
label: 'TELNET'
|
||||
}
|
||||
],
|
||||
selectPageParams: {
|
||||
@@ -259,34 +257,32 @@ export default {
|
||||
authProtocol: 1
|
||||
},
|
||||
columns: [
|
||||
{ title: 'ID', data: 'id' },
|
||||
{
|
||||
title: 'Name',
|
||||
data: function (row) {
|
||||
if (row.name.length > 15) {
|
||||
return row.name.substring(0, 12) + '...'
|
||||
}
|
||||
return row.name
|
||||
}
|
||||
},
|
||||
{ title: 'Manage Ip', data: 'manageIp' },
|
||||
{
|
||||
title: 'Type',
|
||||
data: (row) => {
|
||||
return row.type ? row.type.name : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Model',
|
||||
data: (row) => {
|
||||
return row.model ? row.model.name : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Datacenter',
|
||||
data: (row) => {
|
||||
return row.dc ? row.dc.name : ''
|
||||
}
|
||||
label: 'ID',
|
||||
prop: 'id',
|
||||
minWidth: 50
|
||||
}, {
|
||||
label: 'Name',
|
||||
prop: 'name',
|
||||
minWidth: 100
|
||||
}, {
|
||||
label: 'Manage Ip',
|
||||
prop: 'manageIp',
|
||||
minWidth: 135
|
||||
}, {
|
||||
label: 'Type',
|
||||
prop: 'type'
|
||||
}, {
|
||||
label: 'Model',
|
||||
prop: 'model',
|
||||
minWidth: 120
|
||||
}, {
|
||||
label: 'Datacenter',
|
||||
prop: 'dc',
|
||||
minWidth: 96
|
||||
}, {
|
||||
label: 'Protocol',
|
||||
prop: 'protocol'
|
||||
}
|
||||
],
|
||||
rules: {
|
||||
@@ -365,31 +361,53 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
tableFormat (row, column, cellValue) {
|
||||
let str
|
||||
switch (column.property) {
|
||||
case 'type':
|
||||
str = row.type.name || '-'
|
||||
break
|
||||
case 'model':
|
||||
str = row.model.name || '-'
|
||||
break
|
||||
case 'dc':
|
||||
str = row.dc.name || '-'
|
||||
break
|
||||
case 'protocol':
|
||||
str = this.selectPageParams.authProtocol == 1 ? 'SSH' : 'TELNET'
|
||||
break
|
||||
default:
|
||||
str = cellValue || '-'
|
||||
break
|
||||
}
|
||||
return str
|
||||
},
|
||||
selectAssetAuth (val, label) {
|
||||
this.$refs.selectPage.remove()
|
||||
this.assetContent.assetId = ''
|
||||
if (val) {
|
||||
this.selectValue = val
|
||||
if (val === 'SSH') {
|
||||
this.selectPageParams = { authProtocol: 1, pageNumber: 1 }
|
||||
this.selectPageParams = { authProtocol: 1 }
|
||||
} else {
|
||||
this.selectPageParams = { authProtocol: 2, pageNumber: 1 }
|
||||
this.selectPageParams = { authProtocol: 2 }
|
||||
}
|
||||
} else {
|
||||
label = 'SSH'
|
||||
this.selectPageParams = { authProtocol: 1, pageNumber: 1 }
|
||||
this.selectPageParams = { authProtocol: 1 }
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.$refs.selectPage.pageChange()
|
||||
}, 100)
|
||||
this.$nextTick(() => {
|
||||
this.$refs.selectTable.pageChange(1)
|
||||
})
|
||||
},
|
||||
assetShowChange () {
|
||||
this.assetShow = true
|
||||
this.selectValue = 'SSH'
|
||||
this.selectPageParams = { authProtocol: 1, pageNumber: 1 }
|
||||
if (this.$refs.selectPage) {
|
||||
this.$refs.selectPage.remove()
|
||||
this.$refs.selectPage.pageChange()
|
||||
}
|
||||
this.selectPageParams = { authProtocol: 1 }
|
||||
this.$nextTick(() => {
|
||||
this.$refs.selectTable.filter = ''
|
||||
this.$refs.selectTable.pageChange(1)
|
||||
})
|
||||
|
||||
// this.getAssetData()
|
||||
},
|
||||
/* 活动标签切换时触发 */
|
||||
@@ -500,18 +518,12 @@ export default {
|
||||
connect () {
|
||||
this.prevent_opt.save = true
|
||||
if (this.assetShow) {
|
||||
this.$refs.assetConnect.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$get('asset/asset/' + this.assetContent.assetId).then(res => {
|
||||
const asset = res.data
|
||||
this.addConsole(asset.id, asset.manageIp, '', '', 'asset')
|
||||
this.assetShow = false
|
||||
this.prevent_opt.save = false
|
||||
})
|
||||
} else {
|
||||
this.prevent_opt.save = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$refs.customConnect.validate((valid) => {
|
||||
if (valid) {
|
||||
|
||||
150
nezha-fronted/src/components/common/selectTable.vue
Normal file
150
nezha-fronted/src/components/common/selectTable.vue
Normal file
@@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div class="selectTable">
|
||||
<div class="selectTable-search-input">
|
||||
<slot name="searchLeft"></slot>
|
||||
<el-input size="small" v-model="filter" @keyup.native="search">
|
||||
<i slot="suffix" class="el-icon-search"></i>
|
||||
</el-input>
|
||||
</div>
|
||||
<el-table
|
||||
v-my-loading="loading"
|
||||
:data="tableData"
|
||||
:row-style="{cursor: 'pointer'}"
|
||||
:cell-style="{height:'32px',padding:'0'}"
|
||||
:header-cell-style="{height:'32px',padding: '0'}"
|
||||
:row-class-name="({row})=>{return row[valueKey] == this.myValue ? 'row-selected':''}"
|
||||
@row-click="rowClick"
|
||||
:height="tableHeight"
|
||||
>
|
||||
<el-table-column
|
||||
v-for="(item, index) in columns"
|
||||
:key="`col-${index}`"
|
||||
:min-width="`${item.minWidth}`"
|
||||
:width="`${item.width}`"
|
||||
:prop="item.prop"
|
||||
:label="item.label"
|
||||
:formatter="tableFormat"
|
||||
>
|
||||
</el-table-column>
|
||||
<template slot="empty">
|
||||
<div v-if="!loading" class="table-no-data">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#nz-icon-no-data-list"></use>
|
||||
</svg>
|
||||
<div class="table-no-data__title">No results found</div>
|
||||
</div>
|
||||
<div v-else> </div>
|
||||
</template>
|
||||
</el-table>
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
@current-change="pageChange"
|
||||
:current-page.sync="pageNo"
|
||||
:page-size="pageSize"
|
||||
:total="total"
|
||||
layout="total, prev, pager, next"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import bus from '@/libs/bus'
|
||||
export default {
|
||||
name: 'selectTable',
|
||||
model: {
|
||||
prop: 'myValue'
|
||||
},
|
||||
props: {
|
||||
// 当前选中的值
|
||||
myValue: {
|
||||
type: [Number, String]
|
||||
},
|
||||
api: {
|
||||
type: String,
|
||||
require: true
|
||||
},
|
||||
params: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
// 作为唯一标识的键名
|
||||
valueKey: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
},
|
||||
// 搜索的键名
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
},
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
tableHeight: {
|
||||
type: Number,
|
||||
default: 288
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
// 展示数据格式化
|
||||
tableFormat: {
|
||||
type: Function,
|
||||
default: function (row, column, cellValue) {
|
||||
return cellValue || '-'
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
filter: '',
|
||||
tableData: [],
|
||||
pageNo: 1,
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTableData () {
|
||||
this.loading = true
|
||||
const params = {
|
||||
...this.params,
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize,
|
||||
[this.searchKey]: this.filter
|
||||
}
|
||||
this.$get(this.api, params).then(response => {
|
||||
this.loading = false
|
||||
if (response.code === 200) {
|
||||
this.tableData = response.data.list
|
||||
this.total = response.data.total
|
||||
} else {
|
||||
this.$message.error(response.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 当前行点击选中
|
||||
rowClick (row) {
|
||||
const value = this.myValue == row[this.valueKey] ? '' : row[this.valueKey]
|
||||
this.$emit('input', value)
|
||||
},
|
||||
// 搜索关键字
|
||||
search: bus.debounce(function () {
|
||||
this.pageNo = 1
|
||||
this.getTableData()
|
||||
}, 500),
|
||||
pageChange (val) {
|
||||
this.pageNo = val
|
||||
this.getTableData()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -230,13 +230,11 @@ export default {
|
||||
// 防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
|
||||
validateHost: bus.debounce(function () {
|
||||
this.$message.error(this.$t('validate.host'))
|
||||
},
|
||||
50),
|
||||
}, 50),
|
||||
// 防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
|
||||
validateDuplicate: bus.debounce(function () {
|
||||
this.$message.error(this.$t('ping.duplicate') + ' IP')
|
||||
},
|
||||
50),
|
||||
}, 50),
|
||||
// 添加标签之前
|
||||
beforeAddTag ({ tag, addTag }) {
|
||||
if (!ipv4.test(tag.text) && !ipv6.test(tag.text)) {
|
||||
@@ -395,7 +393,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -221,13 +221,11 @@ export default {
|
||||
// 防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
|
||||
validateHost: bus.debounce(function () {
|
||||
this.$message.error(this.$t('validate.host'))
|
||||
},
|
||||
50),
|
||||
}, 50),
|
||||
// 防止标签输入框失去焦点校验和开始任务校验重复(连续两次message提示)
|
||||
validateDuplicate: bus.debounce(function () {
|
||||
this.$message.error(this.$t('ping.duplicate') + ' IP')
|
||||
},
|
||||
50),
|
||||
}, 50),
|
||||
// 添加标签之前
|
||||
beforeAddTag ({ tag, addTag }) {
|
||||
if (!ipv4.test(tag.text) && !ipv6.test(tag.text)) {
|
||||
@@ -386,7 +384,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -26,10 +26,12 @@ const terminalFile = {
|
||||
if (!state.messageFunction) {
|
||||
state.messageFunction = true
|
||||
window.addEventListener('message', function (e) {
|
||||
try {
|
||||
const data = JSON.parse(e.data) // e.data 里面有自己所传的所有参数 可以根据参数做自己的判断
|
||||
if (data.close) {
|
||||
state.externalTerminal = false
|
||||
}
|
||||
} catch (error) {}
|
||||
})
|
||||
window.addEventListener('unload', () => {
|
||||
state.externalTerminal = false
|
||||
|
||||
@@ -93,7 +93,6 @@ const user = {
|
||||
localStorage.setItem(`nz-user-${res.data.user.id}-theme`, currentTheme)
|
||||
const body = document.getElementsByTagName('body')[0]
|
||||
body.setAttribute('class', `theme-${currentTheme}`)
|
||||
console.log(res)
|
||||
localStorage.setItem('timezoneOffset', moment.tz(res.data.timezone || defaultAppearance.timezone).format('Z'))
|
||||
localStorage.setItem('nz-sys-default-cabinet-usize', res.data.defaultCabinetUsize)
|
||||
localStorage.setItem('nz-sys-max-terminal-num', res.data.maxTerminalNum)
|
||||
|
||||
Reference in New Issue
Block a user