Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions demo/apps/tables/settings.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[APIJSON_TABLES]
moment = {
"editable" : "auto",
"table_fields" : [
{"title":"#","key":"id","width":80},
{"title":"User id","key":"user_id","width":100},
{"title":"Date","key":"date","width":160},
{"title":"Content","key":"content"},
],
"viewedit_fields" : [
{"title":"#","key":"id","editable":False},
{"title":"User id","key":"user_id"},
{"title":"Date","key":"date","editable":False},
{"title":"Content","key":"content","type":"textarea"},
],
}

comment = {
"editable" : "auto",
"table_fields" : [
{"title":"#","key":"id","width":80},
{"title":"User id","key":"user_id","width":100},
{"title":"To id","key":"to_id","width":100},
{"title":"Moment id","key":"moment_id","width":100},
{"title":"Date","key":"date","width":160},
{"title":"Content","key":"content"},
],
"viewedit_fields" : [
{"title":"#","key":"id","editable":False},
{"title":"User id","key":"user_id"},
{"title":"To id","key":"to_id","editable":False},
{"title":"Moment id","key":"moment_id","editable":False},
{"title":"Date","key":"date","editable":False},
{"title":"Content","key":"content","type":"textarea"},
],
}
5 changes: 3 additions & 2 deletions demo/apps/tables/templates/Tables/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div id="app">
<tabs v-model:value="tab_current" type="card">
<tab-pane v-for="item in tabs" :key="item" :label="item" :name="item">
<apijson-table :table_name="item"></apijson-table>
<apijson-table :table_name="item" :config="apijson_tables[item]"></apijson-table>
</tab-pane>
</tabs>
</div>
Expand All @@ -21,7 +21,8 @@
delimiters: ['{', '}'],
data:{
tab_current: null,
tabs: {{=table_keys_json}}
tabs: {{=table_keys_json}},
apijson_tables: {{=apijson_tables_json}}
}
})
</script>
Expand Down
16 changes: 9 additions & 7 deletions demo/apps/tables/views.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
#coding=utf-8
from uliweb import expose, functions
from json import dumps

@expose('/tables')
class Tables(object):
@expose('')
def list(self):
table_keys = settings.APIJSON_MODELS.keys()
if request.user and functions.has_role(request.user,"ADMIN"):
role = "ADMIN"
elif request.user:
role = "LOGIN"
if request.user:
if functions.has_role(request.user,"ADMIN"):
role = "ADMIN"
else:
role = "OWNER"
else:
role = "UNKNOWN"
apijson_tables = functions.get_apijson_tables(role)
return {
"table_keys_json":dumps(table_keys),
"role":role
"table_keys_json":json_dumps(table_keys),
"apijson_tables_json":json_dumps(apijson_tables),
"role":role,
}
17 changes: 17 additions & 0 deletions uliweb_apijson/apijson/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#coding=utf-8

def get_apijson_tables(role="UNKNOWN"):
from uliweb import settings
apijson_tables = dict(settings.APIJSON_TABLES.iteritems())
for n in apijson_tables:
c = apijson_tables[n]
editable = c["editable"]
if editable=="auto":
editable = False
POST = settings.APIJSON_MODELS[n]["POST"]
if POST:
roles = POST["roles"]
if roles:
editable = role in roles
c["editable"] = editable
return apijson_tables
3 changes: 3 additions & 0 deletions uliweb_apijson/apijson/settings.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ user = {
"PUT" : { "roles" : ["ADMIN","OWNER"] },
"DELETE" : { "roles" : ["ADMIN","OWNER"] },
}

