github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Dashboard/view/view.vue (about) 1 <script setup lang="ts"> 2 import {computed, onMounted, onUnmounted, reactive, ref} from 'vue' 3 import {ElTabPane, ElTabs} from 'element-plus' 4 import api from "@/api/api"; 5 import {UUID} from "uuid-generator-ts"; 6 import stream from "@/api/stream"; 7 import {Core, eventBus, stateService} from "@/views/Dashboard/core"; 8 import ViewTab from "@/views/Dashboard/view/ViewTab.vue"; 9 import {propTypes} from "@/utils/propTypes"; 10 import {EventStateChange} from "@/api/types"; 11 import {useAppStore} from "@/store/modules/app"; 12 import {GetFullImageUrl} from "@/utils/serverId"; 13 14 const appStore = useAppStore() 15 16 // --------------------------------- 17 // common 18 // --------------------------------- 19 20 const loading = ref(false) 21 const core = reactive<Core>(new Core()); 22 const currentID = ref('') 23 24 const props = defineProps({ 25 id: propTypes.number.def(0), 26 }) 27 28 const eventStateChanged = (eventName: string, event: EventStateChange) => { 29 core.onStateChanged(event) 30 } 31 32 const eventBusHandler = (eventName: string, event: EventStateChange) => { 33 core.eventBusHandler(eventName, event) 34 } 35 36 onMounted(() => { 37 const uuid = new UUID() 38 currentID.value = uuid.getDashFreeUUID() 39 40 fetchDashboard() 41 42 stream.subscribe('state_changed', currentID.value, stateService.onStateChanged); 43 eventBus.subscribe('stateChanged', eventStateChanged) 44 45 eventBus.subscribe(undefined, eventBusHandler) 46 }) 47 48 onUnmounted(() => { 49 50 stream.unsubscribe('state_changed', currentID.value); 51 eventBus.unsubscribe('stateChanged', eventStateChanged) 52 53 eventBus.unsubscribe(undefined, eventBusHandler) 54 }) 55 56 // --------------------------------- 57 // dashboard 58 // --------------------------------- 59 60 const fetchDashboard = async () => { 61 loading.value = true; 62 const res = await api.v1.dashboardServiceGetDashboardById(props.id) 63 .catch(() => { 64 }) 65 .finally(() => { 66 loading.value = false; 67 }) 68 core.currentBoard(res.data); 69 } 70 71 const activeTabIdx = computed({ 72 get(): string { 73 return core.activeTabIdx + '' 74 }, 75 set(value: string) { 76 core.activeTabIdx = parseInt(value) 77 eventBus.emit('updateGrid', core.getActiveTab?.id) 78 } 79 }) 80 81 const getTabStyle = () => { 82 const style = {} 83 if (core.getActiveTab?.background) { 84 style['background-color'] = core.getActiveTab?.background 85 } else { 86 if (core.getActiveTab?.backgroundAdaptive) { 87 style['background-color'] = appStore.isDark ? '#333335' : '#FFF' 88 } 89 } 90 91 if (core.getActiveTab?.backgroundImage) { 92 style['background-image'] = `url(${GetFullImageUrl(core.getActiveTab.backgroundImage)})` 93 style['background-repeat'] = 'repeat'; 94 style['background-position'] = 'center'; 95 // style['background-size'] = 'cover'; 96 } 97 return style 98 } 99 100 </script> 101 102 <template> 103 <ElTabs 104 v-model="activeTabIdx" 105 v-if="core.tabs.length > 1 && !loading" 106 :style="getTabStyle()" 107 class="pl-20px !min-h-[100%]" 108 :lazy="true"> 109 <ElTabPane 110 v-for="(tab, index) in core.tabs" 111 :label="tab.name" 112 :key="index" 113 :class="[{'gap': tab.gap}]" 114 :disabled="!tab.enabled" 115 :lazy="true"> 116 <ViewTab :tab="tab" :key="index" :core="core"/> 117 </ElTabPane> 118 </ElTabs> 119 120 <div v-if="core.tabs.length && core.tabs.length === 1 && !loading" :class="[{'gap': core.tabs[0].gap}]" 121 :style="getTabStyle()" class="pl-20px pt-20px !min-h-[100%] "> 122 <ViewTab :tab="core.tabs[0]" :core="core"/> 123 </div> 124 </template> 125 126 <style lang="less"> 127 128 129 /* Track */ 130 ::-webkit-scrollbar-track { 131 background: #f1f1f1; 132 } 133 134 p { 135 display: block; 136 margin-block-start: 1em; 137 margin-block-end: 1em; 138 margin-inline-start: 0; 139 margin-inline-end: 0; 140 } 141 142 h1 { 143 display: block; 144 font-size: 2em; 145 margin-block-start: 0.67em; 146 margin-block-end: 0.67em; 147 margin-inline-start: 0; 148 margin-inline-end: 0; 149 font-weight: 700; 150 } 151 152 h2 { 153 display: block; 154 font-size: 1.5em; 155 margin-block-start: 0.67em; 156 margin-block-end: 0.67em; 157 margin-inline-start: 0; 158 margin-inline-end: 0; 159 font-weight: 700; 160 } 161 162 html { 163 line-height: 1.15; 164 } 165 166 </style>