feat : 프로그래스 바 추가
SpecialSource Frontend CD / deploy (push) Successful in 7s

This commit is contained in:
sungjin.choi
2026-05-28 16:04:03 +09:00
parent 3d3783bbca
commit e9bccad047
2 changed files with 263 additions and 56 deletions
+145
View File
@@ -0,0 +1,145 @@
<script setup>
import { computed } from 'vue';
// [Props 정의]
const props = defineProps({
// 현재 진행 값
progress: {
type: Number,
required: true,
default: 0
},
// 총량
total: {
type: Number,
default: 100
},
// 하단에 표시할 상태 메시지
status: {
type: String,
default: 'Initializing...'
},
// 막대의 총 글자 길이
barLength: {
type: Number,
default: 30
}
});
// [핵심 로직: Computed로 실시간 계산]
// 1. 퍼센트 계산 (0 ~ 100, 소수점 버림)
const percentage = computed(() => {
if (props.total <= 0) return 0;
const percent = (props.progress / props.total) * 100;
return Math.min(Math.round(percent), 100); // 100%를 넘지 않도록 제한
});
// 2. ASCII 막대 문자열 생성 (█░ 문자 조합)
const barString = computed(() => {
const filledCount = Math.round((props.barLength * percentage.value) / 100);
const emptyCount = props.barLength - filledCount;
// '.repeat()'를 활용해 칼각 유지
const filledBar = '█'.repeat(filledCount);
const emptyBar = '░'.repeat(emptyCount);
return `${filledBar}${emptyBar}`;
});
</script>
<template>
<div class="tui-window">
<div class="tui-header">
<span class="tui-prompt">porter@specialsource-nas:~$</span>
<span class="tui-cmd">deploy-service --watch</span>
</div>
<div class="tui-bar-row">
<span class="tui-bracket">[</span>
<span class="tui-bar">{{ barString }}</span>
<span class="tui-bracket">]</span>
<span class="tui-percent">{{ percentage.toString().padStart(3, ' ') }}%</span>
</div>
<div class="tui-status-row">
<span class="tui-label">>> Status:</span>
<span class="tui-message">{{ status }}</span>
</div>
</div>
</template>
<style scoped>
/* [TUI 핵심 스타일 CSS] */
.tui-window {
/* 레트로 터미널 배경색 및 초록색 글씨 */
background-color: #000000;
color: #33ff33; /* 형광 초록 */
/* ★가장 중요: 칼각을 위한 고정폭 폰트 설정 */
font-family: 'Courier New', 'Fira Code', 'Monaco', monospace;
padding: 1.5rem;
border-radius: 4px;
border: 1px solid #33ff33;
box-shadow: 0 0 15px rgba(51, 255, 51, 0.2);
display: inline-block;
min-width: 520px; /* 폰트에 따라 깨지지 않게 최소폭 지정 */
box-sizing: border-box;
}
.tui-header {
color: #aaaaaa; /* 프롬프트는 약간 흐리게 */
margin-bottom: 1rem;
font-size: 0.9rem;
}
.tui-cmd {
color: #ffffff;
}
.tui-bar-row {
/* 막대가 스르륵 차오르는 느낌을 위한 자간 및 폰트 크기 조정 */
font-size: 1.25rem;
letter-spacing: 1px;
/* █와 ░의 높이를 맞추기 위해 white-space 설정 */
white-space: pre;
display: flex;
align-items: center;
}
.tui-bracket {
color: #888888;
}
.tui-bar {
/* 막대 문자 자체에 약간의 글로우 효과 */
text-shadow: 0 0 5px rgba(51, 255, 51, 0.5);
}
.tui-percent {
color: #ffffff;
margin-left: 0.75rem;
font-weight: bold;
}
.tui-status-row {
margin-top: 1rem;
font-size: 0.95rem;
border-top: 1px dotted #444;
padding-top: 0.75rem;
}
.tui-label {
color: #888888;
margin-right: 0.5rem;
}
.tui-message {
color: #ffffff;
/* 메시지가 길어질 경우 대비 */
word-break: break-all;
}
</style>