changes
This commit is contained in:
193
components/datatable/DataModel.vue
Normal file
193
components/datatable/DataModel.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div class="columns mx-0">
|
||||
<div class="column is-2">
|
||||
<Caption class="mb-2" v-bind="{title: 'Tên model (bảng)', type: 'has-text-warning'}"></Caption>
|
||||
<div class="mb-2">
|
||||
<input class="input" v-model="text" placeholder="Tìm model" @change="findModel()">
|
||||
</div>
|
||||
<div style="max-height: 80vh; overflow: auto;">
|
||||
<div :class="`py-1 border-bottom is-clickable ${current.model===v.model? 'has-background-primary has-text-white' : ''}`"
|
||||
v-for="v in displayData" @click="changeMenu(v)">
|
||||
{{ v.model}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-10 py-0 px-0">
|
||||
<div class="tabs mb-3">
|
||||
<ul>
|
||||
<li :class="`${v.code===tab? 'is-active has-text-weight-bold fs-18' : 'fs-18'}`" v-for="v in tabs">
|
||||
<a @click="changeTab(v)">{{v.name}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-if="tab==='datatype'">
|
||||
<Caption class="mb-2" v-bind="{title: 'Kiểu dữ liệu (type)', type: 'has-text-warning'}"></Caption>
|
||||
<div style="max-height:75vh; overflow-y: auto;">
|
||||
<div class="py-1 border-bottom is-clickable" v-for="x in current.fields">
|
||||
{{ x.name}}
|
||||
<span class="ml-6 has-text-grey">{{ x.type }}</span>
|
||||
<a class="ml-6 has-text-primary" v-if="x.model" @click="openModel(x)">{{ x.model }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-else-if="tab==='table'">
|
||||
<div class="columns mx-0 mb-0 pb-0">
|
||||
<div class="column is-5">
|
||||
<Caption class="mb-1" v-bind="{title: 'Values', type: 'has-text-warning'}"></Caption>
|
||||
<input class="input" rows="1" v-model="values" placeholder="Tên trường không chứa dấu cách, vd: code,name">
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<Caption class="mb-1" v-bind="{title: 'Filter', type: 'has-text-warning'}"></Caption>
|
||||
<input class="input" rows="1" v-model="filter" placeholder="{'code': 'xyz'}">
|
||||
</div>
|
||||
<div class="column is-2">
|
||||
<Caption class="mb-1" v-bind="{title: 'Sort', type: 'has-text-warning'}"></Caption>
|
||||
<input class="input" rows="1" v-model="sort" placeholder="vd: -code,name">
|
||||
</div>
|
||||
<div class="column is-1">
|
||||
<Caption class="mb-1" v-bind="{title: 'Load', type: 'has-text-warning'}"></Caption>
|
||||
<div>
|
||||
<button class="button is-primary has-text-white" @click="loadData()">Load</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Caption class="mb-1" v-bind="{title: 'Query', type: 'has-text-warning'}"></Caption>
|
||||
<div class="mb-2">
|
||||
{{ query }}
|
||||
<a class="has-text-primary ml-5" @click="copy()">copy</a>
|
||||
<p>{{apiUrl}}
|
||||
<a class="has-text-primary ml-5" @click="$copyToClipboard(apiUrl)">copy</a>
|
||||
<a class="has-text-primary ml-5" target="_blank" :href="apiUrl">open</a>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<DataTable v-bind="{pagename: pagename}" v-if="pagedata" />
|
||||
</div>
|
||||
</template>
|
||||
<div v-else>
|
||||
<img id="image" :src="filePath" alt="">
|
||||
<p class="pl-5">
|
||||
<a class="mr-5" @click="downloadFile()">
|
||||
<SvgIcon v-bind="{name: 'download.svg', type: 'black', size: 24}"></SvgIcon>
|
||||
</a>
|
||||
<a target="_blank" :href="filePath">
|
||||
<SvgIcon v-bind="{name: 'open.svg', type: 'black', size: 24}"></SvgIcon>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Modal @close="showmodal=undefined" v-bind="showmodal" v-if="showmodal"></Modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import { useStore } from '@/stores/index'
|
||||
const { $getdata, $getapi, $createField, $clone, $getpage, $empty, $copyToClipboard, $find, $multiSort, $download, $getpath } = useNuxtApp()
|
||||
const store = useStore()
|
||||
var pagename = 'pagedata3'
|
||||
var pagedata = ref()
|
||||
pagedata.value = $getpage()
|
||||
pagedata.value.perPage = 10
|
||||
store.commit(pagename, pagedata)
|
||||
let list = ['LogEntry', 'Permission', 'ContentType', 'Session', 'Group']
|
||||
var data = (await $getdata('getmodel')).filter(v=>list.findIndex(x=>x===v.model)<0)
|
||||
data = $multiSort(data, {model: 'asc'})
|
||||
var current = ref({fields: []})
|
||||
var tabs = [{code: 'datatype', name: 'Kiểu dữ liệu'}, {code: 'table', name: 'Dữ liệu'}, {code: 'datamodel', name: 'Data model'}]
|
||||
var tab = ref('datatype')
|
||||
var datatable = ref()
|
||||
var query = ref()
|
||||
var values, filter
|
||||
var apiUrl = ref()
|
||||
var showmodal = ref()
|
||||
var text = null
|
||||
var displayData = ref(data)
|
||||
var filePath = `${$getpath()}static/files/datamodel.png`
|
||||
var sort = "-id"
|
||||
current.value = data[0]
|
||||
function changeMenu(v) {
|
||||
values = undefined
|
||||
filter = undefined
|
||||
sort = undefined
|
||||
current.value = v
|
||||
if(tab.value==='table') loadData()
|
||||
}
|
||||
async function changeTab(v) {
|
||||
tab.value = v.code
|
||||
if(v.code==='table') loadData()
|
||||
}
|
||||
async function loadData() {
|
||||
let vfilter = filter? filter.trim() : undefined
|
||||
if(vfilter) {
|
||||
try {
|
||||
vfilter = JSON.parse(vfilter)
|
||||
} catch (error) {
|
||||
alert('Cấu trúc filter có lỗi')
|
||||
vfilter = undefined
|
||||
}
|
||||
}
|
||||
let params = {values: $empty(values)? undefined : values.trim(), filter: filter, sort: $empty(sort)? undefined : sort.trim()}
|
||||
let modelName = current.value.model
|
||||
let found = {name: modelName.toLowerCase().replace('_', ''), url: `data/${modelName}/`, url_detail: `data-detail/${modelName}/`, params: params}
|
||||
query.value = $clone(found)
|
||||
let rs = await $getapi([found])
|
||||
if(rs==='error') return alert('Đã xảy ra lỗi, hãy xem lại câu lệnh.')
|
||||
datatable.value = rs[0].data.rows
|
||||
showData()
|
||||
|
||||
// api query
|
||||
const baseUrl = $getpath() + `${query.value.url}`
|
||||
apiUrl.value = baseUrl
|
||||
let vparams = !$empty(values)? {values: values} : null
|
||||
if(!$empty(filter)) {
|
||||
vparams = vparams? {values: values, filter:filter} : {filter:filter}
|
||||
}
|
||||
if(!$empty(sort)) {
|
||||
if(vparams) {
|
||||
vparams.sort = sort.trim()
|
||||
} else {
|
||||
vparams = {sort: sort.trim()}
|
||||
}
|
||||
}
|
||||
if(vparams) {
|
||||
let url = new URL(baseUrl);
|
||||
let searchParams = new URLSearchParams(vparams);
|
||||
url.search = searchParams.toString();
|
||||
apiUrl.value = baseUrl + url.search
|
||||
}
|
||||
}
|
||||
function showData() {
|
||||
let arr = []
|
||||
if(!$empty(values)) {
|
||||
let arr1 = values.trim().split(',')
|
||||
arr1.map(v=>{
|
||||
let val = v.trim()
|
||||
let field = $createField(val, val, 'string', true)
|
||||
arr.push(field)
|
||||
})
|
||||
} else {
|
||||
current.value.fields.map(v=>{
|
||||
let field = $createField(v.name, v.name, 'string', true)
|
||||
arr.push(field)
|
||||
})
|
||||
}
|
||||
let clone = $clone(pagedata.value)
|
||||
clone.fields = arr
|
||||
clone.data = datatable.value
|
||||
pagedata.value = undefined
|
||||
setTimeout(()=>pagedata.value = clone)
|
||||
}
|
||||
function copy() {
|
||||
$copyToClipboard(JSON.stringify(query.value))
|
||||
}
|
||||
function openModel(x) {
|
||||
showmodal.value = {component: 'datatable/ModelInfo', title: x.model, width: '70%', height: '600px',
|
||||
vbind: {data: data, info: $find(data, {model: x.model})}}
|
||||
}
|
||||
function downloadFile() {
|
||||
$download(`${$getpath()}download/?name=datamodel.png&type=file`, 'datamodel.png')
|
||||
}
|
||||
function findModel() {
|
||||
if($empty(text)) return displayData.value = data
|
||||
displayData.value = data.filter(v=>v.model.toLowerCase().indexOf(text.toLowerCase())>=0)
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user