Files
Supervisor/components/DiagramStorage.vue

122 lines
2.8 KiB
Vue

<template>
<section class="storage-card">
<template v-if="item.loading">
<TextSkeleton custom-class="h-5 w-28" />
<CircleSkeleton custom-class="mt-3 h-[120px] w-[120px]" />
<BlockSkeleton custom-class="mt-3 h-4 w-32" />
</template>
<template v-else>
<p class="font-mono text-[11px] font-medium uppercase tracking-[0.2em] text-white/60">
{{ item.hostName }}
</p>
<div class="chart-wrapper" :class="item.statusColorClass">
<svg class="chart-svg" viewBox="0 0 120 120" aria-label="Pourcentage restant">
<circle
class="track"
cx="60" cy="60"
:r="item.chartRadius"
/>
<circle
class="progress"
cx="60" cy="60"
:r="item.chartRadius"
:style="{
strokeDasharray: `${item.chartCircumference}`,
strokeDashoffset: `${item.chartOffset}`
}"
/>
</svg>
<div class="chart-label">
<strong class="font-mono text-2xl font-bold leading-none">
{{ item.remainingPercentText }}
</strong>
<span class="mt-1 font-mono text-[9px] uppercase tracking-widest text-m-muted">
libre
</span>
</div>
</div>
<p class="font-mono text-xs font-medium text-m-muted/80">
{{ item.usedText }}
<span class="mx-0.5 text-m-muted/40">/</span>
{{ item.totalText }}
</p>
</template>
</section>
</template>
<script setup lang="ts">
import CircleSkeleton from "~/components/skeleton/CircleSkeleton.vue"
import BlockSkeleton from "~/components/skeleton/BlockSkeleton.vue"
import TextSkeleton from "~/components/skeleton/TextSkeleton.vue"
defineProps<{
item: {
loading: boolean
hostName: string
statusColorClass: string
chartRadius: number
chartCircumference: number
chartOffset: number
remainingPercentText: string
usedText: string
totalText: string
}
}>()
</script>
<style scoped>
.storage-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 1.25rem 1rem;
gap: 0.25rem;
}
.chart-wrapper {
position: relative;
width: 120px;
height: 120px;
}
.chart-svg {
width: 100%;
height: 100%;
transform: rotate(-90deg);
}
.track {
fill: none;
stroke: rgba(255, 255, 255, 0.06);
stroke-width: 8;
}
.progress {
fill: none;
stroke: currentColor;
stroke-width: 8;
stroke-linecap: round;
transition: stroke-dashoffset 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}
.chart-label {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.status-success {
color: rgb(var(--m-success));
}
.status-error {
color: rgb(var(--m-error));
}
</style>