[FUNCTIONS]
get_apijson_tables = "uliweb_apijson.apijson.get_apijson_tables"
186 changes: 141 additions & 45 deletions uliweb_apijson/apijson/templates/vue/inc_apijson_table.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<script>
Vue.component('apijson-table', {
delimiters: ['{', '}'],
props: ["table_name"],
props: ["table_name","config"],
template: `<div>
<i-table stripe border :columns="tcolumns" :data="tlist" @on-sort-change="table_on_sort_change"></i-table>
<page :total="total" :page-size="query_count" :current.sync="current_page" :page-size-opts="[10, 20, 50, 100]" show-sizer @on-change="page_on_change" @on-page-size-change="page_on_page_size_change"></page>
<modal v-model="modal_view" title="View">
<modal v-model="modal_view" :title="viewedit_label">
<i-form @submit.native.prevent :label-width="80">
<form-item v-for="item in view_items" :key="item.key" :label="item.key">
<i-input v-if="typeof item.value !=='boolean'" v-model="item.value" :readonly=true></i-input>
<checkbox v-if="typeof item.value ==='boolean'" v-model="item.value" disabled></checkbox>
<form-item v-for="item in viewedit_items" :key="item.key" :label="item.title">
<i-input v-if="item.type=='input'" v-model="item.value" :readonly="!editable(item)"></i-input>
<checkbox v-if="item.type=='checkbox'" v-model="item.value" :disabled="!editable(item)"></checkbox>
<i-input v-if="item.type=='textarea'" v-model="item.value" type="textarea" :autosize="{minRows: 2,maxRows: 5}"></i-input>
</form-item>
<form-item v-if="config_editable" label="action">
<i-button type="info" icon="ios-download" @click="save">Save</i-button>
</form-item>
</i-form>
</modal>
Expand All @@ -21,16 +25,32 @@
var thisp = this
return {
modal_view: false,
view_items: [],
viewedit_items: [],

edit_params: {},

modal_delete: false,
delete_params:{},
tcolumns: [
{title:'#',key:'id',width:80},
{
delete_params: {},

tcolumns: [],
tcolumns_preset: {
"id": {title:'#',key:'id',width:80},
"action": {
title: 'Action',
width: 140,
render: (h, params) => {
return h('div', [
render: function(h, params){
var delete_button = h('Button', {
props: {
type: 'error',
size: 'small'
},
on: {
click: function(){
thisp.remove(params)
}
}
}, 'Delete')
var buttons = [
h('Button', {
props: {
type: 'primary',
Expand All @@ -44,31 +64,31 @@
thisp.show(params)
}
}
}, 'View'),
h('Button', {
props: {
type: 'error',
size: 'small'
},
on: {
click: function(){
thisp.remove(params)
}
}
}, 'Delete')
]);
}, thisp.viewedit_label)
]
if (thisp.config_editable) {
buttons.push(delete_button)
}
return h('div', buttons);
}
}
],
},
tcolumns_init: false,
tlist:[],
query_count: 10,
current_page: 1,
total: 0,
sort_key: "id",
sort_order: "-"
sort_order: "-",

config_editable: false,
config_table_fields: null,
config_viewedit_fields: null
}
},
computed: {
viewedit_label: function(){return this.config_editable?'Edit':'View'}
},
methods: {
update_list: function(){
var thisp = this
Expand All @@ -94,21 +114,30 @@
if (data.code==200) {
var arr = data["[]"]
if (!thisp.tcolumns_init) {
if (arr.length>0) {
var item = arr[0]
for (var k in item){
if (k!="id") {
var col = {title:k,key:k}
if (typeof item[k] ==="boolean") {
col["width"] = 80
}
else if (typeof item[k] ==="number") {
col["width"] = 100
if (thisp.config_table_fields!=null){
thisp.tcolumns = thisp.config_table_fields
thisp.tcolumns.push(thisp.tcolumns_preset["action"])
thisp.tcolumns_init = true
}
else {
thisp.tcolumns.push(thisp.tcolumns_preset["id"])
if (arr.length>0) {
var item = arr[0]
for (var k in item){
if (k!="id") {
var col = {title:k,key:k}
if (typeof item[k] ==="boolean") {
col["width"] = 80
}
else if (typeof item[k] ==="number") {
col["width"] = 100
}
thisp.tcolumns.push(col)
}
thisp.tcolumns.push(col)
}
thisp.tcolumns.push(thisp.tcolumns_preset["action"])
thisp.tcolumns_init = true
}
thisp.tcolumns_init = true
}
}
thisp.tlist = arr
Expand All @@ -119,20 +148,82 @@
},
show: function(params){
var row = params.row
this.view_items = []
this.view_items.push({key:"id",value:row.id})
for (var k in row){
if (k!="id" && k[0]!="_") {
value = row[k]
this.view_items.push({key:k,value:value})
this.viewedit_items = []
if (this.config_viewedit_fields!=null) {
for (var i in this.config_viewedit_fields) {
var d = this.config_viewedit_fields[i]
d.value = row[d.key]
d.type = d.type || "input"
this.viewedit_items.push(d)
}
}
else {
this.viewedit_items.push({title:"id",value:row.id,"type":"input"})
var type2type = {
"boolean":"checkbox"
}
for (var k in row){
if (k!="id" && k[0]!="_") {
var value = row[k]
var type = type2type[typeof value] || "input"
this.viewedit_items.push({title:k,value:value,type:type})
}
}
}
if (this.config_editable){
this.edit_params = params
}
else {
this.edit_params = null
}
this.modal_view = true
},
editable: function(item){
var editable = true
if (item.editable!=null) {editable=item.editable}
return this.config_editable && editable && (item.key!="id")
},
remove: function(params){
this.delete_params = params
this.modal_delete = true
},
save: function(){
var thisp = this
var params = {
"@tag": thisp.table_name
}
var record_params = {}
var row = thisp.edit_params.row

for (var k in thisp.viewedit_items) {
var d = thisp.viewedit_items[k]
if (d.key=="id"|| d.value!=row[d.key]) {
record_params[d.key] = d.value
}
}
params[thisp.table_name] = record_params
$.ajax({
type: "POST",
url: "{{=url_for('uliweb_apijson.apijson.views.ApiJson.put')}}",
contentType: 'application/json',
data: JSON.stringify(params),
success: function (data) {
if (data.code==200){
thisp.$Notice.success({
title: 'success update #'+row.id+' in table '+thisp.table_name,
desc: data.msg
})
thisp.update_list()
}
else {
thisp.$Notice.error({
title: 'error when update #'+row.id+' in table '+thisp.table_name,
desc: data.msg
})
}
}
})
},
real_remove: function(){
var thisp = this
var params = {
Expand Down Expand Up @@ -183,6 +274,11 @@
}
},
mounted: function(){
if (this.config!=null){
this.config_editable = this.config.editable || false
this.config_table_fields = this.config.table_fields || null
this.config_viewedit_fields = this.config.viewedit_fields || null
}
this.update_list()
}
})
Expand Down
6 changes: 3 additions & 3 deletions uliweb_apijson/apijson/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,14 +499,14 @@ def _put_one(self,key,tag):
obj_dict = {"id":id_}
if ret:
obj_dict["code"] = 200
obj_dict["message"] = "success"
obj_dict["msg"] = "success"
obj_dict["count"] = 1
else:
obj_dict["code"] = 400
obj_dict["message"] = "fail"
obj_dict["msg"] = "failed when updating, maybe no change"
obj_dict["count"] = 0
self.rdict["code"] = 400
self.rdict["message"] = "fail"
self.rdict["msg"] = "failed when updating, maybe no change"
self.rdict[key] = obj_dict

def delete(self):
Expand Down