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