diff --git a/dist/js/bundle.js b/dist/js/bundle.js index cb29c6cc..bc017224 100644 --- a/dist/js/bundle.js +++ b/dist/js/bundle.js @@ -22,15 +22,6 @@ var utils = { return Math.random().toString(36).substr(3); }, - async_handler(fn) { - return (req, res, next) => Promise.resolve(fn(req, res, next)) - .catch((err) => { - console.log(err); - // handle error - res.status(err.status_code || 500).send({error: err.message}); - }); - }, - async sleep(seconds) { return new Promise(resolve => { setTimeout(resolve, seconds * 1000); @@ -343,27 +334,59 @@ var model = { ] }; -var document$1 = class BaseDocument { +var observable = class Observable { + on(event, listener) { + this._addListener('_listeners', event, listener); + } + + once(event, listener) { + this._addListener('_onceListeners', event, listener); + } + + async trigger(event, params) { + await this._triggerEvent('_listeners', event, params); + await this._triggerEvent('_onceListeners', event, params); + + // clear once-listeners + if (this._onceListeners && this._onceListeners[event]) { + delete this._onceListeners[event]; + } + } + + _addListener(name, event, listener) { + if (!this[name]) { + this[name] = {}; + } + if (!this[name][event]) { + this[name][event] = []; + } + this[name][event].push(listener); + } + + async _triggerEvent(name, event, params) { + if (this[name] && this[name][event]) { + for (let listener of this[name][event]) { + await listener(params); + } + } + } + + clearListeners() { + this._listeners = {}; + this._onceListeners = {}; + } +}; + +var document$1 = class BaseDocument extends observable { constructor(data) { - this.handlers = {}; + super(); this.fetchValues = {}; this.setup(); Object.assign(this, data); } setup() { - // add handlers - } - - clearHandlers() { - this.handlers = {}; - } - - addHandler(key, method) { - if (!this.handlers[key]) { - this.handlers[key] = []; - } - this.handlers[key].push(method || key); + // add listeners } get meta() { @@ -455,7 +478,7 @@ var document$1 = class BaseDocument { async validateField(key, value) { let field = this.meta.getField(key); if (field && field.fieldtype == 'Select') { - return this.meta.validate_select(field, value); + return this.meta.validateSelect(field, value); } return value; } @@ -551,7 +574,6 @@ var document$1 = class BaseDocument { this.setChildIdx(); await this.applyFormulae(); await this.trigger('validate'); - await this.trigger('commit'); } async insert() { @@ -580,16 +602,11 @@ var document$1 = class BaseDocument { await this.trigger('after_delete'); } - async trigger(key, params) { - if (this.handlers[key]) { - for (let method of this.handlers[key]) { - if (typeof method === 'string') { - await this[method](params); - } else { - await method(params); - } - } + async trigger(event, params) { + if (this[event]) { + await this[event](params); } + await super.trigger(event, params); } // helper functions @@ -610,7 +627,6 @@ var document$1 = class BaseDocument { var meta = class BaseMeta extends document$1 { constructor(data) { super(data); - this.event_handlers = {}; this.list_options = { fields: ['name', 'modified'] }; @@ -660,13 +676,6 @@ var meta = class BaseMeta extends document$1 { return this._hasFormulae; } - on(key, fn) { - if (!this.event_handlers[key]) { - this.event_handlers[key] = []; - } - this.event_handlers[key].push(fn); - } - async set(fieldname, value) { this[fieldname] = value; await this.trigger(fieldname); @@ -747,7 +756,7 @@ var meta = class BaseMeta extends document$1 { return this._keywordFields; } - validate_select(field, value) { + validateSelect(field, value) { let options = field.options; if (typeof options === 'string') { // values given as string @@ -759,17 +768,13 @@ var meta = class BaseMeta extends document$1 { return value; } - async trigger(key, event = {}) { - Object.assign(event, { + async trigger(event, params = {}) { + Object.assign(params, { doc: this, - name: key + name: event }); - if (this.event_handlers[key]) { - for (var handler of this.event_handlers[key]) { - await handler(event); - } - } + await super.trigger(event, params); } }; @@ -1359,27 +1364,6 @@ var ui = { }; -var observable = class Observable { - constructor() { - this._handlers = {}; - } - - on(event, fn) { - if (!this._handlers[event]) { - this._handlers[event] = []; - } - this._handlers[event].push(fn); - } - - async trigger(event, params) { - if (this._handlers[event]) { - for (let handler of this._handlers[event]) { - await handler(params); - } - } - } -}; - var router = class Router extends observable { constructor() { super(); @@ -1538,9 +1522,9 @@ var page = class Page extends observable { this.trigger('hide'); } - addButton(label, cssClass, action) { + addButton(label, className, action) { this.head.classList.remove('hide'); - this.button = frappejs.ui.add('button', 'btn ' + cssClass, this.head); + this.button = frappejs.ui.add('button', 'btn ' + this.getClassName(className), this.head); this.button.innerHTML = label; this.button.addEventListener('click', action); return this.button; @@ -1571,6 +1555,15 @@ var page = class Page extends observable { this.page_error.classList.remove('hide'); this.page_error.innerHTML = `
${message ? message : ""}
`; } + + getClassName(className) { + const newName = { + 'primary': 'btn-primary', + 'secondary': 'btn-outline-secondary' + }[className]; + + return newName || className; + } }; var list = class BaseList { @@ -1875,13 +1868,18 @@ class BaseControl { async handleChange(event) { let value = await this.parse(this.getInputValue()); value = await this.validate(value); + await this.updateDocValue(value); + } + + async updateDocValue(value) { if (this.doc[this.fieldname] !== value) { - if (this.doc.set) { - await this.doc.set(this.fieldname, value); - } - if (this.parent_control) { + if (this.parentControl) { + // its a child this.doc[this.fieldname] = value; - await this.parent_control.doc.set(this.fieldname, this.parent_control.getInputValue()); + await this.parentControl.doc.set(this.fieldname, this.parentControl.getInputValue()); + } else { + // parent + await this.doc.set(this.fieldname, value); } } } @@ -2466,12 +2464,35 @@ class LinkControl extends base { this.awesomplete = new awesomplete(this.input, { autoFirst: true, minChars: 0, - maxItems: 99 + maxItems: 99, + filter: () => true, }); // rebuild the list on input this.input.addEventListener('input', async (event) => { - this.awesomplete.list = await this.getList(this.input.value); + let list = await this.getList(this.input.value); + + // action to add new item + list.push({ + label:frappejs._('+ New {0}', this.target), + value: '__newItem', + action: () => { + } + }); + + this.awesomplete.list = list; + }); + + // new item action + this.input.addEventListener('awesomplete-select', async (e) => { + if (e.text && e.text.value === '__newItem') { + e.preventDefault(); + const newDoc = await frappejs.getNewDoc(this.target); + const formModal = frappejs.desk.showFormModal(this.target, newDoc.name); + formModal.form.once('submit', async () => { + await this.updateDocValue(formModal.form.doc.name); + }); + } }); } @@ -4399,7 +4420,7 @@ var clusterize = createCommonjsModule(function (module) { var frappeDatatable = createCommonjsModule(function (module, exports) { (function webpackUniversalModuleDefinition(root, factory) { module.exports = factory(Sortable, clusterize); -})(typeof self !== 'undefined' ? self : commonjsGlobal, function(__WEBPACK_EXTERNAL_MODULE_9__, __WEBPACK_EXTERNAL_MODULE_11__) { +})(typeof self !== 'undefined' ? self : commonjsGlobal, function(__WEBPACK_EXTERNAL_MODULE_8__, __WEBPACK_EXTERNAL_MODULE_11__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -4462,7 +4483,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 6); +/******/ return __webpack_require__(__webpack_require__.s = 4); /******/ }) /************************************************************************/ /******/ ([ @@ -4924,997 +4945,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -exports.getRowHTML = getRowHTML; - -var _dom = __webpack_require__(0); - -var _dom2 = _interopRequireDefault(_dom); - -var _utils = __webpack_require__(1); - -var _cellmanager = __webpack_require__(3); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var RowManager = function () { - function RowManager(instance) { - _classCallCheck(this, RowManager); - - this.instance = instance; - this.options = this.instance.options; - this.wrapper = this.instance.wrapper; - this.bodyScrollable = this.instance.bodyScrollable; - - this.bindEvents(); - this.refreshRows = (0, _utils.promisify)(this.refreshRows, this); - } - - _createClass(RowManager, [{ - key: 'bindEvents', - value: function bindEvents() { - this.bindCheckbox(); - } - }, { - key: 'bindCheckbox', - value: function bindCheckbox() { - var _this = this; - - if (!this.options.addCheckboxColumn) return; - - // map of checked rows - this.checkMap = []; - - _dom2.default.on(this.wrapper, 'click', '.data-table-col[data-col-index="0"] [type="checkbox"]', function (e, $checkbox) { - var $cell = $checkbox.closest('.data-table-col'); - - var _$$data = _dom2.default.data($cell), - rowIndex = _$$data.rowIndex, - isHeader = _$$data.isHeader; - - var checked = $checkbox.checked; - - if (isHeader) { - _this.checkAll(checked); - } else { - _this.checkRow(rowIndex, checked); - } - }); - } - }, { - key: 'refreshRows', - value: function refreshRows() { - this.instance.renderBody(); - this.instance.setDimensions(); - } - }, { - key: 'refreshRow', - value: function refreshRow(row, rowIndex) { - var _this2 = this; - - var _row = this.datamanager.updateRow(row, rowIndex); - - _row.forEach(function (cell) { - _this2.cellmanager.refreshCell(cell); - }); - } - }, { - key: 'getCheckedRows', - value: function getCheckedRows() { - if (!this.checkMap) { - return []; - } - - return this.checkMap.map(function (c, rowIndex) { - if (c) { - return rowIndex; - } - return null; - }).filter(function (c) { - return c !== null || c !== undefined; - }); - } - }, { - key: 'highlightCheckedRows', - value: function highlightCheckedRows() { - var _this3 = this; - - this.getCheckedRows().map(function (rowIndex) { - return _this3.checkRow(rowIndex, true); - }); - } - }, { - key: 'checkRow', - value: function checkRow(rowIndex, toggle) { - var value = toggle ? 1 : 0; - - // update internal map - this.checkMap[rowIndex] = value; - // set checkbox value explicitly - _dom2.default.each('.data-table-col[data-row-index="' + rowIndex + '"][data-col-index="0"] [type="checkbox"]', this.bodyScrollable).map(function (input) { - input.checked = toggle; - }); - // highlight row - this.highlightRow(rowIndex, toggle); - } - }, { - key: 'checkAll', - value: function checkAll(toggle) { - var value = toggle ? 1 : 0; - - // update internal map - if (toggle) { - this.checkMap = Array.from(Array(this.getTotalRows())).map(function (c) { - return value; - }); - } else { - this.checkMap = []; - } - // set checkbox value - _dom2.default.each('.data-table-col[data-col-index="0"] [type="checkbox"]', this.bodyScrollable).map(function (input) { - input.checked = toggle; - }); - // highlight all - this.highlightAll(toggle); - } - }, { - key: 'highlightRow', - value: function highlightRow(rowIndex) { - var toggle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - - var $row = this.getRow$(rowIndex); - if (!$row) return; - - if (!toggle && this.bodyScrollable.classList.contains('row-highlight-all')) { - $row.classList.add('row-unhighlight'); - return; - } - - if (toggle && $row.classList.contains('row-unhighlight')) { - $row.classList.remove('row-unhighlight'); - } - - this._highlightedRows = this._highlightedRows || {}; - - if (toggle) { - $row.classList.add('row-highlight'); - this._highlightedRows[rowIndex] = $row; - } else { - $row.classList.remove('row-highlight'); - delete this._highlightedRows[rowIndex]; - } - } - }, { - key: 'highlightAll', - value: function highlightAll() { - var toggle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - - if (toggle) { - this.bodyScrollable.classList.add('row-highlight-all'); - } else { - this.bodyScrollable.classList.remove('row-highlight-all'); - for (var rowIndex in this._highlightedRows) { - var $row = this._highlightedRows[rowIndex]; - $row.classList.remove('row-highlight'); - } - this._highlightedRows = {}; - } - } - }, { - key: 'getRow$', - value: function getRow$(rowIndex) { - return (0, _dom2.default)('.data-table-row[data-row-index="' + rowIndex + '"]', this.bodyScrollable); - } - }, { - key: 'getTotalRows', - value: function getTotalRows() { - return this.datamanager.getRowCount(); - } - }, { - key: 'getFirstRowIndex', - value: function getFirstRowIndex() { - return 0; - } - }, { - key: 'getLastRowIndex', - value: function getLastRowIndex() { - return this.datamanager.getRowCount() - 1; - } - }, { - key: 'scrollToRow', - value: function scrollToRow(rowIndex) { - rowIndex = +rowIndex; - this._lastScrollTo = this._lastScrollTo || 0; - var $row = this.getRow$(rowIndex); - if (_dom2.default.inViewport($row, this.bodyScrollable)) return; - - var _$row$getBoundingClie = $row.getBoundingClientRect(), - height = _$row$getBoundingClie.height; - - var _bodyScrollable$getBo = this.bodyScrollable.getBoundingClientRect(), - top = _bodyScrollable$getBo.top, - bottom = _bodyScrollable$getBo.bottom; - - var rowsInView = Math.floor((bottom - top) / height); - - var offset = 0; - if (rowIndex > this._lastScrollTo) { - offset = height * (rowIndex + 1 - rowsInView); - } else { - offset = height * (rowIndex + 1 - 1); - } - - this._lastScrollTo = rowIndex; - _dom2.default.scrollTop(this.bodyScrollable, offset); - } - }, { - key: 'datamanager', - get: function get() { - return this.instance.datamanager; - } - }, { - key: 'cellmanager', - get: function get() { - return this.instance.cellmanager; - } - }]); - - return RowManager; -}(); - -exports.default = RowManager; -function getRowHTML(row, props) { - var dataAttr = (0, _utils.makeDataAttributeString)(props); - - return '\n