diff --git a/setup/index.js b/setup/index.js
index bba39665..2c9d4b44 100644
--- a/setup/index.js
+++ b/setup/index.js
@@ -1,7 +1,6 @@
const frappe = require('frappejs');
const utils = require('frappejs/client/ui/utils');
const slideConfigs = require('./config');
-const Tree = require('frappejs/client/ui/tree');
const FormLayout = require('frappejs/client/view/formLayout');
const Observable = require('frappejs/utils/observable');
diff --git a/www/dist/css/style.css b/www/dist/css/style.css
index ee316316..40a1c6a6 100644
--- a/www/dist/css/style.css
+++ b/www/dist/css/style.css
@@ -7498,76 +7498,10 @@ mark {
margin: 0.25rem; }
.vertical-margin {
margin: 1rem 0px; }
-.tree {
+.tree-body {
padding: 1rem 2rem; }
-.tree li {
- list-style: none; }
-ul.tree-children {
- padding-left: 2rem; }
-.tree-link {
- cursor: pointer;
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- width: 100%; }
-.tree-link:hover {
- background-color: #f8f9fa; }
-.tree-link .node-parent {
- color: #6c757d;
- width: 24px;
- height: 24px;
- text-align: center; }
-.tree-link .node-leaf {
- color: #ced4da; }
-.tree-link .node-parent, .tree-link .node-leaf {
- padding: 0.5rem; }
-.tree-link.active a {
- color: #6c757d; }
-.tree-hover {
- background-color: #e9ecef;
- min-height: 20px;
- border: 1px solid #6c757d; }
-.tree-node-toolbar {
- display: inline-block;
- padding: 0px 5px;
- margin-left: 15px;
- margin-bottom: -4px;
- margin-top: -8px; }
-.tree.with-skeleton, .tree.with-skeleton .tree-node {
- position: relative; }
-.tree.with-skeleton.opened::before, .tree.with-skeleton:last-child::after, .tree.with-skeleton .tree-node.opened::before, .tree.with-skeleton .tree-node:last-child::after {
- content: '';
- position: absolute;
- top: 12px;
- left: 7px;
- height: calc(100% - 23px);
- width: 1px;
- background: #ced4da;
- z-index: -1; }
-.tree.with-skeleton:last-child::after, .tree.with-skeleton .tree-node:last-child::after {
- top: 11px;
- left: -13px;
- height: calc(100% - 15px);
- width: 3px;
- background: #fff; }
-.tree.with-skeleton.opened > .tree-children > .tree-node > .tree-link::before, .tree.with-skeleton .tree-node.opened > .tree-children > .tree-node > .tree-link::before {
- content: '';
- position: absolute;
- width: 18px;
- height: 1px;
- top: 10px;
- left: -12px;
- z-index: -1;
- background: #ced4da; }
-.tree.with-skeleton.opened::before {
- left: 22px;
- top: 33px;
- height: calc(100% - 67px); }
-.tree-link.active ~ .balance-area {
- color: #6c757d !important; }
+f-tree-node {
+ --tree-node-hover: #f8f9fa; }
.setup-container {
margin: 40px auto;
padding: 20px 0px;
diff --git a/www/dist/js/bundle.js b/www/dist/js/bundle.js
index 0fbc299f..ff5da298 100644
--- a/www/dist/js/bundle.js
+++ b/www/dist/js/bundle.js
@@ -27086,6 +27086,35 @@ var ui = {
element.parentNode.removeChild(element);
},
+ on(element, event, selector, handler) {
+ if (!handler) {
+ handler = selector;
+ this.bind(element, event, handler);
+ } else {
+ this.delegate(element, event, selector, handler);
+ }
+ },
+
+ off(element, event, handler) {
+ element.removeEventListener(event, handler);
+ },
+
+ bind(element, event, callback) {
+ event.split(/\s+/).forEach(function (event) {
+ element.addEventListener(event, callback);
+ });
+ },
+
+ delegate(element, event, selector, callback) {
+ element.addEventListener(event, function (e) {
+ const delegatedTarget = e.target.closest(selector);
+ if (delegatedTarget) {
+ e.delegatedTarget = delegatedTarget;
+ callback.call(this, e, delegatedTarget);
+ }
+ });
+ },
+
empty(element) {
while (element.firstChild) {
element.removeChild(element.firstChild);
@@ -28318,173 +28347,115 @@ var utils$3 = {
}
};
-class Tree {
- constructor({parent, label, iconSet, withSkeleton, method}) {
- Object.assign(this, arguments[0]);
- this.nodes = {};
- if(!iconSet) {
- this.iconSet = {
- open: octicons["triangle-down"].toSVG({ "width": 10, "class": "node-parent"}),
- closed: octicons["triangle-right"].toSVG({ "width": 5, "class": "node-parent"}),
- leaf: octicons["primitive-dot"].toSVG({ "width": 7, "class": "node-leaf"})
- };
+const iconSet = {
+ open: octicons["triangle-down"].toSVG({ width: "12", height: "12", "class": "tree-icon-open" }),
+ close: octicons["triangle-right"].toSVG({ width: "12", height: "12", "class": "tree-icon-closed" })
+};
+
+let TreeTemplate = document.createElement('template');
+TreeTemplate.innerHTML = `
+
+
+
+
+`;
+
+class Tree extends HTMLElement {
+ constructor() {
+ super();
+
+ this.attachShadow({ mode: 'open' })
+ .appendChild(TreeTemplate.content.cloneNode(true));
}
-
- make() {
- this.tree = frappejs.ui.create('div', {
- inside: this.parent,
- className: 'tree ' + (this.withSkeleton ? 'with-skeleton' : '')
- });
-
- this.rootNode = this.makeNode(this.label, this.label, true, null, this.tree);
- this.expandNode(this.rootNode);
- }
-
- refresh() {
- // this.selectedNode.parentNode &&
- // this.loadChildren(this.selectedNode.parentNode, true);
- }
-
- async loadChildren(node, deep=false) {
- let children = !deep ? await this.method(node) : await this.getAllNodes(node);
- this.renderNodeChildren(node, children);
- }
-
- renderChildrenDeep(dataList) {
- dataList.map(d => { this.renderNodeChildren(this.nodes[d.parent], d.data); });
- }
-
- renderNodeChildren(node, dataSet=[]) {
- frappejs.ui.empty(node.childrenList);
-
- dataSet.forEach(data => {
- let parentNode = this.nodes[node.value];
- let childNode = this.makeNode(data.label || data.value, data.value,
- data.expandable, parentNode);
- childNode.treeLink.dataset.nodeData = data;
- });
- node.expanded = false;
-
- // As children loaded
- node.loaded = true;
- this.onNodeClick(node, true);
- }
-
- getAllNodes() { }
-
- makeNode(label, value, expandable, parentNode, parentEl) {
- let node = {
- label: label,
- value: value,
- loaded: 0,
- expanded: 0,
- expandable: expandable,
- };
-
- if(parentNode){
- node.parentNode = parentNode;
- node.parent = parentNode.childrenList;
- node.isRoot = 0;
- } else {
- node.isRoot = 1;
- node.parent = parentEl;
- }
-
- this.nodes[value] = node;
- this.buildNodeElement(node);
- this.onRender && this.onRender(node);
-
- return node;
- }
-
- buildNodeElement(node) {
- node.parentLi = frappejs.ui.create('li', {
- inside: node.parent,
- className: 'tree-node'
- });
-
- let iconHtml = '';
- if(this.iconSet) {
- iconHtml = node.expandable ? this.iconSet.closed : this.iconSet.leaf;
- }
- let labelEl = ` ${node.label}`;
-
- node.treeLink = frappejs.ui.create('span', {
- inside: node.parentLi,
- className: 'tree-link',
- 'data-label': node.label,
- innerHTML: iconHtml + labelEl
- });
- node.treeLink.dataset.node = node;
- node.treeLink.addEventListener('click', () => {
- this.onNodeClick(node);
- });
-
- node.childrenList = frappejs.ui.create('ul', {
- inside: node.parentLi,
- className: 'tree-children hide'
- });
-
- // if(this.toolbar) {
- // node.toolbar = this.getToolbar(node).insertAfter(node.treeLink);
- // }
- }
-
- async onNodeClick(node, click = true) {
- this.setSelectedNode(node);
- if(click) {
- this.onClick && this.onClick(node);
- }
- await this.expandNode(node);
- // select link
- utils$3.activate(this.tree, node.treeLink, 'tree-link', 'active');
- if(node.toolbar) this.showToolbar(node);
- }
-
- async expandNode(node) {
- if(node.expandable) {
- await this.toggleNode(node);
- }
-
- node.expanded = !node.expanded;
- // node.parent.classList.toggle('opened', node.expanded);
- node.parent.classList.add('opened');
- node.parentLi.classList.add('opened');
- }
-
- async toggleNode(node) {
- if(!node.loaded) await this.loadChildren(node);
-
- // expand children
- if(node.childrenList) {
- if(node.childrenList.innerHTML.length) {
- if (node.expanded) {
- node.childrenList.classList.add('hide');
- } else {
- node.childrenList.classList.remove('hide');
- }
- }
-
- // open close icon
- if(this.iconSet) {
- const oldIcon = node.treeLink.querySelector('svg');
- const newIconKey = node.expanded ? 'closed' : 'open';
- const newIcon = frappejs.ui.create(this.iconSet[newIconKey]);
- node.treeLink.replaceChild(newIcon, oldIcon);
- }
- }
- }
-
- getSelectedNode() { return this.selectedNode; }
-
- setSelectedNode(node) { this.selectedNode = node; }
-
- showToolbar() { }
}
-var tree = Tree;
+window.customElements.define('f-tree', Tree);
+
+let TreeNodeTemplate = document.createElement('template');
+TreeNodeTemplate.innerHTML = `
+
+
+
+`;
+
+
+class TreeNode extends HTMLElement {
+ static get observedAttributes() {
+ return ['label', 'expanded']
+ }
+
+ constructor() {
+ super();
+
+ let shadowRoot = this.attachShadow({ mode: 'open' });
+ shadowRoot.appendChild(TreeNodeTemplate.content.cloneNode(true));
+ this.iconEl = shadowRoot.querySelector('.tree-node-icon');
+ this.labelEl = shadowRoot.querySelector('.tree-node-label');
+ this.actionsEl = shadowRoot.querySelector('.tree-node-actions');
+ }
+
+ attributeChangedCallback(name, oldValue, newValue) {
+ console.log(name, oldValue, newValue);
+
+ switch(name) {
+ case 'label': {
+ this.labelEl.innerHTML = newValue || '';
+ break;
+ }
+
+ case 'expanded': {
+ this.expanded = this.hasAttribute('expanded');
+
+ if (this.expanded) {
+ this.iconEl.innerHTML = iconSet.open;
+ } else {
+ this.iconEl.innerHTML = iconSet.close;
+ }
+ break;
+ }
+
+ default: break;
+ }
+ }
+}
+
+window.customElements.define('f-tree-node', TreeNode);
// const keyboard = require('frappejs/client/ui/keyboard');
@@ -28527,11 +28498,6 @@ var tree$2 = class BaseTree extends list {
let rootLabel = accountingSettings.companyName;
this.renderTree(rootLabel);
-
- // this.clearEmptyRows();
- // this.updateMore(data.length > this.pageLength);
- // this.selectDefaultRow();
- // this.setActiveListRow();
this.trigger('state-change');
}
@@ -28546,18 +28512,74 @@ var tree$2 = class BaseTree extends list {
}
renderTree(rootLabel) {
- this.tree = new tree({
+ // const tree = new Tree();
+ // tree.getChildNodes = async node => {
+ // const children = await this.getData(node) || [];
+ // return children.map(d => ({
+ // label: d.name,
+ // value: d.name,
+ // expandable: d.isGroup
+ // }));
+ // }
+ // tree.rootNode = {
+ // label: rootLabel,
+ // value: rootLabel,
+ // isRoot: 1,
+ // expandable: 1
+ // }
+ // this.body.appendChild(tree);
+
+ this.rootNode = {
label: rootLabel,
- parent: this.body,
- method: async node => {
- const children = await this.getData(node) || [];
- return children.map(d => ({
- label: d.name,
- value: d.name,
- expandable: d.isGroup
- }));
+ value: rootLabel,
+ isRoot: true,
+ expanded: true,
+ children: []
+ };
+
+ this.treeWrapper = frappejs.ui.create(`
+
+
+
+
+
+
+
+
+ `);
+
+ this.body.appendChild(this.treeWrapper);
+
+ frappejs.ui.on(this.treeWrapper, 'click', 'f-tree-node', async (e, treeNode) => {
+ if (treeNode.expanded) {
+ treeNode.removeAttribute('expanded');
+ } else {
+ treeNode.setAttribute('expanded', '');
}
+
+
+ // if (treeNode.hasAttribute('is-root')) {
+ // node = this.rootNode;
+ // } else {
+
+ // }
+
+
});
+
+
+ // this.tree = new Tree({
+ // label: rootLabel,
+ // parent: this.body,
+ // method: async node => {
+ // const children = await this.getData(node) || [];
+ // return children.map(d => ({
+ // label: d.name,
+ // value: d.name,
+ // expandable: d.isGroup
+ // }));
+ // }
+ // });
}
async getData(node) {
@@ -28585,65 +28607,6 @@ var tree$2 = class BaseTree extends list {
return fields;
}
- getNameHTML(data) {
- return `${data[this.meta.titleField]}`;
- }
-
- getRow(i) {
- if (!this.rows[i]) {
- let row = frappejs.ui.add('div', 'list-row row no-gutters', this.body);
-
- // open on click
- let me = this;
- row.addEventListener('click', async function(e) {
- if (!e.target.tagName !== 'input') {
- await me.showItem(this.docName);
- }
- });
- row.style.display = 'flex';
-
- // make element focusable
- row.setAttribute('tabindex', -1);
- this.rows[i] = row;
- }
- return this.rows[i];
- }
-
- refreshRow(doc) {
- let row = this.getRowByName(doc.name);
- if (row) {
- this.renderRow(row, doc);
- }
- }
-
- async showItem(name) {
- if (this.meta.print) {
- await frappejs.router.setRoute('print', this.doctype, name);
- } else {
- await frappejs.router.setRoute('edit', this.doctype, name);
- }
- }
-
- getCheckedRowNames() {
- return [...this.body.querySelectorAll('.checkbox:checked')].map(check => check.getAttribute('data-name'));
- }
-
- clearEmptyRows() {
- if (this.rows.length > this.data.length) {
- for (let i=this.data.length; i < this.rows.length; i++) {
- let row = this.getRow(i);
- row.innerHTML = '';
- row.style.display = 'none';
- }
- }
- }
-
- selectDefaultRow() {
- if (!frappejs.desk.body.activePage && this.rows.length) {
- this.showItem(this.rows[0].docName);
- }
- }
-
makeToolbar() {
this.makeSearch();
@@ -28668,7 +28631,7 @@ var tree$2 = class BaseTree extends list {
});
this.page.body.addEventListener('click', (event) => {
- if(event.target.classList.contains('checkbox')) {
+ if (event.target.classList.contains('checkbox')) {
this.trigger('state-change');
}
});
@@ -28687,7 +28650,7 @@ var tree$2 = class BaseTree extends list {
this.searchInput = this.toolbar.querySelector('input');
this.searchInput.addEventListener('keypress', (event) => {
- if (event.keyCode===13) {
+ if (event.keyCode === 13) {
this.refresh();
}
});
@@ -28697,69 +28660,6 @@ var tree$2 = class BaseTree extends list {
this.refresh();
});
}
-
- bindKeys() {
- // keyboard.bindKey(this.body, 'up', () => this.move('up'));
- // keyboard.bindKey(this.body, 'down', () => this.move('down'))
-
- // keyboard.bindKey(this.body, 'right', () => {
- // if (frappe.desk.body.activePage) {
- // frappe.desk.body.activePage.body.querySelector('input').focus();
- // }
- // });
-
- // keyboard.bindKey(this.body, 'n', (e) => {
- // frappe.router.setRoute('new', this.doctype);
- // e.preventDefault();
- // });
-
- // keyboard.bindKey(this.body, 'x', async (e) => {
- // let activeListRow = this.getActiveListRow();
- // if (activeListRow && activeListRow.docName) {
- // e.preventDefault();
- // await frappe.db.delete(this.doctype, activeListRow.docName);
- // frappe.desk.body.activePage.hide();
- // }
- // });
- }
-
- async move(direction) {
- let elementRef = direction === 'up' ? 'previousSibling' : 'nextSibling';
- if (document.activeElement && document.activeElement.classList.contains('list-row')) {
- let next = document.activeElement[elementRef];
- if (next && next.docName) {
- await this.showItem(next.docName);
- }
- }
- }
-
- setActiveListRow(name) {
- let activeListRow = this.getActiveListRow();
- if (activeListRow) {
- activeListRow.classList.remove('active');
- }
-
- if (!name) {
- // get name from active page
- name = frappejs.desk.activeDoc && frappejs.desk.activeDoc.name;
- }
-
- if (name) {
- let row = this.getRowByName(name);
- if (row) {
- row.classList.add('active');
- row.focus();
- }
- }
- }
-
- getRowByName(name) {
- return this.body.querySelector(`.list-row[data-name="${name}"]`);
- }
-
- getActiveListRow() {
- return this.body.querySelector('.list-row.active');
- }
};
class BaseControl {
@@ -49466,7 +49366,8 @@ var modelTable = class ModelTable {
getControl(field, parent) {
field.onlyInput = true;
- const control = controls$1.makeControl({field: field, parent: parent});
+ const controls = controls$1;
+ const control = controls.makeControl({field: field, parent: parent});
// change will be triggered by datatable
control.skipChangeEvent = true;
@@ -50215,12 +50116,6 @@ var treepage = class TreePage extends page {
parent: this.body,
page: this
});
-
- // frappe.docs.on('change', (params) => {
- // if (params.doc.doctype === this.tree.meta.name) {
- // this.tree.refreshRow(params.doc);
- // }
- // });
}
async show(params) {
@@ -60782,7 +60677,6 @@ var client$2 = {
frappejs.desk.menu.addItem('ToDo', '#list/ToDo');
frappejs.desk.menu.addItem('Chart of Accounts', '#tree/Account');
- frappejs.desk.menu.addItem('Accounts', '#list/Account');
frappejs.desk.menu.addItem('Items', '#list/Item');
frappejs.desk.menu.addItem('Customers', '#list/Customer');
frappejs.desk.menu.addItem('Invoice', '#list/Invoice');