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>