github.com/easysoft/zendata@v0.0.0-20240513203326-705bd5a7fd67/ui/src/views/data/mine/List.vue (about) 1 <template> 2 <div class="container"> 3 <div class="head"> 4 <div class="title"><Icon type="database" :style="{fontSize: '16px'}" /><span>{{$t('menu.data.list')}}</span></div> 5 <div class="filter"> 6 <a-input-search v-model="keywords" @change="onSearch" :allowClear="true" :placeholder="$t('tips.search')" style="width: 300px" /> 7 </div> 8 <div class="buttons"> 9 <a-button type="primary" @click="create()"><Icon type="plus" :style="{fontSize: '16px'}" /> {{$t('action.create')}}</a-button> 10 </div> 11 </div> 12 13 <a-row :gutter="10"> 14 <a-col :span="hasSelected ? 12 : 24"> 15 <div class="main-table"> 16 <div v-if="defs.length==0" class="no-data-tips">{{$t('tips.pls.refresh.data')}}</div> 17 18 <template v-if="defs.length>0"> 19 <a-table :columns="columns" :data-source="defs" :pagination="false" rowKey="id" :custom-row="customRow"> 20 <a slot="recordTitle" slot-scope="text, record" @click="design(record)">{{record.title}}</a> 21 22 <span slot="folderWithPath" slot-scope="text, record"> 23 <a-tooltip placement="top" overlayClassName="tooltip-light"> 24 <template slot="title"> 25 <span>{{record.path | replacePathSep}}</span> 26 </template> 27 <a>{{record.path | pathToRelated}}</a> 28 </a-tooltip> 29 </span> 30 31 <span slot="action" slot-scope="record"> 32 <a @click="design(record)" :title="$t('action.design')"> 33 <Icon type="control" :style="{fontSize: '16px'}" /> 34 </a> 35 <a @click="edit(record)" :title="$t('action.edit')"> 36 <Icon type="form" :style="{fontSize: '16px'}" /> 37 </a> 38 <a @click="showDeleteConfirm(record)" :title="$t('action.delete')"> 39 <Icon type="delete" :style="{fontSize: '16px'}" /> 40 </a> 41 </span> 42 </a-table> 43 44 <div class="pagination-wrapper"> 45 <a-pagination size="small" simple @change="onPageChange" :current="page" :total="total" :defaultPageSize="15" /> 46 </div> 47 </template> 48 </div> 49 </a-col> 50 <a-col v-if="hasSelected" :span="12"> 51 <Preview :record="selectedRecord" /> 52 </a-col> 53 </a-row> 54 55 <div class="full-screen-modal"> 56 <design-component 57 ref="designPage" 58 :type="type" 59 :visible="designVisible" 60 :modelProp="designModel" 61 :time="time" 62 @ok="handleDesignOk" 63 @cancel="handleDesignCancel" > 64 </design-component> 65 </div> 66 67 <a-modal 68 :visible="editModalVisible" 69 :title="editModalVisible ? editRecord.id ? `${$t('menu.data.edit')}: ${editRecord.title}` : $t('title.data.create') : ''" 70 :footer="false" 71 :centered="true" 72 :width="700" 73 @cancel="handleCancelEditModal" 74 > 75 <Edit 76 :v-if="editModalVisible" 77 :id="editModalVisible ? editRecord ? editRecord.id : 0 : null" 78 :afterSave="handleEditSave" 79 /> 80 </a-modal> 81 </div> 82 </template> 83 84 <script> 85 86 import {Icon, Modal} from 'ant-design-vue' 87 import {listDef, removeDef} from "../../../api/manage"; 88 import {DesignComponent} from '../../../components' 89 import {PageSize, ResTypeDef, replacePathSep, pathToRelated} from "../../../api/utils"; 90 import debounce from "lodash.debounce" 91 import Preview from './Preview'; 92 import Edit from './Edit'; 93 94 export default { 95 name: 'Mine', 96 components: { 97 DesignComponent, 98 Icon, 99 Preview, 100 Edit, 101 }, 102 data() { 103 const columns = [ 104 { 105 title: this.$i18n.t('form.name'), 106 dataIndex: 'title', 107 'class': 'title', 108 scopedSlots: { customRender: 'recordTitle' }, 109 }, 110 { 111 title: this.$i18n.t('form.file'), 112 dataIndex: 'folder', 113 scopedSlots: { customRender: 'folderWithPath' }, 114 width: '300px' 115 }, 116 { 117 title: this.$i18n.t('form.opt'), 118 key: 'action', 119 scopedSlots: { customRender: 'action' }, 120 width: '80px' 121 }, 122 ]; 123 124 return { 125 defs: [], 126 columns, 127 selected: null, 128 129 designVisible: false, 130 designModel: {}, 131 type: ResTypeDef, 132 time: 0, 133 134 keywords: '', 135 page: 1, 136 total: 0, 137 pageSize: PageSize, 138 139 editModalVisible: false, 140 editRecord: null, 141 }; 142 }, 143 computed: { 144 hasSelected: function() { 145 if (!this.defs) return false 146 147 return this.defs.some(x => x.id == this.selected); 148 }, 149 selectedRecord: function() { 150 if (!this.defs) return null 151 152 return this.defs?.find(x => x.id == this.selected); 153 } 154 }, 155 created () { 156 this.loadData() 157 }, 158 mounted () { 159 }, 160 filters: { 161 replacePathSep: function (path) { 162 return replacePathSep(path) 163 }, 164 pathToRelated: function (path) { 165 return pathToRelated(path) 166 } 167 }, 168 methods: { 169 loadData() { 170 listDef(this.keywords, this.page).then(json => { 171 this.defs = json.data.list 172 this.total = json.data.total 173 this.selected = json.data.list.length ? json.data.list[0].id : null 174 }) 175 }, 176 create() { 177 this.editRecord = {}; 178 this.editModalVisible = true; 179 }, 180 edit(record) { 181 this.editRecord = record; 182 this.editModalVisible = true; 183 }, 184 handleCancelEditModal() { 185 this.editModalVisible = false; 186 }, 187 handleEditSave() { 188 this.editModalVisible = false; 189 this.loadData(); 190 }, 191 design(record) { 192 this.time = Date.now() // trigger data refresh 193 console.log(record) 194 this.designVisible = true 195 this.designModel = record 196 }, 197 remove(record) { 198 console.log(record) 199 removeDef(record.id).then(json => { 200 console.log('removeDef', json) 201 this.loadData() 202 }) 203 }, 204 handleDesignOk() { 205 console.log('handleDesignOk') 206 this.designVisible = false 207 }, 208 handleDesignCancel() { 209 console.log('handleDesignCancel') 210 this.designVisible = false 211 this.designModel = {} 212 }, 213 214 onPageChange(page, pageSize) { 215 console.log('onPageChange', page, pageSize) 216 this.page= page 217 this.loadData() 218 }, 219 onSearch: debounce(function() { 220 console.log('onSearch', this.keywords) 221 this.loadData() 222 }, 500), 223 handleClickRow: function(event) { 224 const id = event.target.closest('tr').getAttribute('data-row-key'); 225 this.selected = id; 226 }, 227 customRow: function(record) { 228 const {selected} = this; 229 return { 230 attrs: { 231 'class': record.id == selected ? 'selected' : '' 232 }, 233 on: { 234 click: this.handleClickRow 235 } 236 } 237 }, 238 showDeleteConfirm: function(record) { 239 Modal.confirm({ 240 title: this.$t('tips.delete'), 241 content: (h) => <strong>{record.title}</strong>, 242 okText: this.$t('msg.yes'), 243 cancelText: this.$t('msg.no'), 244 cancelType: 'danger', 245 onOk: () => { 246 this.remove(record) 247 }, 248 }); 249 } 250 } 251 } 252 </script> 253 254 <style lang="less" scoped> 255 .no-data-tips { 256 padding: 15px; 257 text-align: center; 258 } 259 </style>