github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Settings/index.vue (about) 1 <script setup lang="ts"> 2 import {useI18n} from '@/hooks/web/useI18n' 3 import {onMounted, onUnmounted, ref} from 'vue' 4 import {useAppStore} from "@/store/modules/app"; 5 import api from "@/api/api"; 6 import {ElCol, ElDivider, ElForm, ElFormItem, ElInput, ElInputNumber, ElRow, ElSwitch} from 'element-plus' 7 import {ApiDashboard, ApiEntity} from '@/api/stub'; 8 import {DashboardSearch} from "@/components/DashboardSearch"; 9 import {ContentWrap} from "@/components/ContentWrap"; 10 import {UUID} from "uuid-generator-ts"; 11 import stream from "@/api/stream"; 12 import {EventStateChange} from "@/api/types"; 13 import {debounce} from "lodash-es"; 14 import {EntitySearch} from "@/components/EntitySearch"; 15 import {Infotip} from '@/components/Infotip' 16 17 const appStore = useAppStore() 18 19 const {t} = useI18n() 20 21 export interface Settings { 22 mainDashboardDark?: ApiDashboard; 23 mainDashboardLight?: ApiDashboard; 24 devDashboardDark?: ApiDashboard; 25 devDashboardLight?: ApiDashboard; 26 restartComponentIfScriptChanged?: boolean; 27 clearMetricsDays?: number; 28 clearLogsDays?: number; 29 clearEntityStorageDays?: number; 30 clearRunHistoryDays?: number; 31 timezone?: string; 32 createBackupAt?: string; 33 maximumNumberOfBackups?: number; 34 sendbackuptoTelegramBot?: ApiEntity; 35 sendTheBackupInPartsMb?: number; 36 gateClientId?: string; 37 gateClientSecretKey?: string; 38 gateClientServerHost?: string; 39 gateClientServerPort?: number; 40 gateClientPoolIdleSize?: number; 41 gateClientPoolMaxSize?: number; 42 gateClientTLS?: boolean; 43 hmacKey?: string; 44 certPublic?: string; 45 certKey?: string; 46 } 47 48 const settings = ref<Settings>({} as Settings) 49 const loading = ref(true) 50 51 const getDashboardVar = async (name: string) => { 52 await api.v1.variableServiceGetVariableByName(name).then((resp) => { 53 if (!resp.data?.value || resp.data?.value == 'undefined') { 54 return; 55 } 56 const id: number = parseInt(resp.data.value); 57 api.v1.dashboardServiceGetDashboardById(id).then((resp) => { 58 settings.value[name] = resp.data 59 }); 60 }); 61 } 62 63 const getBooleanVar = async (name: string) => { 64 await api.v1.variableServiceGetVariableByName(name).then((resp) => { 65 // console.log(resp.data?.value, typeof resp.data?.value) 66 if ((typeof resp.data?.value == 'string' && resp.data?.value == 'false') || 67 !resp.data?.value || resp.data?.value == 'undefined') { 68 settings.value[name] = false; 69 return; 70 } 71 settings.value[name] = true; 72 }); 73 } 74 75 const getIntegerVar = async (name: string) => { 76 await api.v1.variableServiceGetVariableByName(name).then((resp) => { 77 if (!resp.data?.value || resp.data?.value == 'undefined') { 78 return; 79 } 80 const id: number = parseInt(resp.data.value); 81 settings.value[name] = id; 82 }); 83 } 84 85 const getStringVar = async (name: string) => { 86 await api.v1.variableServiceGetVariableByName(name).then((resp) => { 87 settings.value[name] = resp.data?.value || ''; 88 }); 89 } 90 91 const getStringEntity = async (name: string) => { 92 await api.v1.variableServiceGetVariableByName(name).then((resp) => { 93 if (!resp.data?.value || resp.data?.value == 'undefined') { 94 return; 95 } 96 settings.value[name] = {id: resp.data?.value} as ApiEntity || undefined; 97 }); 98 } 99 100 const getSettings = async () => { 101 loading.value = true 102 await Promise.all([ 103 getDashboardVar('mainDashboardDark'), 104 getDashboardVar('mainDashboardLight'), 105 getDashboardVar('devDashboardDark'), 106 getDashboardVar('devDashboardLight'), 107 getBooleanVar('restartComponentIfScriptChanged'), 108 getIntegerVar('clearMetricsDays'), 109 getIntegerVar('clearLogsDays'), 110 getIntegerVar('clearEntityStorageDays'), 111 getIntegerVar('clearRunHistoryDays'), 112 getStringVar('timezone'), 113 getStringVar('createBackupAt'), 114 getIntegerVar('maximumNumberOfBackups'), 115 getStringEntity('sendbackuptoTelegramBot'), 116 getIntegerVar('sendTheBackupInPartsMb'), 117 getStringVar('gateClientId'), 118 getStringVar('gateClientSecretKey'), 119 getStringVar('gateClientServerHost'), 120 getIntegerVar('gateClientServerPort'), 121 getIntegerVar('gateClientPoolIdleSize'), 122 getIntegerVar('gateClientPoolMaxSize'), 123 getBooleanVar('gateClientTLS'), 124 getStringVar('hmacKey'), 125 getStringVar('certKey'), 126 getStringVar('certPublic') 127 ]) 128 loading.value = false 129 } 130 131 const changedVariable = debounce((name: string) => { 132 let value = '' 133 if (settings.value[name] != undefined) { 134 value = settings.value[name] + '' 135 } 136 if (settings.value[name]?.id) { 137 value = settings.value[name]?.id + '' 138 } 139 api.v1.variableServiceUpdateVariable(name, {value: value}) 140 }, 500) 141 142 const onEntityChanged = async (entity: ApiEntity, name: string) => { 143 api.v1.variableServiceUpdateVariable(name, {value: entity?.id || ''}) 144 } 145 146 const currentID = ref('') 147 148 const onStateChanged = (event: EventStateChange) => { 149 getSettings() 150 } 151 152 onMounted(() => { 153 const uuid = new UUID() 154 currentID.value = uuid.getDashFreeUUID() 155 156 setTimeout(() => { 157 stream.subscribe('event_removed_variable_model', currentID.value, onStateChanged); 158 stream.subscribe('event_updated_variable_model', currentID.value, onStateChanged); 159 }, 200) 160 }) 161 162 onUnmounted(() => { 163 stream.unsubscribe('event_removed_variable_model', currentID.value); 164 stream.unsubscribe('event_updated_variable_model', currentID.value); 165 }) 166 167 168 getSettings() 169 170 </script> 171 172 <template> 173 174 <ContentWrap> 175 176 <ElDivider content-position="left">{{ $t('settings.dashboardOptions') }}</ElDivider> 177 178 <ElForm label-position="top"> 179 <ElRow :gutter="24"> 180 <ElCol :span="12" :xs="12"> 181 <ElFormItem :label="$t('settings.mainDarkDashboard')" prop="mainDashboard"> 182 <DashboardSearch v-model="settings.mainDashboardDark" 183 @update:modelValue="changedVariable('mainDashboardDark')"/> 184 </ElFormItem> 185 </ElCol> 186 <ElCol :span="12" :xs="12"> 187 <ElFormItem :label="$t('settings.devDarkDashboard')" prop="devDashboard"> 188 <DashboardSearch v-model="settings.devDashboardDark" 189 @update:modelValue="changedVariable('devDashboardDark')"/> 190 </ElFormItem> 191 </ElCol> 192 </ElRow> 193 <ElRow :gutter="24"> 194 <ElCol :span="12" :xs="12"> 195 <ElFormItem :label="$t('settings.mainLightDashboard')" prop="mainDashboard"> 196 <DashboardSearch v-model="settings.mainDashboardLight" 197 @update:modelValue="changedVariable('mainDashboardLight')"/> 198 </ElFormItem> 199 </ElCol> 200 <ElCol :span="12" :xs="12"> 201 <ElFormItem :label="$t('settings.devLightDashboard')" prop="devDashboard"> 202 <DashboardSearch v-model="settings.devDashboardLight" 203 @update:modelValue="changedVariable('devDashboardLight')"/> 204 </ElFormItem> 205 </ElCol> 206 </ElRow> 207 208 <ElDivider content-position="left">{{ $t('settings.scriptsOptions') }}</ElDivider> 209 210 <ElRow :gutter="24"> 211 <ElCol :span="12" :xs="12"> 212 <ElFormItem :label="$t('settings.restartComponentIfScriptChanged')" prop="restartComponentIfScriptChanged"> 213 <ElSwitch v-model="settings.restartComponentIfScriptChanged" 214 @update:modelValue="changedVariable('restartComponentIfScriptChanged')"/> 215 </ElFormItem> 216 </ElCol> 217 <ElCol :span="12" :xs="12"/> 218 </ElRow> 219 220 <ElDivider content-position="left">{{ $t('settings.clearHistory') }}</ElDivider> 221 222 <ElRow :gutter="24"> 223 <ElCol :span="12" :xs="12"> 224 <ElFormItem :label="$t('settings.clearMetricsDays')" prop="clearMetricsDays"> 225 <ElInputNumber v-model="settings.clearMetricsDays" @update:modelValue="changedVariable('clearMetricsDays')" 226 :min="1"/> 227 </ElFormItem> 228 </ElCol> 229 <ElCol :span="12" :xs="12"> 230 <ElFormItem :label="$t('settings.clearLogsDays')" prop="clearLogsDays"> 231 <ElInputNumber v-model="settings.clearLogsDays" @update:modelValue="changedVariable('clearLogsDays')" 232 :min="1"/> 233 </ElFormItem> 234 </ElCol> 235 </ElRow> 236 237 <ElRow :gutter="24"> 238 <ElCol :span="12" :xs="12"> 239 <ElFormItem :label="$t('settings.clearEntityStorageDays')" prop="clearEntityStorageDays"> 240 <ElInputNumber v-model="settings.clearEntityStorageDays" 241 @update:modelValue="changedVariable('clearEntityStorageDays')" :min="1"/> 242 </ElFormItem> 243 </ElCol> 244 <ElCol :span="12" :xs="12"> 245 <ElFormItem :label="$t('settings.clearRunHistoryDays')" prop="clearRunHistoryDays"> 246 <ElInputNumber v-model="settings.clearRunHistoryDays" 247 @update:modelValue="changedVariable('clearRunHistoryDays')" :min="1"/> 248 </ElFormItem> 249 </ElCol> 250 </ElRow> 251 252 <ElDivider content-position="left">{{ $t('settings.time') }}</ElDivider> 253 254 <ElRow :gutter="24"> 255 <ElCol :span="12" :xs="12"> 256 <ElFormItem :label="$t('settings.timezone')" prop="timezone"> 257 <ElInput v-model="settings.timezone" @update:modelValue="changedVariable('timezone')"/> 258 </ElFormItem> 259 </ElCol> 260 </ElRow> 261 262 <ElDivider content-position="left">{{ $t('settings.backup') }}</ElDivider> 263 264 <Infotip 265 :show-index="false" 266 title="INFO" 267 :schema="[ 268 { 269 label: t('settings.info1'), 270 }, 271 ]" 272 /> 273 274 <ElRow :gutter="24"> 275 <ElCol :span="12" :xs="12"> 276 <ElFormItem :label="$t('settings.createBackupAt')" prop="createBackupAt"> 277 <ElInput v-model="settings.createBackupAt" @update:modelValue="changedVariable('createBackupAt')"/> 278 </ElFormItem> 279 </ElCol> 280 <ElCol :span="12" :xs="12"> 281 <ElFormItem :label="$t('settings.maximumNumberOfBackups')" prop="maximumNumberOfBackups"> 282 <ElInputNumber v-model="settings.maximumNumberOfBackups" 283 @update:modelValue="changedVariable('maximumNumberOfBackups')" :min="1"/> 284 </ElFormItem> 285 </ElCol> 286 </ElRow> 287 288 <ElRow :gutter="24"> 289 <ElCol :span="12" :xs="12"> 290 <ElFormItem :label="$t('settings.sendbackuptoTelegramBot')" prop="sendbackuptoTelegramBot"> 291 <EntitySearch v-model="settings.sendbackuptoTelegramBot" 292 @change="onEntityChanged($event, 'sendbackuptoTelegramBot')"/> 293 </ElFormItem> 294 </ElCol> 295 <ElCol :span="12" :xs="12"> 296 <ElFormItem :label="$t('settings.sendTheBackupInPartsMb')" prop="maximumNumberOfBackups"> 297 <ElInputNumber v-model="settings.sendTheBackupInPartsMb" 298 @update:modelValue="changedVariable('sendTheBackupInPartsMb')" :min="0"/> 299 </ElFormItem> 300 </ElCol> 301 </ElRow> 302 303 <ElDivider content-position="left">{{ $t('settings.gate') }}</ElDivider> 304 305 <Infotip 306 :show-index="false" 307 title="INFO" 308 :schema="[ 309 { 310 label: t('settings.info2'), 311 }, 312 ]" 313 /> 314 315 <ElRow :gutter="24"> 316 <ElCol :span="12" :xs="12"> 317 <ElFormItem :label="$t('settings.gateClientServerHost')" prop="gateClientServerHost"> 318 <ElInput v-model="settings.gateClientServerHost" 319 @update:modelValue="changedVariable('gateClientServerHost')" clearable/> 320 </ElFormItem> 321 <ElFormItem :label="$t('settings.gateClientId')" prop="gateClientId"> 322 <ElInput type="password" v-model="settings.gateClientId" 323 @update:modelValue="changedVariable('gateClientId')" clearable show-password/> 324 </ElFormItem> 325 <ElFormItem :label="$t('settings.gateClientSecretKey')" prop="gateClientSecretKey"> 326 <ElInput type="password" v-model="settings.gateClientSecretKey" 327 @update:modelValue="changedVariable('gateClientSecretKey')" clearable show-password/> 328 </ElFormItem> 329 </ElCol> 330 <ElCol :span="12" :xs="12"> 331 <ElFormItem :label="$t('settings.gateClientServerPort')" prop="gateClientServerPort"> 332 <ElInputNumber v-model="settings.gateClientServerPort" 333 @update:modelValue="changedVariable('gateClientServerPort')" :min="1"/> 334 </ElFormItem> 335 <ElFormItem :label="$t('settings.gateClientPoolIdleSize')" prop="gateClientPoolIdleSize"> 336 <ElInputNumber v-model="settings.gateClientPoolIdleSize" 337 @update:modelValue="changedVariable('gateClientPoolIdleSize')" :min="1" :max="100"/> 338 </ElFormItem> 339 <ElFormItem :label="$t('settings.gateClientPoolMaxSize')" prop="gateClientPoolMaxSize"> 340 <ElInputNumber v-model="settings.gateClientPoolMaxSize" 341 @update:modelValue="changedVariable('gateClientPoolMaxSize')" :min="1" :max="100"/> 342 </ElFormItem> 343 </ElCol> 344 </ElRow> 345 346 <ElRow :gutter="24"> 347 <ElCol :span="12" :xs="12"> 348 <ElFormItem :label="$t('settings.gateClientTLS')" prop="gateClientTLS"> 349 <ElSwitch v-model="settings.gateClientTLS" @update:modelValue="changedVariable('gateClientTLS')"/> 350 </ElFormItem> 351 </ElCol> 352 <ElCol :span="12" :xs="12"/> 353 </ElRow> 354 355 <ElDivider content-position="left">{{ $t('settings.hmacKey') }}</ElDivider> 356 357 <Infotip 358 type="warning" 359 :show-index="false" 360 title="WARNING" 361 :schema="[ 362 { 363 label: t('settings.info3'), 364 }, 365 ]" 366 /> 367 368 <ElRow :gutter="24"> 369 <ElCol :span="12" :xs="12"> 370 <ElFormItem :label="$t('settings.hmacKey')" prop="hmacKey"> 371 <ElInput type="password" v-model="settings.hmacKey" @update:modelValue="changedVariable('hmacKey')" 372 show-password/> 373 </ElFormItem> 374 </ElCol> 375 <ElCol :span="12" :xs="12"/> 376 </ElRow> 377 378 <ElDivider content-position="left">{{ $t('settings.certificates') }}</ElDivider> 379 380 <Infotip 381 :show-index="false" 382 title="INFO" 383 :schema="[ 384 { 385 label: t('settings.info4'), 386 }, 387 ]" 388 /> 389 390 <ElRow :gutter="24"> 391 <ElCol :span="12" :xs="12"> 392 <ElFormItem :label="$t('settings.certPublic')" prop="certPublic"> 393 <ElInput type="textarea" 394 :autosize="{minRows: 2, maxRows: 10}" 395 v-model="settings.certPublic" 396 @update:modelValue="changedVariable('certPublic')"/> 397 </ElFormItem> 398 </ElCol> 399 <ElCol :span="12" :xs="12"/> 400 </ElRow> 401 402 <ElRow :gutter="24"> 403 <ElCol :span="12" :xs="12"> 404 <ElFormItem :label="$t('settings.certKey')" prop="certKey"> 405 <ElInput type="textarea" 406 :autosize="{minRows: 2, maxRows: 10}" 407 v-model="settings.certKey" 408 @update:modelValue="changedVariable('certKey')"/> 409 </ElFormItem> 410 </ElCol> 411 <ElCol :span="12" :xs="12"/> 412 </ElRow> 413 414 </ElForm> 415 416 </ContentWrap> 417 </template> 418 419 <style> 420 421 </style>