bricks/bricks/dataviewer.js
2024-07-25 18:29:10 +08:00

340 lines
8.7 KiB
JavaScript

var bricks = window.bricks || {};
bricks.DataViewer = class extends bricks.VBox {
constructor(opts){
opts.width = '100%';
opts.height = '100%';
opts.overflow = 'hidden';
super(opts);
this.loader = new bricks.PageDataLoader({
url:this.opts.data_url,
params:this.opts.data_params,
pagerows:this.opts.page_rows,
method:this.opts.data_method,
cache_pages:this.opts.cache_limit
});
this.old_params = null;
this.select_row = null;
this.active_item = null;
this.loading = false;
this.data_offset = 0;
this.keyselectable = true;
this.bind('row_check_changed', this.show_check_event_data.bind(this));
schedule_once(this.build_all.bind(this), 0.1);
}
set_key_select_items(){
if (!this.scrollpanel) return;
var items = this.scrollpanel.children;
this.key_select_items = items.filter(i => i != items[0]);
}
async build_all(){
this.build_title_widget();
this.build_description_widget();
this.build_toolbar_widget();
this.build_records_area();
await this.build_other();
this.check_changed_row = null;
this.scrollpanel.bind('min_threshold', this.load_previous_page.bind(this));
this.scrollpanel.bind('max_threshold', this.load_next_page.bind(this));
await this.render();
this.set_key_select_items();
bricks.debug_obj = this.scrollpanel;
}
async build_other(){
}
async render(params) {
params = params || {};
if (params == this.old_params){
return;
}
this.old_params = params;
bricks.debug('params=', params, 'render() called');
var d = await this.loader.loadData(params);
if (d){
this.scrollpanel.clear_widgets();
await this.before_data_handle();
await this.dataHandle(d);
} else {
bricks.debug(params, 'load data return null');
}
}
async before_data_handle(){
}
async dataHandle(d){
var data = d.rows;
var page = d.add_page;
if (!data){
return;
}
await this.renderPageData(data, page);
if (d.delete_page){
this.delete_page(d.delete_page);
}
}
build_records_area(){
this.filler_widget = new bricks.Filler({});
this.add_widget(this.filler_widget)
this.scrollpanel = new bricks.VScrollPanel({});
this.filler_widget.add_widget(this.scrollpanel);
}
async renderPageData(data, page){
var pos;
if (! this.loader.is_max_page(page)){
data.reverse();
pos = this.data_offset;
} else {
pos = null;
}
for(var i=0; i<data.length;i++){
var rec = data[i];
await this.build_row(rec, page, pos);
}
}
async build_record_view(record){
/* will be overwrite by subclass */
var w = new bricks.VBox({width: '100px',height:'100px'});
w.set_css('test_box');
return w;
}
async build_row(record, page, pos){
var r = await this.build_record_view(record);
r.set_attribute('data-page', page);
this.scrollpanel.add_widget(r, pos);
}
show_check_event_data(event){
var d = event.params;
console.log('row_check_changed event data=', d);
}
build_toolbar_widget(){
var edit_names = [];
var tbdesc = {
width:'auto',
tools:[]
}
if (this.editable){
tbdesc.tools = [
{
name:'add',
tip:'add new record',
icon:this.editable.add_icon || bricks_resource('imgs/add.png')
},
{
name:'update',
tip:'update selected record',
selected_row:true,
icon:this.editable.update_icon || bricks_resource('imgs/update.png')
},
{
name:'delete',
tip:'delete selected record',
selected_row:true,
icon:this.editable.delete_icon || bricks_resource('imgs/delete.png')
}
];
tbdesc.tools.forEach(t => {
edit_names.push(t.name);
});
}
if (this.toolbar){
this.toolbar.tools.forEach(t => {
if (! edit_names.incloudes(t.name)){
tbdesc.tools.push(t);
}
});
}
if (tbdesc.tools.length == 0){
return;
}
this.toolbar_w = new bricks.IconTextBar(tbdesc);
this.add_widget(this.toolbar_w);
this.toolbar_w.bind('command', this.command_event_handle.bind(this));
}
command_event_handle(event){
var tdesc = event.params;
if (tdesc.selected_row && ! this.select_row){
bricks.show_error({title:'Error', message:'need select a row'});
return;
}
if (tdesc.name == 'add'){
this.add_record();
return;
}
if (tdesc.name == 'update'){
this.update_record(this.select_row);
return;
}
if (tdesc.name == 'delete'){
this.delete_record(this.select_row);
return;
}
var d = {
tabular:this,
row:this.select_row,
data:row.user_data
}
this.dispathc(t.name. d);
}
get_edit_fields(){
var fs = this.row_options.fields;
this.fields = [];
var exclouded = [];
if (this.row_options.editexclouded){
exclouded = this.row_options.editexclouded;
}
fs.forEach(f => {
if (!exclouded.includes(f.name)){
this.fields.push(f);
}
});
}
record_check_changed(event){
this.check_changed_row = event.params;
this.dispatch('row_check_changed', event.params.user_data);
}
async renew_record_view(form, row){
var d = form.getValue();
var record = bricks.extend(row.user_data, d);
row.renew(record);
}
get_hidefields(){
var fs = [];
var params = this.data_params || {};
for (var k in params){
fs.push({name:k, value:params[k], uitype:'hide'});
}
return fs;
}
add_record(info){
var hidefields = [];
if (!this.data_params){
this.data_params = {}
}
var fs = this.get_hidefields();
for (var i=0;i<this.fields.length;i++){
fs.push(this.fields[i]);
}
var f = new bricks.ModalForm({
"width":"90%",
"height":"70%",
"submit_url":this.editable.new_data_url,
"fields":fs
});
f.open();
f.bind('submited', this.add_record_finish.bind(this, f));
}
async add_record_finish(f, event){
f.dismiss();
var resp = event.params;
var desc = await resp.json();
var w = await bricks.widgetBuild(desc);
this.render();
}
update_record(){
var record = this.select_row.user_data;
var fields = this.get_hidefields();
for (var i=0; i< this.fields.length; i++){
var f = bricks.extend({}, this.fields[i]);
f.value = record[f.name];
fields.push(f);
}
var f = new bricks.ModalForm({
"width":"90%",
"height":"70%",
"submit_url":this.editable.update_data_url+'?id=' + record.id,
"fields":fields
});
f.open();
f.bind('submited', this.update_record_finish.bind(this, f));
}
update_cancel(f){
f.dismiss();
}
async update_record_finish(form, event){
var resp = event.params;
var desc = await resp.json();
var w = await bricks.widgetBuild(desc);
if (desc.widgettype == 'Message'){
await this.renew_record_view(form, this.select_row);
}
}
delete_record(row, record){
var conform_w = new bricks.Conform({
target:this,
title:'Delete conform',
message:'Are you sure to delete is record?'
});
conform_w.bind('conformed', this.delete_record_act.bind(this, row, record));
conform_w.bind('discard', conform_w.dismiss.bind(conform_w));
}
async delete_record_act(){
var id = this.select_row.user_data.id;
var url = this.editable.delete_data_url + '?id=' + id;
var hc = new bricks.HttpJson();
var desc = await hc.get(url);
var w = await bricks.widgetBuild(desc);
if (desc.widgettype == 'Message'){
this.scrollpanel.remove_widget(this.select_row);
this.select_row = null;
this.render();
}
}
async load_previous_page(){
// console.log('tabular:load_previous_page() called');
if (this.loading){
bricks.debug('this.loading is set, do not thing');
return;
}
var running = new bricks.Running({target:this});
this.loading = true;
try {
var d = await this.loader.loadPreviousPage();
if (d){
this.dataHandle(d);
var total = this.scrollpanel.dom_element.scrollHeight - this.scrollpanel.dom_element.clientHeight;
this.scrollpanel.dom_element.scrollTop = d.pos_rate * total;
} else {
bricks.debug(this.loader, 'load previous page error');
}
} catch (e) {
bricks.debug('e=', e);
}
this.loading = false;
running.dismiss();
}
async load_next_page(){
// console.log('tabular:load_next_page() called');
if (this.loading){
bricks.debug('this.loading is set, do not thing');
return;
}
var running = new bricks.Running({target:this});
this.loading = true;
try {
var d = await this.loader.loadNextPage();
if (d){
this.dataHandle(d);
var total = this.scrollpanel.dom_element.scrollHeight - this.scrollpanel.dom_element.clientHeight;
this.scrollpanel.dom_element.scrollTop = d.pos_rate * total;
} else {
bricks.debug(this.loader, 'load next page error');
}
} catch (e){
bricks.debug('error happened', e);
}
this.loading = false;
running.dismiss();
bricks.debug('load_next_page() finished');
}
delete_page(page){
var items = this.dom_element.querySelectorAll('[data-page="' + page + '"]');
for (var i=0;i<items.length;i++) {
var w = items[i].bricks_widget;
this.scrollpanel.remove_widget(w);
}
}
}
bricks.Factory.register('DataViewer', bricks.DataViewer);