CMVR-BID/src/views/flow/components/NodeState.vue

151 lines
3.3 KiB
Vue
Raw Normal View History

2025-08-21 14:11:58 +08:00
<template>
<div>
<div class="state__container" :class="`nodeState-${props.state}`">
<div class="context">
<div class="state">
<el-icon>
<SuccessFilled v-if="props.state === 'SUCCESS'" />
<CircleCloseFilled v-if="['FAILED', 'STOPPED'].includes(props.state)" />
<VideoPause v-if="props.state === 'PAUSED'" />
<Loading v-if="props.state === 'RUNNING'" />
</el-icon>
<div class="text">{{ getStateText() }}</div>
</div>
<div class="resultText" v-popover="popoverRef" @click="popoverVisible = !popoverVisible">{{ popoverVisible ? '隐藏结果' : '展示结果' }}</div>
</div>
</div>
<el-popover
ref="popoverRef"
virtual-triggering
persistent
placement="right-start"
:visible="popoverVisible"
:teleported="false"
popper-class="popover__container"
>
<template #default>
<div class="params__container input">
<div class="paramsTitle">输入</div>
<div>
<slot name="input"></slot>
</div>
</div>
<div class="params__container output" v-if="slots.output">
<div class="paramsTitle">输出</div>
<div>
<slot name="output"></slot>
</div>
</div>
</template>
</el-popover>
</div>
</template>
<script setup lang="js">
import { ref, useSlots } from 'vue'
import { SuccessFilled, CircleCloseFilled, Loading, VideoPause } from '@element-plus/icons-vue'
const props = defineProps({
state: {
type: String,
default: 'NORMAL'
}
})
const slots = useSlots()
const getStateText = () => {
const map = {
SUCCESS: '成功',
RUNNING: '运行中',
FAILED: '失败',
PAUSED: '已暂停',
STOPPED: '已停止',
NORMAL: ''
}
return map[props.state]
}
const popoverRef = ref();
const popoverVisible = ref(false);
</script>
<style lang="scss" scoped>
.state__container {
display: none;
margin-bottom: 8px;
.context {
display: flex;
align-items: center;
justify-content: space-between;
padding: 4px;
font-size: 12px;
.state {
display: flex;
align-items: center;
.text {
margin: 0 8px;
}
}
.resultText {
color: #1664ff;
cursor: pointer;
}
}
}
.nodeState-SUCCESS {
display: block;
background-color: #eef9f1;
.el-icon {
font-size: 16px;
color: #309256;
}
}
.nodeState-FAILED {
display: block;
background-color: #fdf5f5;
.el-icon {
font-size: 16px;
color: #ee3f38;
}
}
.nodeState-STOPPED {
display: block;
background-color: #fdf5f5;
.el-icon {
font-size: 16px;
color: #ee3f38;
}
}
.nodeState-PAUSED {
display: block;
background-color: #cbcbcb;
.el-icon {
font-size: 16px;
color: #666;
}
}
.nodeState-RUNNING {
display: block;
background-color: #f4f7ff;
.el-icon {
color: #68a2e4;
font-size: 16px;
animation: rotateAnimation 2s linear infinite;
}
}
</style>