You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
2.6 KiB
Vue
121 lines
2.6 KiB
Vue
<template>
|
|
<div class="metric-grid">
|
|
<div v-for="item in metrics" :key="item.key" class="metric-card">
|
|
<div class="metric-card__icon" :style="{ background: itemColors[item.key]?.bg, color: itemColors[item.key]?.fg }">
|
|
<Icon :icon="item.icon" />
|
|
</div>
|
|
<div class="metric-card__content">
|
|
<div class="metric-card__title">{{ t(`DataCollection.RunOverview.metrics.${item.key}`) }}</div>
|
|
<div class="metric-card__value">
|
|
{{ item.value.toFixed(2) }}<span>{{ item.unit }}</span>
|
|
</div>
|
|
<div class="metric-card__compare">
|
|
<span>{{ t('DataCollection.RunOverview.compareLabel') }}</span>
|
|
<span :class="item.change >= 0 ? 'is-up' : 'is-down'">
|
|
{{ item.change >= 0 ? '↑' : '↓' }} {{ Math.abs(item.change).toFixed(2) }}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { RunOverviewMetric } from './types'
|
|
|
|
defineProps<{
|
|
metrics: RunOverviewMetric[]
|
|
}>()
|
|
|
|
const { t } = useI18n()
|
|
|
|
const itemColors: Record<string, { bg: string; fg: string }> = {
|
|
utilizationRate: { bg: 'rgba(61, 132, 255, 0.12)', fg: '#3d84ff' },
|
|
powerOnRate: { bg: 'rgba(86, 196, 94, 0.12)', fg: '#56c45e' },
|
|
faultRate: { bg: 'rgba(255, 164, 54, 0.12)', fg: '#ffa436' },
|
|
standbyRate: { bg: 'rgba(156, 108, 255, 0.12)', fg: '#9c6cff' }
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.metric-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
gap: 16px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.metric-card {
|
|
display: flex;
|
|
align-items: center;
|
|
min-height: 104px;
|
|
padding: 22px 24px;
|
|
background: #fff;
|
|
border: 1px solid #edf1f7;
|
|
border-radius: 14px;
|
|
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.04);
|
|
}
|
|
|
|
.metric-card__icon {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 52px;
|
|
height: 52px;
|
|
margin-right: 18px;
|
|
font-size: 28px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.metric-card__content {
|
|
min-width: 0;
|
|
}
|
|
|
|
.metric-card__title {
|
|
margin-bottom: 6px;
|
|
color: #475467;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.metric-card__value {
|
|
color: #101828;
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
line-height: 1.2;
|
|
|
|
span {
|
|
margin-left: 2px;
|
|
font-size: 18px;
|
|
}
|
|
}
|
|
|
|
.metric-card__compare {
|
|
display: flex;
|
|
gap: 8px;
|
|
margin-top: 10px;
|
|
color: #667085;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.is-up {
|
|
color: #f04438;
|
|
}
|
|
|
|
.is-down {
|
|
color: #12b76a;
|
|
}
|
|
|
|
@media (max-width: 1200px) {
|
|
.metric-grid {
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.metric-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style>
|