vue-django
Version:
个人实验项目, 本框架的目标是借鉴并超越django admin的自动化思想, 实现UI前端的极简快速定制开发
280 lines (267 loc) • 10.1 kB
JavaScript
/**
* Created by denishuang on 2018/4/23.
*/
import model_view from './model_view'
import table_view from './table_view'
import TrueFlag from '../components/widgets/TrueFlag.vue'
import ChoicesDisplay from '../components/widgets/ChoicesDisplay.vue'
import Date2Now from '../components/widgets/Date2Now.vue'
import ForeignKey from '../components/widgets/ForeignKey.vue'
import {uniqueId} from 'lodash'
export default {
mixins: [model_view, table_view],
props: {
tableItems: {
type: Array, default: function () {
return [{name: '__str__', label: '名称'}]
}
},
modelTableUrl: String,
topActionList: {
type: Array, default: function () {
return ['refresh', 'create', ['download']]
}
},
rowActionList: {
type: Array, default: function () {
return ['edit', ['delete']]
}
},
showTopBar: {
type: Boolean, default: function () {
return true
}
},
showPagger: {
type: Boolean, default: function () {
return true
}
},
onTableDBClick: {
type: Function, default: undefined
},
modelListSubUrl: String,
filterItems: Array,
batchActionItems: {type: Array, default: () => []}
},
data () {
return {
modelTableFilters: {},
modelTableOrderingFields: [],
modelTableFilterFields: [],
modelTableSearchFields: [],
modelTableItems: [],
modelTableAvairableActions: {
'refresh': {
icon: 'refresh',
title: '刷新',
do: this.modelTableRefresh
},
'create': {
icon: 'plus',
title: '创建',
do: this.tableToCreateModel,
show: () => this.modelCheckPermission('add')
},
'edit': {
icon: 'pencil',
title: '编辑',
do: this.tableToEditModel,
show: () => this.modelCheckPermission('change')
},
'delete': {
icon: 'trash',
title: '删除',
do: this.tableToDeleteModel,
show: () => this.modelCheckPermission('delete')
},
'download': {
icon: 'download',
label: '导出',
do: this.dumpExcelData
},
'batch': {
icon: 'archive',
title: '批量创建',
do: this.tableToBatchCreateModel,
show: () => this.modelCheckPermission('add')
}
}
}
},
created(){
this.$store.state.bus.$on('model-posted', this.modelTableOnModelPosted)
this.$store.state.bus.$on('model-deleted', this.modelTableOnModelPosted)
},
beforeDestroy () {
this.$store.state.bus.$off('model-posted', this.modelTableOnModelPosted)
this.$store.state.bus.$off('model-deleted', this.modelTableOnModelPosted)
},
components: {},
methods: {
modelTableInit(){
this.modelInit()
this.tableUrl = this.modelTableUrl || this.modelListSubUrl && `${this.modelListUrl}${this.modelListSubUrl}/` || this.modelListUrl
this.tableUpdateQueries({})
this.modelLoadOptions().then((data) => {
let search = this.modelOptions.actions.SEARCH
this.modelTableOrderingFields = search.ordering_fields
this.modelTableSearchFields = search.search_fields
let filterItems = this.filterItems || search.filter_fields
this.modelTableFilterFields = filterItems.map((a) => {
return Object.assign({multiple: false}, this.modelFieldConfigs[a])
})
this.modelTableFilters = Object.assign({}, this.getFilters())
this.modelTableItems = this.tableNormalizeItems(this.tableItems)
})
},
modelTableOnModelPosted({model}){
let dps = this.modelConfig.rest_options.dependencies
if (model.fullName === this.appModelName || dps && dps.includes(model.fullName)) {
this.tableLoad()
}
},
modelTableRefresh(){
this.tableLoad()
},
tableOnRowSelect(row, column, cell, event){
if (this.onTableDBClick) {
this.onTableDBClick(row, column, cell, event)
} else if (this.rowActionList.includes('edit') && this.modelCheckPermission('change')) {
this.tableToEditModel({row, column, cell, event})
}
},
tableToEditModel ({row}){
// wayky edit
const path = `/${this.appModelName.replace('.', '/')}/${row.id}`
this.$router.push(path)
this.resolveCurrentTagLabel(path, `编辑${row.__str__}`)
},
tableToDeleteModel ({row}){
return this.$confirm(`确定要删除${row.__str__}吗?`, {type: 'warning'}).then(() => {
return this.modelDelete(row.id)
}).catch(this.onServerResponseError)
},
tableToBatchCreateModel (){
this.$router.push(`${this.modelListUrl}batch?${this.modelConfig.title_field}=${this.tableQueries.search}`)
},
tableToCreateModel(){
let createUrl = `${this.modelListUrl}create`
if (!!this.modelConfig.title_field && !!this.tableQueries.search) {
createUrl = `${createUrl}?${this.modelConfig.title_field}=${this.tableQueries.search}`
}
const path = createUrl
this.$router.push(path)
this.resolveCurrentTagLabel(path, `新增${this.modelConfig.verbose_name}`)
},
tableNormalizeItems(tableItems){
return tableItems.map((i) => {
let a, field
if (typeof i == 'string') {
field = this.modelFieldConfigs[i]
if (!field) {
console.error(`field ${i} not found`)
}
a = {
name: i,
label: field.label || field.name,
type: field.type,
model: field.model,
choices: field.choices,
field
}
} else {
field = this.modelFieldConfigs[i.name]
if (field) {
a = Object.assign({}, {
label: field.label || field.name,
type: field.type,
model: field.model,
choices: field.choices,
field
}, i)
} else {
a = i
}
}
if (!a.useFormWidget) {
a.widget = a.widget || this.tableDefaultWidget(a)
}
// console.log(a)
return a
})
},
tableDefaultWidget(f){
// console.log(f)
return f.model ? ForeignKey :
(f.type == 'boolean' ? TrueFlag :
( ['datetime', 'date'].includes(f.type) ? Date2Now :
f.choices ? ChoicesDisplay : undefined))
},
choices2selectOptions(choices){
return choices.map((a) => {
return {text: a.display_name, value: a.value}
})
},
get_actions(action_list){
return action_list.map((a) => {
if (typeof a === 'string') {
let d = this.modelTableAvairableActions[a]
if (!d) {
console.error(`find no avariable actions for ${a}`)
}
d.name = a
return d
}
else if (a instanceof Array) {
return this.get_actions(a)
} else {
return a
}
})
},
getFilters(){
let postFields = this.modelFieldConfigs
let filters = {}
Object.keys(postFields).forEach((k) => {
let f = postFields[k]
if (f.choices) {
filters[`${k}_name`] = filters[k] = this.choices2selectOptions(f.choices)
}
// else if(f.type == 'boolean'){
// filters[k] = [{text:'是', value:true},{text:'否', value:false}]
// }
})
return filters
}
},
computed: {
modelTableSearchFieldNames () {
let vns = []
Object.keys(this.tableBaseQueries).forEach((a) => {
let c = this.modelFieldConfigs[a]
if (c) {
vns.push(c.label)
}
})
return this.modelTableSearchFields.filter((a) => !(a in vns)).join(',')
},
modelTableTitle(){
return `${this.modelConfig.verbose_name}列表`
},
top_actions(){
return this.get_actions(this.topActionList)
},
row_actions(){
return this.get_actions(this.rowActionList)
}
},
watch: {
tableItems(val){
if (this.modelConfig.rest_options) {
this.modelTableItems = this.tableNormalizeItems(val)
this.modelTableItems.forEach(a => a.columnKey = uniqueId())
}
}
}
}