kystudio/src/components/admin/SystemCapacity/CapacityTopBar.vue (257 lines of code) (raw):

<template> <div class="capacity-top-bar"> <el-popover ref="activeNodes" width="290" popper-class="nodes-popover" v-model="showNodes"> <div class="contain" @mouseover="showNodeDetails = false"> <div class="lastest-update-time"> <el-tooltip :content="$t('lastUpdateTime')" effect="dark" placement="top"><i class="icon el-icon-ksd-type_time"></i></el-tooltip>{{latestUpdateTime | timeFormatHasTimeZone}}</div> <div class="data-valumns"> <p :class="['label', 'node-item']" @mouseover.stop @mouseenter.stop="showNodeDetails = true"> <span>{{$t('usedNodes')}}:<span :class="['font-medium']">{{nodeList.length}}</span></span> <template> <!-- <span class="font-disabled" v-if="systemNodeInfo.fail">{{$t('failApi')}}</span> --> <!-- <el-tooltip :content="$t('failedTagTip')" effect="dark" placement="top"> <el-tag size="mini" type="danger">{{$t('failApi')}}</el-tag> </el-tooltip> --> <el-tag size="mini" type="danger" v-if="isOnlyQueryNode">{{$t('noActiveAllNode')}}</el-tag> <!-- <el-tag size="mini" type="danger" v-if="systemNodeInfo.node_status === 'OVERCAPACITY'">{{$t('excess')}}</el-tag> --> </template> <span class="icon el-icon-ksd-more_02 node-list-icon"></span></p> </div> </div> <div class="nodes" v-if="showNodeDetails && isNodeLoadingSuccess && !isNodeLoading" @mouseenter="showNodeDetails = true" @mouseleave="showNodeDetails = false"> <!-- <p class="error-text" v-if="!nodeList.filter(it => it.mode === 'all').length">{{$t('noNodesTip1')}}</p> --> <div class="node-details" v-if="nodeList.length > 0"> <div class="node-list" v-for="(node, index) in nodeList" :key="index"> <span v-custom-tooltip="{text: `${node.host}(${node.mode === 'All' ? 'All' : $t(`kylinLang.common.${node.mode.toLocaleLowerCase()}Node`)})`, w: 20}">{{`${node.host}(${node.mode === 'All' ? 'All' : $t(`kylinLang.common.${node.mode.toLocaleLowerCase()}Node`)})`}}</span> </div> </div> <div class="node-details nodata" v-else>{{$t('kylinLang.common.noData')}}</div> </div> </el-popover> <p class="active-nodes" v-popover:activeNodes @click="showNodes = !showNodes"> <span :class="['flag', getNodesNumColor]"></span> <span class="server-status">{{$t('serverStatus')}}</span> </p> </div> </template> <script> import Vue from 'vue' import { Component } from 'vue-property-decorator' import { mapActions, mapState, mapGetters } from 'vuex' import locales from './locales' import filterElements from '../../../filter/index' import { handleError } from '../../../util/business' @Component({ methods: { ...mapActions({ getNodeList: 'GET_NODES_LIST' }) }, computed: { ...mapState({ latestUpdateTime: state => state.capacity.latestUpdateTime }), ...mapGetters([ 'isOnlyQueryNode', 'isOnlyJobNode', 'isAdminRole' ]) }, locales }) export default class CapacityTopBar extends Vue { showNodes = false isNodeLoadingSuccess = false nodeList = [] isNodeLoading = true showNodeDetails = false filterElements = filterElements nodesTimer = null modelObj = { all: 'All', job: 'Job', query: 'Query' } get getNodesNumColor () { return 'is-success' } created () { this.getHANodes() } getHANodes () { if (this._isDestroyed) { return } this.isNodeLoading = true const data = {ext: true} if (this.nodesTimer) { data.isAuto = true } this.getNodeList(data).then((res) => { if (this._isDestroyed) { return } this.isNodeLoadingSuccess = true res.servers.length && (this.nodeList = res.servers.map(it => ({...it, mode: this.modelObj[it.mode]}))) this.isNodeLoading = false clearTimeout(this.nodesTimer) this.nodesTimer = setTimeout(() => { this.getHANodes() }, 1000 * 60) }).catch((e) => { if (e.status === 401) { handleError(e) } else { clearTimeout(this.nodesTimer) this.timer = setTimeout(() => { this.getHANodes() }, 1000 * 60) } }) } } </script> <style lang="less" scoped> @import '../../../assets/styles/variables.less'; .capacity-top-bar { position: relative; min-width: 65px; // padding-right: 20px; .active-nodes { position: relative; &:hover { color: @text-normal-color !important; } .server-status { font-weight: @font-regular; &:hover { color: @base-color; } } .flag { width: 10px; height: 10px; // position: absolute; // left: -8px; display: inline-block; border-radius: 100%; &.is-danger { background-color: @error-color-1; } &.is-warning { background-color: @warning-color-1; } &.is-success { background-color: @normal-color-1; } } .el-icon-ksd-restart { color: @base-color; } } .font-disabled { color: @text-disabled-color; } } .is-danger { color: @error-color-1; } .is-warning { color: @warning-color-1; } .is-success { color: @normal-color-1; } .error-text { color: @error-color-1; font-size: 12px; margin-bottom: 13px; } </style> <style lang="less"> @import '../../../assets/styles/variables.less'; .nodes-popover { padding: 0 !important; margin-left: -200px; position: relative; .popper__arrow { // margin-left: 50px; left: initial !important; right: 38px; } .font-disabled { color: @text-disabled-color; } .contain { .lastest-update-time { height: 30px; padding: 5px 10px; line-height: 20px; box-sizing: border-box; color: @text-normal-color; border-bottom: 1px solid @line-border-color3; .icon { margin-right: 5px; color: @text-disabled-color; } } .data-valumns { padding: 10px 0; box-sizing: border-box; .label { line-height: 28px; padding: 0 10px; box-sizing: border-box; .over-thirty-days { cursor: pointer; } } .node-item { position: relative; cursor: pointer; .node-list-icon { position: absolute; right: 10px; top: 10px; font-size: 9px; } &:hover { background: @base-color-9; } &.is-disabled { pointer-events: none; } } } } .nodes { max-height: 170px; overflow: auto; text-align: left; position: absolute; background: #ffffff; transform: translate(-105%, 0); margin-top: -39px; width: 208px; padding: 10px; box-sizing: border-box; box-shadow: 0 0px 6px 0px #E5E5E5; .node-details { text-align: left; width: 100%; &.nodata { color: @text-disabled-color; text-align: center; } } .node-list { color: @text-normal-color; margin-top: 8px; width: 100%; display: inline-block; &:first-child { margin-top: 0; } .custom-tooltip-layout { vertical-align: middle; line-height: 1; width: 100%; } } } } </style>