2
0
mirror of https://github.com/frappe/books.git synced 2024-11-14 01:14:03 +00:00

[ui] add links to forms

This commit is contained in:
Rushabh Mehta 2018-03-26 14:23:46 +05:30
parent dc6eab2d61
commit 3646e7d778
8 changed files with 98 additions and 13 deletions

View File

@ -30,16 +30,23 @@ module.exports = class TablePage extends Page {
this.filterSelector.reset(this.doctype); this.filterSelector.reset(this.doctype);
} }
if (frappe.flags.filters) { if (frappe.params.filters) {
this.filterSelector.setFilters(frappe.flags.filters); this.filterSelector.setFilters(frappe.params.filters);
frappe.flags.filters = null;
} }
frappe.params = null;
if (!this.modelTable) { if (!this.modelTable) {
this.modelTable = new ModelTable({ this.modelTable = new ModelTable({
doctype: this.doctype, doctype: this.doctype,
parent: this.tableWrapper, parent: this.tableWrapper,
layout: 'fluid' layout: 'fluid',
getRowData: async (rowIndex) => {
return await frappe.getDoc(this.doctype, this.data[rowIndex].name);
},
setValue: async (control) => {
await control.handleChange();
await control.doc.update();
}
}); });
} }
@ -48,14 +55,14 @@ module.exports = class TablePage extends Page {
async run() { async run() {
this.displayFilters(); this.displayFilters();
const data = await frappe.db.getAll({ this.data = await frappe.db.getAll({
doctype: this.doctype, doctype: this.doctype,
fields: ['*'], fields: ['*'],
filters: this.filterSelector.getFilters(), filters: this.filterSelector.getFilters(),
start: this.start, start: this.start,
limit: 500 limit: 500
}); });
this.modelTable.refresh(data); this.modelTable.refresh(this.data);
} }
displayFilters() { displayFilters() {

View File

@ -4,7 +4,7 @@ const controls = require('frappejs/client/view/controls');
const Modal = require('frappejs/client/ui/modal'); const Modal = require('frappejs/client/ui/modal');
module.exports = class ModelTable { module.exports = class ModelTable {
constructor({doctype, parent, layout, parentControl, getRowDoc, constructor({doctype, parent, layout, parentControl, getRowData,
isDisabled, getTableData}) { isDisabled, getTableData}) {
Object.assign(this, arguments[0]); Object.assign(this, arguments[0]);
this.meta = frappe.getMeta(this.doctype); this.meta = frappe.getMeta(this.doctype);
@ -75,17 +75,16 @@ module.exports = class ModelTable {
control.skipChangeEvent = true; control.skipChangeEvent = true;
return { return {
initValue: (value, rowIndex, column) => { initValue: async (value, rowIndex, column) => {
let doc = this.getRowDoc(rowIndex);
column.activeControl = control; column.activeControl = control;
control.parentControl = this.parentControl; control.parentControl = this.parentControl;
control.doc = doc; control.doc = await this.getRowData(rowIndex);
control.setFocus(); control.setFocus();
control.setInputValue(control.doc[column.id]); control.setInputValue(control.doc[column.id]);
return control; return control;
}, },
setValue: async (value, rowIndex, column) => { setValue: async (value, rowIndex, column) => {
control.handleChange(); await this.setValue(control);
}, },
getValue: () => { getValue: () => {
return control.getInputValue(); return control.getInputValue();
@ -94,6 +93,10 @@ module.exports = class ModelTable {
} }
async setValue(control) {
await control.handleChange();
}
getControlModal(field) { getControlModal(field) {
this.modal = new Modal({ this.modal = new Modal({
title: frappe._('Edit {0}', field.label), title: frappe._('Edit {0}', field.label),

View File

@ -10,9 +10,9 @@ class TableControl extends BaseControl {
parent: this.wrapper.querySelector('.datatable-wrapper'), parent: this.wrapper.querySelector('.datatable-wrapper'),
parentControl: this, parentControl: this,
layout: this.layout || 'ratio', layout: this.layout || 'ratio',
getRowDoc: (rowIndex) => this.doc[this.fieldname][rowIndex], getTableData: () => this.getTableData(),
getRowData: (rowIndex) => this.doc[this.fieldname][rowIndex],
isDisabled: () => this.isDisabled(), isDisabled: () => this.isDisabled(),
getTableData: () => this.getTableData()
}); });
this.setupToolbar(); this.setupToolbar();
} }

View File

@ -10,6 +10,7 @@ module.exports = class BaseForm extends Observable {
this.controls = {}; this.controls = {};
this.controlList = []; this.controlList = [];
this.sections = []; this.sections = [];
this.links = [];
this.meta = frappe.getMeta(this.doctype); this.meta = frappe.getMeta(this.doctype);
if (this.setup) { if (this.setup) {
@ -193,6 +194,49 @@ module.exports = class BaseForm extends Observable {
} }
} }
setLinks(label, options) {
// set links to helpful reports as identified by this.meta.links
if (this.meta.links) {
let links = this.getLinks();
if (!links.equals(this.links)) {
this.refreshLinks(links);
this.links = links;
}
}
}
getLinks() {
let links = [];
for (let link of this.meta.links) {
if (link.condition(this)) {
links.push(link);
}
}
return links;
}
refreshLinks(links) {
this.container.clearLinks();
for(let link of links) {
// make the link
this.container.addLink(link.label, () => {
let options = link.action(this);
if (options) {
if (options.params) {
// set route parameters
frappe.params = options.params;
}
if (options.route) {
// go to the given route
frappe.router.setRoute(...options.route);
}
}
});
}
}
async bindEvents(doc) { async bindEvents(doc) {
if (this.doc && this.docListener) { if (this.doc && this.docListener) {
// stop listening to the old doc // stop listening to the old doc
@ -250,6 +294,7 @@ module.exports = class BaseForm extends Observable {
control.refresh(); control.refresh();
} }
this.trigger('refresh', this); this.trigger('refresh', this);
this.setLinks();
} }
async submit() { async submit() {

View File

@ -46,6 +46,10 @@ module.exports = class Page extends Observable {
return link; return link;
} }
clearLinks() {
frappe.ui.empty(this.linksElement);
}
hide() { hide() {
this.parent.activePage = null; this.parent.activePage = null;
this.wrapper.classList.add('hide'); this.wrapper.classList.add('hide');

View File

@ -20,6 +20,8 @@ module.exports = {
this.forms = {}; this.forms = {};
this.views = {}; this.views = {};
this.flags = {}; this.flags = {};
// temp params while calling routes
this.params = {};
}, },
registerLibs(common) { registerLibs(common) {

View File

@ -41,5 +41,24 @@ module.exports = {
"label": "Description", "label": "Description",
"fieldtype": "Text" "fieldtype": "Text"
} }
],
links: [
{
label: 'Close',
condition: (form) => form.doc.status !== 'Closed',
action: async (form) => {
await form.doc.set('status', 'Closed');
await form.doc.update();
}
},
{
label: 'Re-Open',
condition: (form) => form.doc.status !== 'Open',
action: async (form) => {
await form.doc.set('status', 'Open');
await form.doc.update();
}
}
] ]
} }

View File

@ -1,3 +1,8 @@
Array.prototype.equals = function( array ) {
return this.length == array.length &&
this.every( function(item,i) { return item == array[i] } );
}
module.exports = { module.exports = {
slug(text) { slug(text) {
return text.toLowerCase().replace(/ /g, '_'); return text.toLowerCase().replace(/ /g, '_');