179 lines
3.6 KiB
Vue
Executable File
179 lines
3.6 KiB
Vue
Executable File
<script lang="ts" setup>
|
|
import {charts} from "~/config/charts";
|
|
import type {PropType} from "vue";
|
|
import type {serverValueItem} from "~/components/SettingCard.vue";
|
|
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
|
|
|
|
|
|
const mainLayoutStore = useMainLayoutStore()
|
|
const visible = ref(false)
|
|
const props = defineProps({
|
|
id: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
title: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
chart: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
values: {
|
|
type: Array as PropType<serverValueItem[]>,
|
|
required: true
|
|
},
|
|
isDraggable: {
|
|
type: Boolean,
|
|
required: false
|
|
}
|
|
})
|
|
const cardRef = ref(null)
|
|
const {width} = useElementBounding(cardRef)
|
|
const rangeNum = ref(6)
|
|
const targetIsVisible = useElementVisibility(cardRef)
|
|
const isSwitched = ref(false)
|
|
watch(() => mainLayoutStore.SelectServer.id, () => {
|
|
isSwitched.value = true
|
|
setTimeout(() => {
|
|
isSwitched.value = false
|
|
})
|
|
})
|
|
watchDebounced(
|
|
width,
|
|
() => {
|
|
//更新图表过滤
|
|
rangeNum.value = Math.floor(width.value / 40)
|
|
//最大12
|
|
rangeNum.value = rangeNum.value > 24 ? 24 : rangeNum.value
|
|
},
|
|
{debounce: 500, maxWait: 1000},
|
|
)
|
|
const valueIds = computed(() => props.values.map(x => x.dataType))
|
|
const valueNames = computed(() => props.values.map(x => x.dataName))
|
|
const items = [
|
|
{
|
|
label: '全屏查看',
|
|
command: () => {
|
|
|
|
}
|
|
}, {
|
|
label: '刷新',
|
|
command: () => {
|
|
}
|
|
}, {
|
|
label: '弹出',
|
|
command: () => {
|
|
}
|
|
}, {
|
|
label: '删除',
|
|
command: () => {
|
|
mainLayoutStore.deleteLayout(props.id)
|
|
}
|
|
}, {
|
|
label: '设置',
|
|
command: () => {
|
|
visible.value = true
|
|
}
|
|
}
|
|
];
|
|
</script>
|
|
|
|
<template>
|
|
<div :id="`card_${id}`" ref="cardRef" class="card-layout ">
|
|
<Dialog v-model:visible="visible" :pt="{
|
|
root: 'border-none',
|
|
mask: {
|
|
style: 'backdrop-filter: blur(10px)'
|
|
}
|
|
}" modal>
|
|
<template #container="{ closeCallback }">
|
|
<SettingCard :card-id="id" :close-callback="closeCallback" is-setting/>
|
|
</template>
|
|
</Dialog>
|
|
<SplitButton :model="items" class="SplitButton"/>
|
|
<div :id="'item' + id" class="card-title vue-draggable-handle">
|
|
<div></div>
|
|
<h3>{{ title ?? "默认标题" }}</h3>
|
|
</div>
|
|
<component :is="charts.find(x => x.id === chart)?.component" v-if="targetIsVisible&&!isSwitched"
|
|
:rangeNum="rangeNum"
|
|
:valueIds="valueIds"
|
|
:valueNames="valueNames"/>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "base";
|
|
|
|
.card-layout {
|
|
width: 100%;
|
|
height: 100%;
|
|
background: $light-bg-color;
|
|
border-radius: $radius;
|
|
box-shadow: 0 10px 30px 0 rgba(17, 38, 146, 0.05);
|
|
padding: $padding*1.5;
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: $gap*1.5;
|
|
will-change: scroll-position, contents;
|
|
border: $border;
|
|
.dark-mode & {
|
|
background: $dark-bg-color;
|
|
}
|
|
}
|
|
|
|
.SplitButton {
|
|
position: absolute;
|
|
right: $padding*.5;
|
|
top: $padding*.5;
|
|
|
|
:deep(.p-button) {
|
|
background: unset;
|
|
border: unset;
|
|
padding: unset;
|
|
|
|
> svg {
|
|
stroke: $light-unfocused-color;
|
|
|
|
.dark-mode & {
|
|
stroke: $dark-unfocused-color;
|
|
}
|
|
|
|
&:hover {
|
|
stroke: $light-text-color;
|
|
|
|
.dark-mode & {
|
|
stroke: $dark-text-color;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.card-title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: $gap;
|
|
color: $light-text-color;
|
|
|
|
&,
|
|
h3:hover {
|
|
cursor: move;
|
|
}
|
|
|
|
.dark-mode & {
|
|
color: $dark-text-color;
|
|
}
|
|
|
|
div {
|
|
width: 6px;
|
|
height: 20px;
|
|
border-radius: $radius;
|
|
background: $primary-color;
|
|
}
|
|
}
|
|
</style>
|