Skip to content

Commit

Permalink
Merge branch 'master' of github.com:szuprefix/vue-django
Browse files Browse the repository at this point in the history
  • Loading branch information
szuprefix committed Apr 15, 2020
2 parents 2d0a989 + 9b3b77e commit f70b85a
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 34 deletions.
34 changes: 34 additions & 0 deletions src/components/form/widgets/TemplateSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<div class="content-template-select">
<el-tag @click="selectValue(t.name)" :type="t.type" hit effect="plain" v-for="t in templates" :key="t.name">{{t.name}}</el-tag>
</div>

</template>
<script>
import arrayNormalise from '../../../utils/array_normalize'
export default{
props: {
value: String,
field: Object,
context: Object
},
data () {
return {
templates: arrayNormalise(this.field.templates, {})
}
},
components: {},
methods: {
selectValue(v) {
this.$emit('input', v)
}
},
computed: {}
}
</script>
<style>
.content-template-select .el-tag {
cursor: pointer;
margin-right: 1rem;
}
</style>
3 changes: 3 additions & 0 deletions src/components/model/Search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<model-select :field="f" v-model="value[f.name]" @input="onSearch"
:showCreate="false" :appModel="f.model"
v-else-if="f.model" :pageSize="100"></model-select>
<el-select v-model="value[f.name]" clearable :placeholder="`请选择${f.label}`" v-else-if="f.choices" @change="onSearch">
<el-option v-for="c in f.choices" :label="c.display_name" :value="c.value" :key="c.value"></el-option>
</el-select>
</template>

