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