github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Automation/Triggers/index.vue (about)

     1  <script setup lang="ts">
     2  import {useI18n} from '@/hooks/web/useI18n'
     3  import {Table} from '@/components/Table'
     4  import {h, onMounted, onUnmounted, reactive, ref, watch} from 'vue'
     5  import {Pagination, TableColumn} from '@/types/table'
     6  import api from "@/api/api";
     7  import {ElButton, ElMessage, ElTag} from 'element-plus'
     8  import {ApiTrigger} from "@/api/stub";
     9  import {useRouter} from "vue-router";
    10  import {ContentWrap} from "@/components/ContentWrap";
    11  import {parseTime} from "@/utils";
    12  import {EventStateChange, EventTriggerCompleted} from "@/api/types";
    13  import {UUID} from "uuid-generator-ts";
    14  import stream from "@/api/stream";
    15  import {useCache} from "@/hooks/web/useCache";
    16  
    17  const {push} = useRouter()
    18  const {t} = useI18n()
    19  const {wsCache} = useCache()
    20  
    21  interface TableObject {
    22    tableList: ApiTrigger[]
    23    params?: any
    24    loading: boolean
    25    sort?: string
    26  }
    27  
    28  interface Params {
    29    page?: number;
    30    limit?: number;
    31    sort?: string;
    32  }
    33  
    34  const cachePref = 'triggers'
    35  const tableObject = reactive<TableObject>(
    36      {
    37        tableList: [],
    38        loading: false,
    39        sort: wsCache.get(cachePref + 'Sort') || '-createdAt'
    40      }
    41  );
    42  
    43  const currentID = ref('')
    44  
    45  const onStateChanged = (event: EventStateChange) => {
    46    getList()
    47  }
    48  
    49  const onEventTriggerActivated = (event: EventTriggerCompleted) => {
    50    for (const i in tableObject.tableList) {
    51      if (tableObject.tableList[i].id == event.id) {
    52        tableObject.tableList[i].completed = true;
    53        setTimeout(() => {
    54          tableObject.tableList[i].completed = false
    55        }, 500)
    56        return
    57      }
    58    }
    59  }
    60  
    61  onMounted(() => {
    62    const uuid = new UUID()
    63    currentID.value = uuid.getDashFreeUUID()
    64  
    65    setTimeout(() => {
    66      stream.subscribe('event_trigger_loaded', currentID.value, onStateChanged);
    67      stream.subscribe('event_trigger_unloaded', currentID.value, onStateChanged);
    68      stream.subscribe('event_trigger_completed', currentID.value, onEventTriggerActivated);
    69    }, 1000)
    70  })
    71  
    72  onUnmounted(() => {
    73    stream.unsubscribe('event_trigger_loaded', currentID.value);
    74    stream.unsubscribe('event_trigger_unloaded', currentID.value);
    75    stream.unsubscribe('event_trigger_completed', currentID.value);
    76  })
    77  
    78  const columns: TableColumn[] = [
    79    {
    80      field: 'id',
    81      label: t('automation.triggers.id'),
    82      sortable: true,
    83      width: "60px"
    84    },
    85    {
    86      field: 'name',
    87      label: t('automation.triggers.name'),
    88      sortable: true,
    89      width: "170px"
    90    },
    91    {
    92      field: 'areaId',
    93      label: t('automation.area'),
    94      width: "100px",
    95      sortable: true,
    96      formatter: (row: ApiTrigger) => {
    97        return h(
    98            'span',
    99            row.area?.name
   100        )
   101      }
   102    },
   103    {
   104      field: 'pluginName',
   105      label: t('automation.triggers.pluginName'),
   106      sortable: true,
   107    },
   108    {
   109      field: 'description',
   110      label: t('automation.description'),
   111      sortable: true,
   112      formatter: (row: ApiTrigger) => {
   113        return h(
   114            'span',
   115            row?.description || t('automation.nothing')
   116        )
   117      }
   118    },
   119    {
   120      field: 'operations',
   121      label: t('automation.triggers.operations'),
   122      width: "100px",
   123    },
   124    {
   125      field: 'status',
   126      label: t('entities.status'),
   127      width: "70px",
   128    },
   129    {
   130      field: 'createdAt',
   131      label: t('main.createdAt'),
   132      type: 'time',
   133      sortable: true,
   134      width: "170px",
   135      formatter: (row: ApiTrigger) => {
   136        return h(
   137            'span',
   138            parseTime(row.createdAt)
   139        )
   140      }
   141    },
   142    {
   143      field: 'updatedAt',
   144      label: t('main.updatedAt'),
   145      type: 'time',
   146      sortable: true,
   147      width: "170px",
   148      formatter: (row: ApiTrigger) => {
   149        return h(
   150            'span',
   151            parseTime(row.updatedAt)
   152        )
   153      }
   154    },
   155  ]
   156  const paginationObj = ref<Pagination>({
   157    currentPage: wsCache.get(cachePref + 'CurrentPage') || 1,
   158    pageSize: wsCache.get(cachePref + 'PageSize') || 50,
   159    total: 0,
   160    pageSizes: [50, 100, 150, 250],
   161  })
   162  
   163  const getList = async () => {
   164    tableObject.loading = true
   165  
   166    wsCache.set(cachePref + 'CurrentPage', paginationObj.value.currentPage)
   167    wsCache.set(cachePref + 'PageSize', paginationObj.value.pageSize)
   168    wsCache.set(cachePref + 'Sort', tableObject.sort)
   169  
   170    let params: Params = {
   171      page: paginationObj.value.currentPage,
   172      limit: paginationObj.value.pageSize,
   173      sort: tableObject.sort,
   174    }
   175  
   176    const res = await api.v1.triggerServiceGetTriggerList(params)
   177        .catch(() => {
   178        })
   179        .finally(() => {
   180          tableObject.loading = false
   181        })
   182    if (res) {
   183      const {items, meta} = res.data;
   184      tableObject.tableList = items;
   185      paginationObj.value.currentPage = meta.pagination.page;
   186      paginationObj.value.total = meta.pagination.total;
   187    } else {
   188      tableObject.tableList = [];
   189    }
   190  }
   191  
   192  watch(
   193      () => paginationObj.value.currentPage,
   194      () => {
   195        getList()
   196      }
   197  )
   198  
   199  watch(
   200      () => paginationObj.value.pageSize,
   201      () => {
   202        getList()
   203      }
   204  )
   205  
   206  const sortChange = (data) => {
   207    const {column, prop, order} = data;
   208    const pref: string = order === 'ascending' ? '+' : '-'
   209    tableObject.sort = pref + prop
   210    getList()
   211  }
   212  
   213  getList()
   214  
   215  const addNew = () => {
   216    push('/automation/triggers/new')
   217  }
   218  
   219  
   220  const selectRow = (row) => {
   221    if (!row) {
   222      return
   223    }
   224    const {id} = row
   225    push(`/automation/triggers/edit/${id}`)
   226  }
   227  
   228  const enable = async (trigger: ApiTrigger) => {
   229    if (!trigger?.id) return;
   230    await api.v1.triggerServiceEnableTrigger(trigger.id);
   231    ElMessage({
   232      title: t('Success'),
   233      message: t('message.requestSentSuccessfully'),
   234      type: 'success',
   235      duration: 2000
   236    });
   237  }
   238  
   239  const disable = async (trigger: ApiTrigger) => {
   240    if (!trigger?.id) return;
   241    await api.v1.triggerServiceDisableTrigger(trigger.id);
   242    ElMessage({
   243      title: t('Success'),
   244      message: t('message.requestSentSuccessfully'),
   245      type: 'success',
   246      duration: 2000
   247    });
   248  }
   249  
   250  const tableRowClassName = (data) => {
   251    const {row, rowIndex} = data
   252    let style = ''
   253    if (row.completed) {
   254      style = 'completed'
   255    }
   256    return style
   257  }
   258  
   259  const callTrigger = async (trigger: ApiTrigger) => {
   260    if (!trigger?.id) return;
   261    await api.v1.developerToolsServiceCallTrigger({id: trigger.id})
   262        .catch(() => {
   263        })
   264        .finally(() => {
   265          ElMessage({
   266            title: t('Success'),
   267            message: t('message.callSuccessful'),
   268            type: 'success',
   269            duration: 2000
   270          })
   271        })
   272  }
   273  
   274  </script>
   275  
   276  <template>
   277    <ContentWrap>
   278      <ElButton class="flex mb-20px items-left" type="primary" @click="addNew()" plain>
   279        <Icon icon="ep:plus" class="mr-5px"/>
   280        {{ t('automation.triggers.addNew') }}
   281      </ElButton>
   282  
   283      <Table
   284          :selection="false"
   285          v-model:pageSize="paginationObj.pageSize"
   286          v-model:currentPage="paginationObj.currentPage"
   287          :columns="columns"
   288          :data="tableObject.tableList"
   289          :loading="tableObject.loading"
   290          :pagination="paginationObj"
   291          @sort-change="sortChange"
   292          :row-class-name="tableRowClassName"
   293          style="width: 100%"
   294          :showUpPagination="20"
   295      >
   296        <template #name="{ row }">
   297          <span @click.prevent.stop="selectRow(row)" style="cursor: pointer">
   298            {{ row.name }}
   299          </span>
   300        </template>
   301  
   302        <template #pluginName="{row}">
   303          <ElTag>
   304            {{ row.pluginName }}
   305          </ElTag>
   306        </template>
   307  
   308        <template #operations="{ row }">
   309  
   310          <ElButton :link="true" @click.prevent.stop="callTrigger(row)" :disabled="!row?.isLoaded">
   311            {{ $t('main.call') }}
   312          </ElButton>
   313  
   314        </template>
   315  
   316        <template #status="{ row }">
   317          <div class="w-[100%] text-center">
   318            <ElButton :link="true" @click.prevent.stop="enable(row)" v-if="!row?.isLoaded">
   319              <Icon icon="noto:red-circle" class="mr-5px"/>
   320            </ElButton>
   321            <ElButton :link="true" @click.prevent.stop="disable(row)" v-if="row?.isLoaded">
   322              <Icon icon="noto:green-circle" class="mr-5px"/>
   323            </ElButton>
   324          </div>
   325        </template>
   326  
   327      </Table>
   328  
   329    </ContentWrap>
   330  
   331  </template>
   332  
   333  <style lang="less">
   334  
   335  .light {
   336    .el-table__row {
   337      &.completed {
   338        --el-table-tr-bg-color: var(--el-color-primary-light-7);
   339        -webkit-transition: background-color 200ms linear;
   340        -ms-transition: background-color 200ms linear;
   341        transition: background-color 200ms linear;
   342      }
   343    }
   344  }
   345  
   346  .dark {
   347    .el-table__row {
   348      &.completed {
   349        --el-table-tr-bg-color: var(--el-color-primary-dark-2);
   350        -webkit-transition: background-color 200ms linear;
   351        -ms-transition: background-color 200ms linear;
   352        transition: background-color 200ms linear;
   353      }
   354    }
   355  }
   356  
   357  </style>