github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Plugins/edit.vue (about) 1 <script setup lang="ts"> 2 import {ElButton, ElCol, ElEmpty, ElRow, ElTabPane, ElTabs} from 'element-plus' 3 import api from "@/api/api"; 4 import {useRoute, useRouter} from "vue-router"; 5 import {computed, ref, unref} from "vue"; 6 import { 7 ApiAttribute, 8 ApiPlugin, 9 ApiPluginOptionsResultEntityAction, 10 ApiPluginOptionsResultEntityState 11 } from "@/api/stub"; 12 import Form from './components/Form.vue' 13 import {useI18n} from "@/hooks/web/useI18n"; 14 import {Plugin} from './components/Types' 15 import {AttributesViewer} from "@/components/Attributes"; 16 import ActionsViewer from "@/views/Plugins/components/ActionsViewer.vue"; 17 import StatesViewer from "@/views/Plugins/components/StatesViewer.vue"; 18 import SettingsEditor from "@/views/Plugins/components/SettingsEditor.vue"; 19 import {useEmitt} from "@/hooks/web/useEmitt"; 20 import {ContentWrap} from "@/components/ContentWrap"; 21 import {useCache} from "@/hooks/web/useCache"; 22 23 const {t} = useI18n() 24 const writeRef = ref<ComponentRef<typeof Form>>() 25 const route = useRoute(); 26 const {push} = useRouter() 27 const pluginName = computed<string>(() => route.params.name as string); 28 29 const currentPlugin = ref<Nullable<Plugin>>(null) 30 const loading = ref(false) 31 const activeTab = ref('main') 32 const lastState = ref<boolean>(false) 33 34 const fetch = async () => { 35 loading.value = true 36 const res = await api.v1.pluginServiceGetPlugin(pluginName.value as string) 37 .catch(() => { 38 }) 39 .finally(() => { 40 loading.value = false 41 }) 42 if (res) { 43 const plugin: ApiPlugin = res.data; 44 45 46 // setts 47 let settings: ApiAttribute[] = []; 48 if (res.data.options?.setts) { 49 for (const key in res.data.options.setts) { 50 let st = res.data.options.setts[key] 51 if (res.data.settings[key]) { 52 st = res.data.settings[key] 53 } 54 settings.push(st) 55 } 56 } 57 58 // actor states 59 let actorStates: ApiPluginOptionsResultEntityState[] = []; 60 if (res.data.options?.actorStates) { 61 for (const key in res.data.options.actorStates) { 62 actorStates.push(res.data.options.actorStates[key]) 63 } 64 } 65 66 // actor actions 67 let actorActions: ApiPluginOptionsResultEntityAction[] = []; 68 if (res.data.options?.actorActions) { 69 for (const key in res.data.options.actorActions) { 70 actorActions.push(res.data.options.actorActions[key]) 71 } 72 } 73 74 // actor attributes 75 // let actorAttrs: ApiAttribute[] = [] 76 // if (res.data.options?.actorAttrs) { 77 // for (const key in res.data.options.actorAttrs) { 78 // actorAttrs.push(res.data.options.actorAttrs[key]) 79 // } 80 // } 81 82 // actor attributes 83 // let actorSetts: ApiAttribute[] = [] 84 // if (res.data.options?.actorSetts) { 85 // for (const key in res.data.options.actorSetts) { 86 // actorSetts.push(res.data.options.actorSetts[key]) 87 // } 88 // } 89 90 currentPlugin.value = { 91 name: plugin.name, 92 version: plugin.version, 93 enabled: plugin.enabled, 94 system: plugin.system, 95 actor: plugin.actor, 96 triggers: plugin.options?.triggers, 97 actors: plugin.options?.actors, 98 actorCustomAttrs: plugin.options?.actorCustomAttrs, 99 actorCustomActions: plugin.options?.actorCustomActions, 100 actorCustomStates: plugin.options?.actorCustomStates, 101 actorCustomSetts: plugin.options?.actorCustomSetts, 102 setts: settings, 103 actorStates: actorStates, 104 actorActions: actorActions, 105 actorAttrs: Object.assign({}, res.data.options?.actorAttrs), 106 actorSetts: Object.assign({}, res.data.options?.actorSetts), 107 } as Plugin 108 // console.log(currentPlugin.value) 109 const {enabled} = res.data; 110 lastState.value = enabled 111 } else { 112 currentPlugin.value = null 113 } 114 } 115 116 const save = async () => { 117 const write = unref(writeRef) 118 const validate = await write?.elFormRef?.validate()?.catch(() => { 119 }) 120 if (validate) { 121 const data = (await write?.getFormData()) as ApiPlugin 122 if (data.enabled === lastState.value) { 123 return 124 } 125 lastState.value = data.enabled || false 126 if (data.enabled) { 127 await api.v1.pluginServiceEnablePlugin(pluginName.value) 128 } else { 129 await api.v1.pluginServiceDisablePlugin(pluginName.value) 130 } 131 fetch() 132 } 133 } 134 135 const cancel = () => { 136 push('/etc/plugins') 137 } 138 139 const showActorTabIf = (): boolean => { 140 if (Object.keys(currentPlugin.value?.actorAttrs || {}).length || 141 Object.keys(currentPlugin.value?.actorActions || {}).length || 142 Object.keys(currentPlugin.value?.actorStates || {}).length || 143 Object.keys(currentPlugin.value?.actorSetts || {}).length) { 144 return true 145 } 146 return false 147 } 148 149 const showSettingsTabIf = (): boolean => { 150 if (currentPlugin.value?.setts && Object.keys(currentPlugin.value?.setts || {}).length) { 151 return true 152 } 153 return false 154 } 155 156 const saveSetting = async (val: ApiAttribute[]) => { 157 let settings: { 158 [key: string]: ApiAttribute 159 } = {}; 160 for (const index in val) { 161 settings[val[index].name] = val[index]; 162 } 163 await api.v1.pluginServiceUpdatePluginSettings(pluginName.value, {settings: settings}) 164 fetch() 165 } 166 167 const readme = ref(''); 168 const {wsCache} = useCache() 169 const getReadme = async () => { 170 const lang = wsCache.get('lang') || 'en'; 171 const res = await api.v1.pluginServiceGetPluginReadme(pluginName.value, {lang: lang}) 172 .catch(() => { 173 }) 174 .finally(() => { 175 loading.value = false 176 }) 177 if (res && res.data) { 178 readme.value = res.data; 179 } 180 } 181 182 const tabHandler = (tab: any, ev: any) => { 183 const {props} = tab; 184 if (props.name != 'readme') return; 185 getReadme() 186 } 187 188 useEmitt({ 189 name: 'settingsUpdated', 190 callback: (settings: ApiAttribute[]) => { 191 saveSetting(settings) 192 } 193 }) 194 195 fetch() 196 197 </script> 198 199 <template> 200 <ContentWrap> 201 <el-tabs class="demo-tabs" v-model="activeTab" @tab-click="tabHandler"> 202 <el-tab-pane :label="$t('plugins.main')" name="main"> 203 <Form ref="writeRef" :current-row="currentPlugin"/> 204 <div style="text-align: right"> 205 <ElButton type="primary" @click="save()"> 206 {{ t('main.save') }} 207 </ElButton> 208 </div> 209 </el-tab-pane> 210 <!-- /Main --> 211 <el-tab-pane 212 :label="$t('plugins.actor')" 213 :disabled="!showActorTabIf()" 214 name="actor"> 215 216 <!-- attributes--> 217 <el-row class="mt-10px" 218 v-if="currentPlugin?.actorAttrs && Object.keys(currentPlugin?.actorAttrs || {}).length"> 219 <el-col> 220 {{ $t('plugins.actorAttrs') }} 221 </el-col> 222 </el-row> 223 <el-row class="mt-20px" v-if="currentPlugin?.actorAttrs && Object.keys(currentPlugin?.actorAttrs || {}).length"> 224 <el-col> 225 <AttributesViewer v-model="currentPlugin.actorAttrs"/> 226 </el-col> 227 </el-row> 228 <!-- /attributes--> 229 <!-- actions--> 230 <el-row class="mt-20px" 231 v-if="currentPlugin?.actorActions && Object.keys(currentPlugin?.actorActions).length"> 232 <el-col> 233 {{ $t('plugins.actorActions') }} 234 </el-col> 235 </el-row> 236 <el-row class="mt-20px" 237 v-if="currentPlugin?.actorActions && Object.keys(currentPlugin?.actorActions).length"> 238 <el-col> 239 <ActionsViewer :actions="currentPlugin.actorActions"/> 240 </el-col> 241 </el-row> 242 <!-- /actions--> 243 <!-- states--> 244 <el-row class="mt-20px" 245 v-if="currentPlugin?.actorStates && Object.keys(currentPlugin?.actorStates).length"> 246 <el-col> 247 {{ $t('plugins.actorStates') }} 248 </el-col> 249 </el-row> 250 <el-row class="mt-20px" 251 v-if="currentPlugin?.actorStates && Object.keys(currentPlugin?.actorStates).length"> 252 <el-col> 253 <StatesViewer :states="currentPlugin.actorStates"/> 254 </el-col> 255 </el-row> 256 <!-- /states--> 257 <!-- settings--> 258 <el-row class="mt-10px" 259 v-if="currentPlugin?.actorSetts && Object.keys(currentPlugin?.actorSetts || {}).length"> 260 <el-col> 261 {{ $t('plugins.actorSettings') }} 262 </el-col> 263 </el-row> 264 <el-row class="mt-20px" 265 v-if="currentPlugin?.actorSetts && Object.keys(currentPlugin?.actorSetts || {}).length"> 266 <el-col> 267 <AttributesViewer v-model="currentPlugin.actorSetts"/> 268 </el-col> 269 </el-row> 270 <!-- /settings--> 271 </el-tab-pane> 272 <!-- /Actor --> 273 274 <el-tab-pane 275 :label="$t('plugins.settings')" 276 name="settings" 277 :disabled="!showSettingsTabIf()"> 278 <div v-if="currentPlugin?.setts && Object.keys(currentPlugin?.setts || {}).length"> 279 <SettingsEditor :attrs="currentPlugin.setts"/> 280 </div> 281 </el-tab-pane> 282 <!-- /Settings --> 283 284 <el-tab-pane :label="$t('plugins.readme')" lazy name="readme"> 285 <div v-html="readme"></div> 286 <ElEmpty v-if="readme == ''" description="no info"/> 287 </el-tab-pane> 288 </el-tabs> 289 </ContentWrap> 290 </template> 291 292 <style lang="less" scoped> 293 294 </style>