<template v-for="f in filterFields" v-if="! (f.name in exclude)">
Expand Down
45 changes: 29 additions & 16 deletions src/components/model/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,9 @@
let orderingFields = get(this.model.options, 'actions.SEARCH.ordering_fields', [])
let rs = array_normalize(config.listItems, this.model.fieldConfigs, (a) => {
Object.assign(a, {field: this.model.fieldConfigs[a.name]})
if(!a.formatter) {
a.formatter = this.genDefaultFormatter(a)
}
if (!a.useFormWidget) {
a.widget = a.widget || this.defaultWidget(a)
}
Expand Down Expand Up @@ -277,21 +279,32 @@
}
}
},
excelFormat(data){
let ds = data.map((d) => {
return this.tableItems.map((a) => {
let v = d[a.name]
if (a.choices) {
return a.choices.find(a => a.value === v).display_name
} else if (a.model) {
return d[`${a.name}_name`]
}
return v
})
})
return [this.tableItems.map((a) => a.label)].concat(ds)
genDefaultFormatter (f) {
if (f.choices) {
return (d, n, v) => f.choices.find(a => a.value === v).display_name
} else if (f.model) {
return (d, n, v) => d[`${f.name}_name`]
}
},
// excelFormat(data){
// let ds = data.map((d) => {
// console.log(this.tableItems)
// return this.tableItems.map((a) => {
// let v = d[a.name]
// if (a.choices) {
// v= a.choices.find(a => a.value === v).display_name
// } else if (a.model) {
// v = d[`${a.name}_name`]
// }
// if (a.formatter) {
// v = a.formatter(d, a.name, v)
// }
// return v
//
// })
// })
// return [this.tableItems.map((a) => a.label)].concat(ds)
// },
checkPermission(p, m){
m = m || this
return this.$store.state.user.model_permissions[m.appModel].includes(p)
Expand Down Expand Up @@ -368,7 +381,7 @@
return {
topActions,
rowActions,
excelFormat: this.excelFormat,
// excelFormat: this.excelFormat,
permissionFunction: this.checkPermission,
dblClickAction: 'edit',
title: this.model.config.verbose_name,
Expand Down
67 changes: 67 additions & 0 deletions src/components/model/widgets/AutoComplete.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<template>
<el-autocomplete
v-model="iValue"
:value-key="valueKey"
:fetch-suggestions="toSearch"
:placeholder="field.placeHolder || field.label"
clearable>

</el-autocomplete>
</template>
<script>
export default{
props: {
value: String,
field: Object
},
data () {
return {
iValue: '',
selectOptions: undefined
}
},
components: {},
created () {
this.iValue = this.value
},
methods: {
toSearch(qs, cb) {
let p = this.selectOptions ? Promise.resolve() : this.load()
p.then(() => {
this.search(qs, cb)
})
},
search(qs, cb) {
let b = qs && this.selectOptions.length>10
var results = b ? this.selectOptions.filter(this.createFilter(qs)) : this.selectOptions
cb(results)
},
createFilter(qs) {
let t = qs.toLowerCase()
let vk = this.valueKey
return (item) => {
return (item[vk].toLowerCase().indexOf(t) === 0)
}
},
load() {
return this.$http.get(this.field.url).then(({data}) => {
let prepare = this.field.prepare ? this.field.prepare : a => a
this.selectOptions = prepare(data)
})
},
},
computed: {
valueKey () {
return this.field.valueKey || 0
}
},
watch: {
value (v) {
this.iValue = v
},
iValue (v) {
this.$emit('input', v)
}
}
}
</script>
4 changes: 2 additions & 2 deletions src/components/table/DataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
let rowspan = m[rowIndex][columnIndex]
return {rowspan, colspan: rowspan > 0 ? 1 : 0}
},
genDefaultFormater (f) {
genDefaultFormatter (f) {
let df = (v) => v
let func = ['decimal', 'number', 'integer'].includes(f.type) && toThousandslsFilter || ['percent'].includes(f.type) && percent || df
return (row, column, cellValue, index) => func(cellValue)
Expand All @@ -121,7 +121,7 @@
f.align = f.align || ['decimal', 'number', 'percent', 'integer'].includes(f.type) && 'right' || 'left'
f.widget = f.widget || this.cellWidget
f.headerWidget = f.headerWidget || this.headerWidget
f.formatter = f.formatter || this.genDefaultFormater(f)
f.formatter = f.formatter || this.genDefaultFormatter(f)
if (f.subColumns) {
f.subColumns = f.subColumns.map(i => this.normalizeField(i))
}
Expand Down
57 changes: 44 additions & 13 deletions src/components/table/Table.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<el-table :data="_value" ref="table" v-loading="loading"
:element-loading-text="loading" v-on="elListeners" v-bind="elAttrs">
:element-loading-text="loading" v-on="elListeners" v-bind="elAttrs">
<slot name="left"></slot>
<column :field="f" v-for="f in _items" :key="f.name"></column>
<column :field="f" v-for="f in _items" v-if="f.hidden !== true" :key="f.name"></column>
<el-table-column label="" align="right" fixed="right"
v-if="rowActions && rowActions.length>0 || topActions && topActions.length>0">
<template slot="header" slot-scope="scope" v-if="topActions">
Expand All @@ -20,7 +20,7 @@
</el-table>
</template>
<script>
import {percent, toThousandslsFilter} from '../../utils/filters'
import {percent, toThousandslsFilter, json} from '../../utils/filters'
import {sortBy} from 'lodash'
import Column from './Column.vue'
import Actions from '../layout/Actions.vue'
Expand Down Expand Up @@ -69,9 +69,25 @@
methods: {
excelFormat(data){
let ds = data.map((d) => {
return this.fieldNames.map((a) => d[a])
let rs = []
this.fields.forEach(f => {
let fd = d[f.name]
if (f.items) {
f.items.forEach(a => {
rs.push(fd[a.name])
})
} else {
let r = d[f.name]
if (f.formatter) {
r = f.formatter(d, f.name, r)
}
rs.push(r)
}
})
return rs
})
return [this.fieldNames].concat(ds)
return [this.fieldLabels].concat(ds)
},
excelGetAllData () {
return Promise.resolve(this.value)
Expand All @@ -81,7 +97,7 @@
let excelGetAllData = this.$attrs.excelGetAllData || this.excelGetAllData
let excelFormat = this.$attrs.excelFormat || this.excelFormat
excelGetAllData().then((data) => {
if(data === undefined) {
if (data === undefined) {
this.loading = false
return
}
Expand All @@ -107,7 +123,10 @@
let rowspan = m[rowIndex][columnIndex]
return {rowspan, colspan: rowspan > 0 ? 1 : 0}
},
genDefaultFormater (f) {
genDefaultFormatter (f) {
if (f.type === 'field') {
return (row, column, cellValue, index) => json(cellValue, f.items)
}
let df = (v) => v
let func = ['decimal', 'number', 'integer'].includes(f.type) && toThousandslsFilter || ['percent'].includes(f.type) && percent || df
return (row, column, cellValue, index) => func(cellValue)
Expand All @@ -122,14 +141,14 @@
})
},
normalizeItem(f){
if(typeof f === 'string'){
f = {name:f}
if (typeof f === 'string') {
f = {name: f}
}
f.type = f.type || 'string'
f.align = f.align || ['decimal', 'number', 'percent', 'integer'].includes(f.type) && 'right' || 'left'
f.widget = f.widget || this.cellWidget
f.headerWidget = f.headerWidget || this.headerWidget
f.formatter = f.formatter || this.genDefaultFormater(f)
f.formatter = f.formatter || this.genDefaultFormatter(f)
if (f.subColumns) {
f.subColumns = f.subColumns.map(i => this.normalizeItem(i))
}
Expand Down Expand Up @@ -159,9 +178,21 @@
return this.normalizeItem(i)
})
},
fieldNames (){
let fs = flatten(this._items, 'subColumns')
return fs.map(a => a.name)
fields () {
return flatten(this._items, 'subColumns')
},
fieldNames () {
return this.fields.map(a => a.name)
},
fieldLabels () {
let rs = []
this.fields.map(f => {
let ls = f.items ? f.items : [f]
ls.forEach(a => {
rs.push(a.label || a.name)
})
})
return rs
},
_value(){
if (this.group > 0) {
Expand Down
5 changes: 3 additions & 2 deletions src/components/widgets/ChoicesDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
<script>
export default{
props: {
value: [String, Number],
value: Object,
field: Object
},
computed:{
display(){
let a = this.field.choices.find(a => a.value == this.value)
let v = this.value[this.field.name]
let a = this.field.choices.find(a => a.value === v)
return a && a.display_name
}
}
Expand Down
1 change: 1 addition & 0 deletions src/components/widgets/ForeignKey.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@
<style>
a.foreignkey-link:hover{
text-decoration: underline;
color:blue;
}
</style>
50 changes: 50 additions & 0 deletions src/components/widgets/JsonDisplay.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<template>
<el-row class="json-display">
<template v-for="a in items">
<el-col :span="8" class="label">{{a.label || a.name}}</el-col>
<el-col :span="16">{{a.value}}&nbsp;</el-col>
</template>
</el-row>
</template>
<script>
export default{
props: {
value: Object,
field: Object,
context: Object
},
data () {
return {
items: []
}
},
created () {
this.normalizeItems()
},
components: {},
methods: {
normalizeItems () {
let d = this.value
let items = this.field.items || []
this.items = items.map(a => {
a.value = d[a.name]
return a
})
}
},
watch: {
value () {
this.normalizeItems()
}
}
}
</script>
<style>
.json-display {
background-color: #F2F6FC;
}
.json-display .label{
background-color: #EBEEF5;
text-align: right; padding-right: 1rem;
}
</style>

0 comments on commit f70b85a

Please sign in to comment.