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> &nbsp;
    35                  <a @click="edit(record)" :title="$t('action.edit')">
    36                    <Icon type="form" :style="{fontSize: '16px'}" />
    37                  </a> &nbsp;
    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>