github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Dashboard/view/ViewTab.vue (about) 1 <script setup lang="ts"> 2 import {computed, nextTick, onMounted, onUnmounted, PropType, ref, watch} from "vue"; 3 import {Card, Core, eventBus, fontService, Tab} from "@/views/Dashboard/core"; 4 import Vuuri from "@/components/Vuuri" 5 import ViewCard from "@/views/Dashboard/view/ViewCard.vue"; 6 import {Frame} from "@/views/Dashboard/components"; 7 import {useAppStore} from "@/store/modules/app"; 8 import {DraggableContainer} from "@/components/DraggableContainer"; 9 10 const appStore = useAppStore() 11 12 // --------------------------------- 13 // common 14 // --------------------------------- 15 const grid = ref(null) 16 const props = defineProps({ 17 core: { 18 type: Object as PropType<Core>, 19 }, 20 tab: { 21 type: Object as PropType<Tab>, 22 default: () => null 23 }, 24 }) 25 26 const reloadKey = ref(0); 27 const eventHandler = (event: string, tabId: number) => { 28 if (props.tab?.id === tabId) { 29 // console.log('update tab', tabId) 30 reloadKey.value += 1 31 } 32 } 33 34 const eventUpdateGridHandler = (event: string, tabId: number) => { 35 if (props.tab?.id === tabId) { 36 // console.log('update grid', tabId) 37 nextTick(() => { 38 grid.value.update() 39 }) 40 } 41 } 42 43 onMounted(() => { 44 eventBus.subscribe('updateTab', eventHandler) 45 eventBus.subscribe('updateGrid', eventUpdateGridHandler) 46 }) 47 48 onUnmounted(() => { 49 eventBus.unsubscribe('updateTab', eventHandler) 50 eventBus.unsubscribe('updateGrid', eventUpdateGridHandler) 51 }) 52 53 // --------------------------------- 54 // component methods 55 // --------------------------------- 56 57 const getItemWidth = (card: Card) => { 58 if (card.width > 0) { 59 return `${card.width}px` 60 } 61 return `${props.tab?.columnWidth}px` 62 } 63 64 const getItemHeight = (card: Card) => { 65 return `${card.height}px` 66 } 67 68 const cards = computed<Card[]>(() => props.tab?.cards2) 69 const modalCards = computed<Card[]>(() => props.tab?.modalCards) 70 71 watch( 72 () => props.tab.fonts, 73 (val?: string[]) => { 74 if (!val) return 75 val.forEach(variableName => fontService.loadFont(variableName)) 76 }, 77 { 78 immediate: true 79 } 80 ) 81 82 const getBackground = (card: Card) => { 83 let background = 'inherit' 84 if (card?.background) { 85 background = card.background 86 } else { 87 if (card?.backgroundAdaptive) { 88 background = appStore.isDark ? '#232324' : '#F5F7FA' 89 } 90 } 91 return background 92 } 93 94 const getModalWidth = (card: Card): number => { 95 if (card.width > 0) { 96 return card.width 97 } 98 return props.tab?.columnWidth 99 } 100 101 const getModalHeight = (card: Card) => { 102 return card.height 103 } 104 105 </script> 106 107 <template> 108 <Vuuri 109 v-model="cards" 110 item-key="id" 111 :get-item-width="getItemWidth" 112 :get-item-height="getItemHeight" 113 :drag-enabled="false" 114 ref="grid" 115 :key="reloadKey" 116 > 117 <template #item="{item}"> 118 <Frame :frame="item.templateFrame" :background="getBackground(item)" v-if="item.template"> 119 <ViewCard :card="item" :key="item" :core="core"/> 120 </Frame> 121 <ViewCard v-else :card="item" :key="item" :core="core"/> 122 </template> 123 </Vuuri> 124 125 <DraggableContainer 126 v-for="(item, index) in modalCards" 127 :key="index + item?.id || 0" 128 :class-name="'dashboard-modal'" 129 :name="'modal-card-items-' + item.id" 130 :initial-width="getModalWidth(item)" 131 :initial-height="getModalHeight(item) + (item?.modalHeader?24: 0)" 132 :modal="true" 133 :header="item?.modalHeader" 134 :resizeable="false" 135 v-show="!item.hidden" 136 > 137 <template #header> 138 <span v-html="item.title"></span> 139 </template> 140 <template #default> 141 <Frame :frame="item.templateFrame" :background="getBackground(item)" v-if="item.template"> 142 <ViewCard :card="item" :key="index" :core="core"/> 143 </Frame> 144 <ViewCard v-else :card="item" :key="index" :core="core"/> 145 </template> 146 </DraggableContainer> 147 </template> 148 149 <style lang="less"> 150 .gap { 151 .muuri-item { 152 padding: 5px; 153 154 .muuri-item-content { 155 overflow: -webkit-paged-x; 156 } 157 } 158 } 159 160 .draggable-container.dashboard-modal { 161 background: none; 162 backdrop-filter: blur(10px); 163 164 .draggable-container-content { 165 padding: 0; 166 } 167 } 168 </style>