github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Entities/components/Metrics.vue (about) 1 <script setup lang="ts"> 2 3 import {useI18n} from '@/hooks/web/useI18n' 4 import {PropType, reactive, ref, unref, watch} from 'vue' 5 import {ElButton, ElRow, ElCol, ElCard, ElPopconfirm, ElSkeleton, ElEmpty} from 'element-plus' 6 import {ApiMetric} from "@/api/stub"; 7 import MetricForm from "@/views/Entities/components/MetricForm.vue"; 8 9 const {t} = useI18n() 10 const props = defineProps({ 11 metrics: { 12 type: Array as PropType<ApiMetric[]>, 13 default: () => [] 14 } 15 }) 16 17 interface Current { 18 metrics: ApiMetric[]; 19 item?: ApiMetric; 20 index: number; 21 } 22 23 const current = reactive<Current>({ 24 metrics: [], 25 index: -1, 26 }) 27 28 watch( 29 () => props.metrics, 30 (val: ApiMetric[]) => { 31 if (val == unref(current.metrics)) return; 32 current.metrics = val 33 if (val.length) { 34 current.index = 0 35 current.item = val[0] 36 } 37 }, 38 { 39 immediate: true 40 } 41 ) 42 43 const addNew = () => { 44 current.metrics.push({ 45 description: undefined, 46 name: `new metric ${current.metrics.length}`, 47 ranges: [], 48 type: 'LINE', 49 options: { 50 items: [] 51 } 52 } as ApiMetric); 53 current.index = current.metrics.length - 1 || 0; 54 current.item = Object.assign({}, current.metrics[current.index]) 55 } 56 57 const edit = (val: ApiMetric, $index) => { 58 current.item = val 59 current.index = $index 60 } 61 62 const addProperty = () => { 63 64 } 65 const remove = () => { 66 if (!current.metrics || !current.metrics.length || current.index < 0) { 67 return; 68 } 69 current.metrics.splice(current.index, 1); 70 current.index = current.metrics.length - 1; 71 72 if (current.metrics.length) { 73 current.index = current.metrics.length - 1 74 current.item = current.metrics[current.index] 75 } else { 76 current.index = -1 77 current.item = undefined 78 } 79 } 80 81 82 </script> 83 84 <template> 85 <ElRow :gutter="20" > 86 <ElCol :span="6" :xs="12"> 87 <ElCard class="box-card"> 88 <template #header> 89 <div class="card-header"> 90 <span>{{$t('metrics.list')}}</span> 91 <ElButton @click="addNew()" text> 92 {{ t('entities.addNewMetric') }} 93 </ElButton> 94 </div> 95 </template> 96 <div @click="edit(metric, index)" v-for="(metric, index) in metrics" :key="metric" class="text item cursor-pointer">{{ metric.name }}</div> 97 <div v-if="!metrics.length" class="text item">{{$t('metrics.noMetrics')}}</div> 98 </ElCard> 99 </ElCol> 100 101 <ElCol :span="14" :xs="12"> 102 <ElCol> 103 <MetricForm v-model="current.item"/> 104 105 <ElEmpty v-if="!current.item" :rows="5" class="mt-20px mb-20px"> 106 <ElButton type="primary" @click="addNew()"> 107 {{ t('entities.addNewMetric') }} 108 </ElButton> 109 </ElEmpty> 110 111 <ElRow v-if="current.item"> 112 <ElCol> 113 <div style="padding-bottom: 20px"> 114 <div style="text-align: right;" class="mt-20px"> 115 <ElPopconfirm 116 :confirm-button-text="$t('main.ok')" 117 :cancel-button-text="$t('main.no')" 118 width="250" 119 style="margin-left: 10px;" 120 :title="$t('main.are_you_sure_to_do_want_this?')" 121 @confirm="remove" 122 > 123 <template #reference> 124 <ElButton class="mr-10px" type="danger" plain> 125 <Icon icon="ep:delete" class="mr-5px"/> 126 {{ t('metrics.removeMetric') }} 127 </ElButton> 128 </template> 129 </ElPopconfirm> 130 </div> 131 </div> 132 </ElCol> 133 </ElRow> 134 </ElCol> 135 </ElCol> 136 137 138 139 </ElRow> 140 </template> 141 142 <style lang="less" scoped> 143 .card-header { 144 display: flex; 145 justify-content: space-between; 146 align-items: center; 147 } 148 149 </style>