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