github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Automation/components/Actions.vue (about) 1 <script setup lang="ts"> 2 import {useI18n} from '@/hooks/web/useI18n' 3 import {Table} from '@/components/Table' 4 import {PropType, reactive, ref, unref, watch} from 'vue' 5 import {TableColumn} from '@/types/table' 6 import {ElButton, ElTag, ElPopconfirm} from 'element-plus' 7 import {ApiAction, ApiAttribute, ApiTrigger, ApiTypes} from "@/api/stub"; 8 import {useEmitt} from "@/hooks/web/useEmitt"; 9 import ActionForm from "@/views/Automation/components/ActionForm.vue"; 10 import {useRouter} from "vue-router"; 11 import {Trigger} from "@/views/Automation/components/types"; 12 13 const {currentRoute, addRoute, push} = useRouter() 14 const props = defineProps({ 15 actions: { 16 type: Array as PropType<ApiAction[]>, 17 default: () => [] 18 } 19 }) 20 21 const writeRef = ref<ComponentRef<typeof ActionForm>>() 22 let currentAction = reactive<Nullable<ApiAction>>(null) 23 let currentActionIndex = ref(0) 24 25 enum Mode { 26 VIEW = 'VIEW', 27 EDIT = 'EDIT', 28 NEW = 'NEW' 29 } 30 31 const mode = ref<Mode>(Mode.VIEW) 32 const {t} = useI18n() 33 34 interface TableObject { 35 tableList: ApiAction[] 36 } 37 38 const tableObject = reactive<TableObject>( 39 { 40 tableList: [], 41 } 42 ); 43 44 watch( 45 () => props.actions, 46 (val: ApiAction[]) => { 47 if (val == unref(tableObject.tableList)) return; 48 tableObject.tableList = val 49 }, 50 { 51 immediate: true 52 } 53 ) 54 55 const columns: TableColumn[] = [ 56 { 57 field: 'name', 58 label: t('actions.name'), 59 }, 60 { 61 field: 'script', 62 label: t('actions.script'), 63 }, 64 { 65 field: 'entity', 66 label: t('actions.entity'), 67 }, 68 { 69 field: 'action', 70 label: t('actions.action'), 71 }, 72 { 73 field: 'operations', 74 label: t('actions.operations'), 75 width: "200px", 76 type: 'time', 77 78 }, 79 ] 80 81 const addNew = () => { 82 currentAction = null 83 mode.value = Mode.NEW 84 } 85 86 const {emitter} = useEmitt() 87 const call = (action: ApiAction) => { 88 emitter.emit('callAction', action.name) 89 } 90 91 const updateActions = () => { 92 const actions = unref(tableObject.tableList) 93 emitter.emit('updateActions', actions) 94 } 95 96 const edit = (action: ApiAction, $index) => { 97 currentActionIndex.value = $index 98 currentAction = unref(action) 99 mode.value = Mode.EDIT 100 } 101 102 const save = async () => { 103 const write = unref(writeRef) 104 const validate = await write?.elFormRef?.validate()?.catch(() => { 105 }) 106 const data = (await write?.getFormData()) as ApiAction 107 if (validate) { 108 const action = { 109 id: data?.id, 110 name: data.name, 111 entity: data.entity, 112 entityId: data.entity?.id || null, 113 script: data.script, 114 scriptId: data.script?.id || null, 115 entityActionName: data.entityActionName, 116 } as ApiAction 117 if (mode.value === Mode.NEW) { 118 tableObject.tableList.push(action) 119 } else { 120 tableObject.tableList[currentActionIndex.value] = action 121 } 122 mode.value = Mode.VIEW 123 updateActions() 124 } 125 } 126 127 const resetForm = () => { 128 mode.value = Mode.VIEW 129 currentAction = null 130 } 131 132 const removeItem = () => { 133 tableObject.tableList.splice(currentActionIndex.value, 1); 134 mode.value = Mode.VIEW 135 } 136 137 const goToEntity = (action: ApiAction) => { 138 if (!action.entity?.id) { 139 return 140 } 141 push(`/entities/edit/${action.entity?.id}`) 142 } 143 144 const goToScript = (action: ApiAction) => { 145 if (!action.script?.id) { 146 return 147 } 148 push(`/scripts/edit/${action.script?.id}`) 149 } 150 </script> 151 152 <template> 153 <ElButton class="flex mb-20px items-left" @click="addNew()" plain> 154 <Icon icon="ep:plus" class="mr-5px"/> 155 {{ t('actions.addNew') }} 156 </ElButton> 157 158 <Table 159 v-if="mode==='VIEW'" 160 :selection="false" 161 :columns="columns" 162 :data="tableObject.tableList" 163 style="width: 100%" 164 > 165 166 <template #script="{row}"> 167 <ElButton v-if="row.script" :link="true" @click.prevent.stop="goToScript(row)"> 168 {{ row.script.name }} 169 </ElButton> 170 <span v-else>-</span> 171 </template> 172 173 <template #entity="{row}"> 174 <ElButton v-if="row.entity" :link="true" @click.prevent.stop="goToEntity(row)"> 175 {{ row.entity.id }} 176 </ElButton> 177 <span v-else>-</span> 178 </template> 179 180 <template #action="{row}"> 181 <span v-if="row.entityActionName">{{ row.entityActionName }}</span> 182 <span v-else>-</span> 183 </template> 184 185 <template #operations="{ row }"> 186 <ElButton :link="true" @click.prevent.stop="call(row)"> 187 {{ $t('main.call') }} 188 </ElButton> 189 190 <ElButton :link="true" @click.prevent.stop="edit(row)"> 191 {{ $t('main.edit') }} 192 </ElButton> 193 194 </template> 195 196 </Table> 197 198 <ActionForm ref="writeRef" :action="currentAction" v-if="mode!=='VIEW'"/> 199 200 <div style="text-align: right" v-if="mode!=='VIEW'"> 201 202 <ElButton v-if="mode === 'NEW'" type="primary" @click="save()"> 203 {{ t('actions.addAction') }} 204 </ElButton> 205 206 <ElButton v-if="mode === 'EDIT'" type="primary" @click="save()"> 207 {{ t('main.update') }} 208 </ElButton> 209 210 <ElButton type="default" @click="resetForm()"> 211 {{ t('main.cancel') }} 212 </ElButton> 213 214 <ElPopconfirm 215 v-if="mode === 'EDIT'" 216 :confirm-button-text="$t('main.ok')" 217 :cancel-button-text="$t('main.no')" 218 width="250" 219 style="margin-left: 10px;" 220 :title="$t('main.are_you_sure_to_do_want_this?')" 221 @confirm="removeItem" 222 > 223 <template #reference> 224 <ElButton class="mr-10px" type="danger" plain> 225 <Icon icon="ep:delete" class="mr-5px"/> 226 {{ t('main.remove') }} 227 </ElButton> 228 </template> 229 </ElPopconfirm> 230 231 </div> 232 233 </template> 234 235 <style lang="less"> 236 237 </style>