layout03CoreWidgetM.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <template>
  2. <div>
  3. <div class="inner--header--wrap">
  4. <h2
  5. v-if="totalPage > 0"
  6. class="inner--component--title none--after"
  7. >
  8. 장비별 KPI ({{ page || 0 }}/{{ totalPage }})
  9. </h2>
  10. <h2 v-else>
  11. 장비별 KPI
  12. </h2>
  13. <p class="inner--component--total">
  14. Total : <span>{{ props.totalCnt }}</span>
  15. </p>
  16. </div>
  17. <div class="inner--content df--block pt--1rem">
  18. <swiper
  19. :autoplay="{
  20. delay: 20000,
  21. disableOnInteraction: false,
  22. }"
  23. :loop="true"
  24. :touch-ratio="0"
  25. :slides-per-view="1"
  26. :modules="[Autoplay]"
  27. @slide-change="onSlideChange"
  28. >
  29. <swiper-slide
  30. v-for="(slide, index) in props.items"
  31. :key="`core-swiper-slide-${index}`"
  32. >
  33. <div class="equip--card--wrap">
  34. <div
  35. v-for="(item, idx) in slide"
  36. :key="`core-swiper-slide-item-${idx}`"
  37. class="equip--card"
  38. :class="getLevelClass(item.connect, item.level)"
  39. >
  40. <div class="equip--name">
  41. {{ item.neName }}
  42. </div>
  43. <ul class="equip--st">
  44. <li>
  45. <i
  46. class="circle"
  47. :class="getBodyStatusClass(item.connect)"
  48. />
  49. <p>STATUS</p>
  50. <span class="active">{{ item.connect.isConnected ? 'ACTIVE' : item.connect.reason.join(',') }}</span>
  51. </li>
  52. <li
  53. v-for="(kpi, idx) in item.kpiItems"
  54. :key="`core-widget-${index}-${idx}`"
  55. >
  56. <i
  57. class="circle"
  58. :class="getBodyLevelClass(kpi.val)"
  59. />
  60. <p>{{ kpi.label }}</p>
  61. <span>{{ toRoundFix(kpi.val, 2) }}%</span>
  62. </li>
  63. </ul>
  64. </div>
  65. </div>
  66. </swiper-slide>
  67. </swiper>
  68. </div>
  69. </div>
  70. </template>
  71. <script setup>
  72. /***********************
  73. * import
  74. ************************/
  75. import { useI18n } from "vue-i18n"
  76. import apiUrl from '@/composables/useApi';
  77. import useAxios from '@/composables/useAxios';
  78. import useUtil from '@/composables/useUtil';
  79. import { Swiper, SwiperSlide } from 'swiper/vue';
  80. import { Navigation, Pagination, Autoplay } from 'swiper/modules';
  81. import 'swiper/css';
  82. import 'swiper/swiper-bundle.css'
  83. /***********************
  84. * plugins inject
  85. ************************/
  86. const { $toast, $log, $dayjs, $eventBus } = useNuxtApp()
  87. // props
  88. const props = defineProps({
  89. items: {
  90. type: Array,
  91. default: () => []
  92. },
  93. totalCnt: {
  94. type: Number,
  95. default: 0
  96. }
  97. })
  98. // 참조가능 데이터 설정
  99. defineExpose({})
  100. // 발신 이벤트 선언
  101. const emit = defineEmits([""]);
  102. const i18n = useI18n();
  103. /***********************
  104. * data & created
  105. ************************/
  106. const page = ref(1);
  107. const totalPage = computed(() => Math.floor(props.totalCnt / 4) + (props.totalCnt % 4 == 0 ? 0 : 1))
  108. /***********************
  109. * Methods
  110. ************************/
  111. /** Slide onChang Event */
  112. function onSlideChange(swiper) {
  113. if(swiper.realIndex != page.value + 1)
  114. page.value = swiper.realIndex + 1
  115. }
  116. const toRoundFix = (data, digit) => parseFloat(data).toFixed(digit);
  117. // 레벨 클래스 : CRITICAL, MAJOR , MINOR
  118. const getLevelClass = (connect, level) => {
  119. if(!connect.isConnected) return 'discon';
  120. else if(level === 'CRITICAL') return 'critical';
  121. else if(level === 'MAJOR') return 'major';
  122. else if(level === 'MINOR') return 'minor';
  123. else return 'normal';
  124. }
  125. // 세부 데이터 상태값
  126. const getBodyLevelClass = (val) => {
  127. if(val >= 95) return 'critical'; // red
  128. else if(val >= 90) return 'major'; // brown
  129. else if(val >= 85) return 'minor'; // yellow
  130. else return ''; // green
  131. }
  132. // 세부 데이터 STATUS 상태값
  133. const getBodyStatusClass = (connect) => {
  134. if(connect.isConnected) return 'normal';
  135. else return 'critical';
  136. }
  137. </script>