Skip to content

Commit d95c0c5

Browse files
committed
add apijson-table edit feature
1 parent 7f33970 commit d95c0c5

File tree

7 files changed

+194
-43
lines changed

7 files changed

+194
-43
lines changed

demo/apps/tables/settings.ini

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[APIJSON_TABLES]
2+
moment = {
3+
"editable" : "auto",
4+
"table_fields" : [
5+
{"title":"#","key":"id","width":80},
6+
{"title":"User id","key":"user_id","width":100},
7+
{"title":"Date","key":"date","width":160},
8+
{"title":"Content","key":"content"},
9+
],
10+
"viewedit_fields" : [
11+
{"title":"#","key":"id","editable":False},
12+
{"title":"User id","key":"user_id"},
13+
{"title":"Date","key":"date","editable":False},
14+
{"title":"Content","key":"content","type":"textarea"},
15+
],
16+
}
17+
18+
comment = {
19+
"editable" : "auto",
20+
"table_fields" : [
21+
{"title":"#","key":"id","width":80},
22+
{"title":"User id","key":"user_id","width":100},
23+
{"title":"To id","key":"to_id","width":100},
24+
{"title":"Moment id","key":"moment_id","width":100},
25+
{"title":"Date","key":"date","width":160},
26+
{"title":"Content","key":"content"},
27+
],
28+
"viewedit_fields" : [
29+
{"title":"#","key":"id","editable":False},
30+
{"title":"User id","key":"user_id"},
31+
{"title":"To id","key":"to_id","editable":False},
32+
{"title":"Moment id","key":"moment_id","editable":False},
33+
{"title":"Date","key":"date","editable":False},
34+
{"title":"Content","key":"content","type":"textarea"},
35+
],
36+
}

demo/apps/tables/templates/Tables/list.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<div id="app">
1111
<tabs v-model:value="tab_current" type="card">
1212
<tab-pane v-for="item in tabs" :key="item" :label="item" :name="item">
13-
<apijson-table :table_name="item"></apijson-table>
13+
<apijson-table :table_name="item" :config="apijson_tables[item]"></apijson-table>
1414
</tab-pane>
1515
</tabs>
1616
</div>
@@ -21,7 +21,8 @@
2121
delimiters: ['{', '}'],
2222
data:{
2323
tab_current: null,
24-
tabs: {{=table_keys_json}}
24+
tabs: {{=table_keys_json}},
25+
apijson_tables: {{=apijson_tables_json}}
2526
}
2627
})
2728
</script>

demo/apps/tables/views.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
#coding=utf-8
22
from uliweb import expose, functions
3-
from json import dumps
43

54
@expose('/tables')
65
class Tables(object):
76
@expose('')
87
def list(self):
98
table_keys = settings.APIJSON_MODELS.keys()
10-
if request.user and functions.has_role(request.user,"ADMIN"):
11-
role = "ADMIN"
12-
elif request.user:
13-
role = "LOGIN"
9+
if request.user:
10+
if functions.has_role(request.user,"ADMIN"):
11+
role = "ADMIN"
12+
else:
13+
role = "OWNER"
1414
else:
1515
role = "UNKNOWN"
16+
apijson_tables = functions.get_apijson_tables(role)
1617
return {
17-
"table_keys_json":dumps(table_keys),
18-
"role":role
18+
"table_keys_json":json_dumps(table_keys),
19+
"apijson_tables_json":json_dumps(apijson_tables),
20+
"role":role,
1921
}

uliweb_apijson/apijson/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#coding=utf-8
2+
3+
def get_apijson_tables(role="UNKNOWN"):
4+
from uliweb import settings
5+
apijson_tables = dict(settings.APIJSON_TABLES.iteritems())
6+
for n in apijson_tables:
7+
c = apijson_tables[n]
8+
editable = c["editable"]
9+
if editable=="auto":
10+
editable = False
11+
POST = settings.APIJSON_MODELS[n]["POST"]
12+
if POST:
13+
roles = POST["roles"]
14+
if roles:
15+
editable = role in roles
16+
c["editable"] = editable
17+
return apijson_tables

uliweb_apijson/apijson/settings.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ user = {
1616
"PUT" : { "roles" : ["ADMIN","OWNER"] },
1717
"DELETE" : { "roles" : ["ADMIN","OWNER"] },
1818
}
19+
20+
[FUNCTIONS]
21+
get_apijson_tables = "uliweb_apijson.apijson.get_apijson_tables"

