-
+
`;
@@ -18001,20 +18010,32 @@ var list = class BaseList {
renderRow(i, data) {
let row = this.getRow(i);
row.innerHTML = this.getRowBodyHTML(data);
- row.style.display = 'block';
+ row.setAttribute('data-name', data.name);
+ row.style.display = 'flex';
}
getRowBodyHTML(data) {
- return `
` + this.getRowHTML(data);
+ return `
+
+
` + this.getRowHTML(data);
}
getRowHTML(data) {
- return `
${data.name}`;
+ return `
${data.name}
`;
}
getRow(i) {
if (!this.rows[i]) {
- this.rows[i] = frappejs.ui.add('div', 'list-row', this.body);
+ this.rows[i] = frappejs.ui.add('div', 'list-row row no-gutters', this.body);
+
+ // open on click
+ let doctype = this.doctype;
+ this.rows[i].addEventListener('click', function(e) {
+ if (!e.target.tagName !== 'input') {
+ let name = this.getAttribute('data-name');
+ frappejs.router.setRoute('edit', doctype, name);
+ }
+ });
}
return this.rows[i];
}
@@ -18061,6 +18082,7 @@ class BaseControl {
if (this.setup) {
this.setup();
}
+ this.make();
}
bind(doc) {
@@ -18069,7 +18091,6 @@ class BaseControl {
}
refresh() {
- this.make();
this.setDocValue();
}
@@ -18080,20 +18101,18 @@ class BaseControl {
}
make() {
- if (!this.input) {
- if (!this.onlyInput) {
- this.makeFormGroup();
- this.makeLabel();
- }
- this.makeInput();
- this.setInputName();
- this.setRequiredAttribute();
- this.setDisabled();
- if (!this.onlyInput) {
- this.makeDescription();
- }
- this.addChangeHandler();
+ if (!this.onlyInput) {
+ this.makeFormGroup();
+ this.makeLabel();
}
+ this.makeInput();
+ this.setInputName();
+ this.setRequiredAttribute();
+ this.setDisabled();
+ if (!this.onlyInput) {
+ this.makeDescription();
+ }
+ this.addChangeHandler();
}
makeFormGroup() {
@@ -20865,6 +20884,10 @@ class LinkControl extends base {
make() {
super.make();
this.input.setAttribute('type', 'text');
+ this.setupAwesomplete();
+ }
+
+ setupAwesomplete() {
this.awesomplete = new awesomplete(this.input, {
autoFirst: true,
minChars: 0,
@@ -20898,6 +20921,7 @@ class LinkControl extends base {
});
}
});
+
}
async getList(query) {
@@ -26814,20 +26838,21 @@ var modal = class Modal extends observable {
class TableControl extends base {
make() {
- if (!this.datatable) {
- this.wrapper = frappejs.ui.add('div', 'table-wrapper', this.getInputParent());
- this.wrapper.innerHTML =
- `
-
-
-
-
`;
+ this.makeWrapper();
+ this.makeDatatable();
+ this.setupToolbar();
+ }
- this.makeDatatable();
- this.setupToolbar();
- }
+ makeWrapper() {
+ this.wrapper = frappejs.ui.add('div', 'table-wrapper', this.getInputParent());
+ this.wrapper.innerHTML =
+ `
+
+
+
+
`;
}
makeDatatable() {
@@ -26989,7 +27014,7 @@ class TextControl extends base {
var text = TextControl;
-const control_classes = {
+const controlClasses = {
Data: data,
Date: date,
Currency: currency,
@@ -27004,12 +27029,11 @@ const control_classes = {
var controls$1 = {
getControlClass(fieldtype) {
- return control_classes[fieldtype];
+ return controlClasses[fieldtype];
},
makeControl({field, form, parent}) {
- const control_class = this.getControlClass(field.fieldtype);
- let control = new control_class({field:field, form:form, parent:parent});
- control.make();
+ const controlClass = this.getControlClass(field.fieldtype);
+ let control = new controlClass({field:field, form:form, parent:parent});
return control;
}
};
@@ -27123,7 +27147,7 @@ var form = class BaseForm extends observable {
if (this.meta.settings && this.actions.includes('settings')) {
let menu = this.container.getDropdown(frappejs._('Menu'));
menu.addItem(frappejs._('Settings...'), () => {
- frappejs.router.setRoute('edit', frappejs.slug(this.meta.settings), this.meta.settings);
+ frappejs.desk.showFormModal(frappejs.slug(this.meta.settings), this.meta.settings);
});
}
@@ -27147,6 +27171,18 @@ var form = class BaseForm extends observable {
// flag so that name is cleared only once
await this.doc.set('name', '');
}
+ this.setTitle();
+ }
+
+ setTitle() {
+ const doctype = this.doc.meta.name;
+ if (this.doc.meta.isSingle || !this.doc.meta.showTitle) {
+ this.container.setTitle(doctype);
+ } else if (this.doc._notInserted) {
+ this.container.setTitle(frappejs._('New {0}', doctype));
+ } else {
+ this.container.setTitle(`${doctype} ${this.doc.name}`);
+ }
}
async bindEvents(doc) {
@@ -27296,10 +27332,23 @@ var formpage = class FormPage extends page {
async showDoc(doctype, name) {
try {
await this.form.setDoc(doctype, name);
+ this.setActiveListRow(doctype, name);
} catch (e) {
this.renderError(e.status_code, e.message);
}
}
+
+ setActiveListRow(doctype, name) {
+ let activeListRow = document.querySelector('.list-page .list-body .list-row.active');
+ if (activeListRow) {
+ activeListRow.classList.remove('active');
+ }
+
+ let myListRow = document.querySelector(`.list-body[data-doctype="${doctype}"] .list-row[data-name="${name}"]`);
+ if (myListRow) {
+ myListRow.classList.add('active');
+ }
+ }
};
var listpage = class ListPage extends page {
@@ -27327,47 +27376,6 @@ var listpage = class ListPage extends page {
}
};
-var navbar = class Navbar {
- constructor({brand_label = 'Home'} = {}) {
- Object.assign(this, arguments[0]);
- this.items = {};
- this.navbar = frappejs.ui.add('div', 'navbar navbar-expand-md border-bottom navbar-dark bg-dark', document.querySelector('body'));
-
- this.brand = frappejs.ui.add('a', 'navbar-brand', this.navbar);
- this.brand.href = '#';
- this.brand.textContent = brand_label;
-
- this.toggler = frappejs.ui.add('button', 'navbar-toggler', this.navbar);
- this.toggler.setAttribute('type', 'button');
- this.toggler.setAttribute('data-toggle', 'collapse');
- this.toggler.setAttribute('data-target', 'desk-navbar');
- this.toggler.innerHTML = `
`;
-
- this.navbar_collapse = frappejs.ui.add('div', 'collapse navbar-collapse', this.navbar);
- this.navbar_collapse.setAttribute('id', 'desk-navbar');
-
- this.nav = frappejs.ui.add('ul', 'navbar-nav mr-auto', this.navbar_collapse);
- }
-
- addItem(label, route) {
- let item = frappejs.ui.add('li', 'nav-item', this.nav);
- item.link = frappejs.ui.add('a', 'nav-link', item);
- item.link.textContent = label;
- item.link.href = route;
- this.items[label] = item;
- return item;
- }
-
- add_dropdown(label) {
-
- }
-
- add_search() {
- let form = frappejs.ui.add('form', 'form-inline my-2 my-md-0', this.nav);
-
- }
-};
-
var menu = class DeskMenu {
constructor(parent) {
this.parent = parent;
@@ -27376,27 +27384,29 @@ var menu = class DeskMenu {
}
make() {
- this.listGroup = frappejs.ui.add('div', 'list-group list-group-flush', this.parent);
+ this.listGroup = frappejs.ui.add('div', 'list-body', this.parent);
}
addItem(label, action) {
- let item = frappejs.ui.add('a', 'list-group-item list-group-item-action', this.listGroup);
+ let item = frappejs.ui.add('div', 'list-row', this.listGroup);
item.textContent = label;
if (typeof action === 'string') {
- item.href = action;
this.routeItems[action] = item;
- } else {
- item.addEventListener('click', () => {
- action();
- this.setActive(item);
- });
}
+ item.addEventListener('click', async () => {
+ if (typeof action === 'string') {
+ await frappejs.router.setRoute(action);
+ } else {
+ action();
+ }
+ this.setActive(item);
+ });
}
setActive() {
if (this.routeItems[window.location.hash]) {
let item = this.routeItems[window.location.hash];
- let className = 'list-group-item-secondary';
+ let className = 'active';
let activeItem = this.listGroup.querySelector('.' + className);
if (activeItem) {
@@ -27438,11 +27448,6 @@ var formmodal = class FormModal extends modal {
async showWith(doctype, name) {
await this.form.setDoc(doctype, name);
- if (this.form.doc._notInserted) {
- this.setTitle(frappejs._('New {0}', doctype));
- } else {
- this.setTitle(`${doctype} ${name}`);
- }
this.show();
this.$modal.find('input:first').focus();
}
@@ -27454,9 +27459,9 @@ var desk = class Desk {
frappejs.router.listen();
let body = document.querySelector('body');
- this.navbar = new navbar();
- this.container = frappejs.ui.add('div', 'container-fluid', body);
- this.containerRow = frappejs.ui.add('div', 'row', this.container);
+ //this.navbar = new Navbar();
+ this.container = frappejs.ui.add('div', '', body);
+ this.containerRow = frappejs.ui.add('div', 'row no-gutters', this.container);
this.makeColumns(columns);
this.pages = {
@@ -28234,6 +28239,7 @@ var isSingle$5 = 0;
var istable$1 = 0;
var keywordFields$5 = [];
var settings = "Invoice Settings";
+var showTitle = true;
var fields$5 = [{"fieldname":"date","label":"Date","fieldtype":"Date"},{"fieldname":"customer","label":"Customer","fieldtype":"Link","target":"Customer","required":1},{"fieldname":"items","label":"Items","fieldtype":"Table","childtype":"Invoice Item","required":true},{"fieldname":"total","label":"Total","fieldtype":"Currency","formula":"doc.getSum('items', 'amount')","required":true,"disabled":true}];
var invoice = {
name: name$5,
@@ -28242,6 +28248,7 @@ var invoice = {
istable: istable$1,
keywordFields: keywordFields$5,
settings: settings,
+ showTitle: showTitle,
fields: fields$5
};
@@ -28252,6 +28259,7 @@ var invoice$1 = Object.freeze({
istable: istable$1,
keywordFields: keywordFields$5,
settings: settings,
+ showTitle: showTitle,
fields: fields$5,
default: invoice
});
@@ -28396,6 +28404,21 @@ var account_client = {
List: AccountList
};
+class InvoiceList extends list {
+ getFields() {
+ return ['name', 'customer', 'total'];
+ }
+ getRowHTML(data) {
+ return `
${data.name}
+
${data.customer}
+
${frappejs.format(data.total, {fieldtype:"Currency"})}
`;
+ }
+}
+
+var invoiceClient = {
+ List: InvoiceList
+};
+
client.start({
columns: 3,
server: 'localhost:8000'
@@ -28413,6 +28436,7 @@ client.start({
frappe.modules.todo_client = todo_client;
frappe.modules.account_client = account_client;
+ frappe.modules.invoice_client = invoiceClient;
frappe.desk.menu.addItem('ToDo', '#list/todo');
frappe.desk.menu.addItem('Accounts', '#list/account');
diff --git a/models/doctype/invoice/invoice.json b/models/doctype/invoice/invoice.json
index 8c3ef22b..cdc6b1fc 100644
--- a/models/doctype/invoice/invoice.json
+++ b/models/doctype/invoice/invoice.json
@@ -5,6 +5,7 @@
"istable": 0,
"keywordFields": [],
"settings": "Invoice Settings",
+ "showTitle": true,
"fields": [
{
"fieldname": "date",
diff --git a/models/doctype/invoice/invoiceClient.js b/models/doctype/invoice/invoiceClient.js
new file mode 100644
index 00000000..676a3899
--- /dev/null
+++ b/models/doctype/invoice/invoiceClient.js
@@ -0,0 +1,17 @@
+const BaseList = require('frappejs/client/view/list');
+const frappe = require('frappejs');
+
+class InvoiceList extends BaseList {
+ getFields() {
+ return ['name', 'customer', 'total'];
+ }
+ getRowHTML(data) {
+ return `
${data.name}
+
${data.customer}
+
${frappe.format(data.total, {fieldtype:"Currency"})}
`;
+ }
+}
+
+module.exports = {
+ List: InvoiceList
+}
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 045bf8fc..f877a04a 100644
--- a/src/index.js
+++ b/src/index.js
@@ -18,6 +18,7 @@ client.start({
frappe.modules.todo_client = require('frappejs/models/doctype/todo/todo_client.js');
frappe.modules.account_client = require('../models/doctype/account/account_client.js');
+ frappe.modules.invoice_client = require('../models/doctype/invoice/invoiceClient.js');
frappe.desk.menu.addItem('ToDo', '#list/todo');
frappe.desk.menu.addItem('Accounts', '#list/account');