github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/views/Entities/components/States.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 StateForm from "@/views/Entities/components/StateForm.vue"; 10 import {EntityState} from "@/views/Entities/components/types"; 11 import {propTypes} from "@/utils/propTypes"; 12 13 const {push} = useRouter() 14 const props = defineProps({ 15 states: { 16 type: Array as PropType<EntityState[]>, 17 default: () => [] 18 }, 19 pluginStates: { 20 type: Array as PropType<EntityState[]>, 21 default: () => [] 22 }, 23 customStates: propTypes.bool.def(false), 24 }) 25 26 const writeRef = ref<ComponentRef<typeof StateForm>>() 27 let currentState = reactive<Nullable<EntityState>>(null) 28 let currentStateIndex = 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: EntityState[] 41 } 42 43 const tableObject = reactive<TableObject>( 44 { 45 tableList: [], 46 } 47 ); 48 49 watch( 50 () => props.states, 51 (val: EntityState[]) => { 52 if (val == unref(tableObject.tableList)) return; 53 tableObject.tableList = val 54 if (val.length) { 55 currentState = 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 width: "200px", 68 }, 69 { 70 field: 'image', 71 label: t('entities.image'), 72 width: "110px", 73 }, 74 { 75 field: 'description', 76 label: t('entities.description'), 77 }, 78 { 79 field: 'operations', 80 label: t('entities.operations'), 81 width: "200px", 82 type: 'time', 83 84 }, 85 ] 86 87 const addNew = () => { 88 currentState = null 89 mode.value = Mode.NEW 90 } 91 92 const {emitter} = useEmitt() 93 const setState = (state: EntityState) => { 94 emitter.emit('setState', state.name) 95 } 96 97 const updateTriggers = () => { 98 const states = unref(tableObject.tableList) 99 emitter.emit('updateStates', states) 100 } 101 102 const edit = (state: EntityState, $index) => { 103 currentStateIndex.value = $index 104 currentState = unref(state) 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 EntityState 113 if (validate) { 114 const state = { 115 name: data.name, 116 description: data.description, 117 imageId: data.image?.id, 118 image: data.image, 119 } as EntityState 120 if (mode.value === Mode.NEW) { 121 tableObject.tableList.push(state) 122 } else { 123 tableObject.tableList[currentStateIndex.value] = state 124 } 125 mode.value = Mode.VIEW 126 updateTriggers() 127 } 128 } 129 130 const resetForm = () => { 131 mode.value = Mode.VIEW 132 currentState = null 133 } 134 135 const removeItem = () => { 136 tableObject.tableList.splice(currentStateIndex.value, 1); 137 mode.value = Mode.VIEW 138 } 139 140 const goToScript = (state: EntityState) => { 141 if (!state.script?.id) { 142 return 143 } 144 push(`/scripts/edit/${state.script?.id}`) 145 } 146 147 const loadFromPlugin = async () => { 148 emitter.emit('updateStates', unref(props.pluginStates)) 149 } 150 151 </script> 152 153 <template> 154 <ElButton class="flex mb-20px items-left" @click="addNew()" plain v-if="mode ==='VIEW' && customStates"> 155 <Icon icon="ep:plus" class="mr-5px"/> 156 {{ t('entities.addNewState') }} 157 </ElButton> 158 159 <ElButton class="flex mb-20px items-left" @click="loadFromPlugin()" plain 160 v-if="mode ==='VIEW' && pluginStates.length"> 161 {{ t('entities.loadFromPlugin') }} 162 </ElButton> 163 164 <Table 165 v-if="mode==='VIEW'" 166 :selection="false" 167 :columns="columns" 168 :data="tableObject.tableList" 169 style="width: 100%" 170 > 171 172 <template #image="{row}"> 173 <span v-if="row.image"><Icon icon="ic:sharp-check" class="mr-5px"/></span> 174 <span v-else>-</span> 175 </template> 176 177 <template #operations="{ row, $index }"> 178 179 <ElButton :link="true" @click.prevent.stop="setState(row)"> 180 {{ $t('entities.setState') }} 181 </ElButton> 182 183 <ElButton :link="true" @click.prevent.stop="edit(row, $index)"> 184 {{ $t('main.edit') }} 185 </ElButton> 186 187 </template> 188 189 </Table> 190 191 <StateForm ref="writeRef" :state="currentState" v-if="mode!=='VIEW'"/> 192 193 <div style="text-align: right" v-if="mode!=='VIEW'"> 194 195 <ElButton v-if="mode === 'NEW'" type="primary" @click="save()"> 196 {{ t('entities.addNewState') }} 197 </ElButton> 198 199 <ElButton v-if="mode === 'EDIT'" type="primary" @click="save()"> 200 {{ t('main.update') }} 201 </ElButton> 202 203 <ElButton type="default" @click="resetForm()"> 204 {{ t('main.cancel') }} 205 </ElButton> 206 207 <ElPopconfirm 208 v-if="mode === 'EDIT'" 209 :confirm-button-text="$t('main.ok')" 210 :cancel-button-text="$t('main.no')" 211 width="250" 212 style="margin-left: 10px;" 213 :title="$t('main.are_you_sure_to_do_want_this?')" 214 @confirm="removeItem" 215 > 216 <template #reference> 217 <ElButton class="mr-10px" type="danger" plain> 218 <Icon icon="ep:delete" class="mr-5px"/> 219 {{ t('main.remove') }} 220 </ElButton> 221 </template> 222 </ElPopconfirm> 223 224 </div> 225 </template> 226 227 <style lang="less"> 228 229 </style>