uliweb_apijson/apijson/templates/vue/inc_apijson_table.html

Lines changed: 123 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
<script>
22
Vue.component('apijson-table', {
33
delimiters: ['{', '}'],
4-
props: ["table_name"],
4+
props: ["table_name","config"],
55
template: `<div>
66
<i-table stripe border :columns="tcolumns" :data="tlist" @on-sort-change="table_on_sort_change"></i-table>
77
<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>
8-
<modal v-model="modal_view" title="View">
8+
<modal v-model="modal_view" :title="viewedit_label">
99
<i-form @submit.native.prevent :label-width="80">
10-
<form-item v-for="item in view_items" :key="item.key" :label="item.key">
11-
<i-input v-if="typeof item.value !=='boolean'" v-model="item.value" :readonly=true></i-input>
12-
<checkbox v-if="typeof item.value ==='boolean'" v-model="item.value" disabled></checkbox>
10+
<form-item v-for="item in viewedit_items" :key="item.key" :label="item.title">
11+
<i-input v-if="item.type=='input'" v-model="item.value" :readonly="!editable(item)"></i-input>
12+
<checkbox v-if="item.type=='checkbox'" v-model="item.value" :disabled="!editable(item)"></checkbox>
13+
<i-input v-if="item.type=='textarea'" v-model="item.value" type="textarea" :autosize="{minRows: 2,maxRows: 5}"></i-input>
14+
</form-item>
15+
<form-item v-if="config_editable" label="action">
16+
<i-button type="info" icon="ios-download" @click="save">Save</i-button>
1317
</form-item>
1418
</i-form>
1519
</modal>
@@ -21,12 +25,17 @@
2125
var thisp = this
2226
return {
2327
modal_view: false,
24-
view_items: [],
28+
viewedit_items: [],
29+
30+
edit_params: {},
31+
2532
modal_delete: false,
26-
delete_params:{},
27-
tcolumns: [
28-
{title:'#',key:'id',width:80},
29-
{
33+
delete_params: {},
34+
35+
tcolumns: [],
36+
tcolumns_preset: {
37+
"id": {title:'#',key:'id',width:80},
38+
"action": {
3039
title: 'Action',
3140
width: 140,
3241
render: (h, params) => {
@@ -44,7 +53,7 @@
4453
thisp.show(params)
4554
}
4655
}
47-
}, 'View'),
56+
}, this.viewedit_label),
4857
h('Button', {
4958
props: {
5059
type: 'error',
@@ -59,16 +68,23 @@
5968
]);
6069
}
6170
}
62-
],
71+
},
6372
tcolumns_init: false,
6473
tlist:[],
6574
query_count: 10,
6675
current_page: 1,
6776
total: 0,
6877
sort_key: "id",
69-
sort_order: "-"
78+
sort_order: "-",
79+
80+
config_editable: false,
81+
config_table_fields: null,
82+
config_viewedit_fields: null
7083
}
7184
},
85+
computed: {
86+
viewedit_label: function(){return this.config_editable?'Edit':'View'}
87+
},
7288
methods: {
7389
update_list: function(){
7490
var thisp = this
@@ -94,21 +110,30 @@
94110
if (data.code==200) {
95111
var arr = data["[]"]
96112
if (!thisp.tcolumns_init) {
97-
if (arr.length>0) {
98-
var item = arr[0]
99-
for (var k in item){
100-
if (k!="id") {
101-
var col = {title:k,key:k}
102-
if (typeof item[k] ==="boolean") {
103-
col["width"] = 80
104-
}
105-
else if (typeof item[k] ==="number") {
106-
col["width"] = 100
113+
if (thisp.config_table_fields!=null){
114+
thisp.tcolumns = thisp.config_table_fields
115+
thisp.tcolumns.push(thisp.tcolumns_preset["action"])
116+
thisp.tcolumns_init = true
117+
}
118+
else {
119+
thisp.tcolumns.push(thisp.tcolumns_preset["id"])
120+
if (arr.length>0) {
121+
var item = arr[0]
122+
for (var k in item){
123+
if (k!="id") {
124+
var col = {title:k,key:k}
125+
if (typeof item[k] ==="boolean") {
126+
col["width"] = 80
127+
}
128+
else if (typeof item[k] ==="number") {
129+
col["width"] = 100
130+
}
131+
thisp.tcolumns.push(col)
107132
}
108-
thisp.tcolumns.push(col)
109133
}
134+
thisp.tcolumns.push(thisp.tcolumns_preset["action"])
135+
thisp.tcolumns_init = true
110136
}
111-
thisp.tcolumns_init = true
112137
}
113138
}
114139
thisp.tlist = arr
@@ -119,20 +144,82 @@
119144
},
120145
show: function(params){
121146
var row = params.row
122-
this.view_items = []
123-
this.view_items.push({key:"id",value:row.id})
124-
for (var k in row){
125-
if (k!="id" && k[0]!="_") {
126-
value = row[k]
127-
this.view_items.push({key:k,value:value})
147+
this.viewedit_items = []
148+
if (this.config_viewedit_fields!=null) {
149+
for (var i in this.config_viewedit_fields) {
150+
var d = this.config_viewedit_fields[i]
151+
d.value = row[d.key]
152+
d.type = d.type || "input"
153+
this.viewedit_items.push(d)
128154
}
129155
}
156+
else {
157+
this.viewedit_items.push({title:"id",value:row.id,"type":"input"})
158+
var type2type = {
159+
"boolean":"checkbox"
160+
}
161+
for (var k in row){
162+
if (k!="id" && k[0]!="_") {
163+
var value = row[k]
164+
var type = type2type[typeof value] || "input"
165+
this.viewedit_items.push({title:k,value:value,type:type})
166+
}
167+
}
168+
}
169+
if (this.config_editable){
170+
this.edit_params = params
171+
}
172+
else {
173+
this.edit_params = null
174+
}
130175
this.modal_view = true
131176
},
177+
editable: function(item){
178+
var editable = true
179+
if (item.editable!=null) {editable=item.editable}
180+
return this.config_editable && editable && (item.key!="id")
181+
},
132182
remove: function(params){
133183
this.delete_params = params
134184
this.modal_delete = true
135185
},
186+
save: function(){
187+
var thisp = this
188+
var params = {
189+
"@tag": thisp.table_name
190+
}
191+
var record_params = {}
192+
var row = thisp.edit_params.row
193+
194+
for (var k in thisp.viewedit_items) {
195+
var d = thisp.viewedit_items[k]
196+
if (d.key=="id"|| d.value!=row[d.key]) {
197+
record_params[d.key] = d.value
198+
}
199+
}
200+
params[thisp.table_name] = record_params
201+
$.ajax({
202+
type: "POST",
203+
url: "{{=url_for('uliweb_apijson.apijson.views.ApiJson.put')}}",
204+
contentType: 'application/json',
205+
data: JSON.stringify(params),
206+
success: function (data) {
207+
if (data.code==200){
208+
thisp.$Notice.success({
209+
title: 'success update #'+row.id+' in table '+thisp.table_name,
210+
desc: data.msg
211+
})
212+
thisp.update_list()
213+
}
214+
else {
215+
thisp.$Notice.error({
216+
title: 'error when update #'+row.id+' in table '+thisp.table_name,
217+
desc: data.msg
218+
})
219+
}
220+
}
221+
})
222+
},
136223
real_remove: function(){
137224
var thisp = this
138225
var params = {
@@ -183,6 +270,11 @@
183270
}
184271
},
185272
mounted: function(){
273+
if (this.config!=null){
274+
this.config_editable = this.config.editable || false
275+
this.config_table_fields = this.config.table_fields || null
276+
this.config_viewedit_fields = this.config.viewedit_fields || null
277+
}
186278
this.update_list()
187279
}
188280
})

uliweb_apijson/apijson/views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -499,14 +499,14 @@ def _put_one(self,key,tag):
499499
obj_dict = {"id":id_}
500500
if ret:
501501
obj_dict["code"] = 200
502-
obj_dict["message"] = "success"
502+
obj_dict["msg"] = "success"
503503
obj_dict["count"] = 1
504504
else:
505505
obj_dict["code"] = 400
506-
obj_dict["message"] = "fail"
506+
obj_dict["msg"] = "failed when updating, maybe no change"
507507
obj_dict["count"] = 0
508508
self.rdict["code"] = 400
509-
self.rdict["message"] = "fail"
509+
self.rdict["msg"] = "failed when updating, maybe no change"
510510
self.rdict[key] = obj_dict
511511

512512
def delete(self):

0 commit comments

Comments
 (0)