From c4a04d3dcab37fddfc9e6655c2fedc2e5942a6c5 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Sun, 13 Jun 2021 11:48:40 +0300 Subject: [PATCH] cs fix --- client/src/action-handler.js | 2 +- client/src/ajax.js | 4 +- client/src/number.js | 70 +++++--- client/src/page-title.js | 14 +- client/src/pre-loader.js | 83 +++++---- client/src/router.js | 255 +++++++++++++++++++--------- client/src/search-manager.js | 196 ++++++++++++++------- client/src/session-storage.js | 23 ++- client/src/storage.js | 58 ++++--- client/src/theme-manager.js | 41 +++-- client/src/ui.js | 281 +++++++++++++++++++------------ client/src/utils.js | 8 +- client/src/view-helper.js | 11 +- client/src/view-record-helper.js | 17 +- client/src/view.js | 41 +++-- client/src/web-socket-manager.js | 56 +++--- 16 files changed, 751 insertions(+), 409 deletions(-) diff --git a/client/src/action-handler.js b/client/src/action-handler.js index fc4183b779..3129b28ea6 100644 --- a/client/src/action-handler.js +++ b/client/src/action-handler.js @@ -28,7 +28,7 @@ define('action-handler', [], function () { - var ActionHandler = function (view) { + let ActionHandler = function (view) { this.view = view; }; diff --git a/client/src/ajax.js b/client/src/ajax.js index 7d68c6085b..ad63a55449 100644 --- a/client/src/ajax.js +++ b/client/src/ajax.js @@ -28,10 +28,10 @@ define('ajax', [], function () { - var Ajax = Espo.Ajax = { + let Ajax = Espo.Ajax = { request: function (url, type, data, options) { - var options = options || {}; + options = options || {}; options.type = type; options.url = url; diff --git a/client/src/number.js b/client/src/number.js index 57edc6eeda..7785eb6120 100644 --- a/client/src/number.js +++ b/client/src/number.js @@ -28,22 +28,23 @@ define('number', [], function () { - var NumberUtil = function (config, preferences) { + let NumberUtil = function (config, preferences) { this.config = config; + this.preferences = preferences; this.thousandSeparator = null; this.decimalMark = null; - this.config.on('change', function () { + this.config.on('change', () => { this.thousandSeparator = null; this.decimalMark = null; - }, this); + }); - this.preferences.on('change', function () { + this.preferences.on('change', () => { this.thousandSeparator = null; this.decimalMark = null; - }, this); + }); this.maxDecimalPlaces = 10; }; @@ -51,22 +52,32 @@ define('number', [], function () { _.extend(NumberUtil.prototype, { formatInt: function (value) { - if (value === null || value === undefined) return ''; + if (value === null || value === undefined) { + return ''; + } + + let stringValue = value.toString(); - var stringValue = value.toString(); stringValue = stringValue.replace(/\B(?=(\d{3})+(?!\d))/g, this.getThousandSeparator()); + return stringValue; }, formatFloat: function (value, decimalPlaces) { - if (value === null || value === undefined) return ''; + if (value === null || value === undefined) { + return ''; + } if (decimalPlaces === 0) { value = Math.round(value); - } else if (decimalPlaces) { + } + else if (decimalPlaces) { value = Math.round(value * Math.pow(10, decimalPlaces)) / (Math.pow(10, decimalPlaces)); - } else { - value = Math.round(value * Math.pow(10, this.maxDecimalPlaces)) / (Math.pow(10, this.maxDecimalPlaces)); + } + else { + value = Math.round( + value * Math.pow(10, this.maxDecimalPlaces)) / (Math.pow(10, this.maxDecimalPlaces) + ); } var parts = value.toString().split("."); @@ -74,17 +85,22 @@ define('number', [], function () { if (decimalPlaces === 0) { return parts[0]; - } else if (decimalPlaces) { - var decimalPartLength = 0; + } + + if (decimalPlaces) { + let decimalPartLength = 0; + if (parts.length > 1) { decimalPartLength = parts[1].length; - } else { + } + else { parts[1] = ''; } if (decimalPlaces && decimalPartLength < decimalPlaces) { - var limit = decimalPlaces - decimalPartLength; - for (var i = 0; i < limit; i++) { + let limit = decimalPlaces - decimalPartLength; + + for (let i = 0; i < limit; i++) { parts[1] += '0'; } } @@ -95,32 +111,42 @@ define('number', [], function () { }, getThousandSeparator: function () { - if (this.thousandSeparator !== null) return this.thousandSeparator; + if (this.thousandSeparator !== null) { + return this.thousandSeparator; + } + + let thousandSeparator = '.'; - var thousandSeparator = '.'; if (this.preferences.has('thousandSeparator')) { thousandSeparator = this.preferences.get('thousandSeparator'); - } else { + } + else { if (this.config.has('thousandSeparator')) { thousandSeparator = this.config.get('thousandSeparator'); } } + this.thousandSeparator = thousandSeparator; return thousandSeparator; }, getDecimalMark: function () { - if (this.decimalMark !== null) return this.decimalMark; + if (this.decimalMark !== null) { + return this.decimalMark; + } + + let decimalMark = '.'; - var decimalMark = '.'; if (this.preferences.has('decimalMark')) { decimalMark = this.preferences.get('decimalMark'); - } else { + } + else { if (this.config.has('decimalMark')) { decimalMark = this.config.get('decimalMark'); } } + this.decimalMark = decimalMark; return decimalMark; diff --git a/client/src/page-title.js b/client/src/page-title.js index fcef06b802..0b1be94a4a 100644 --- a/client/src/page-title.js +++ b/client/src/page-title.js @@ -28,7 +28,7 @@ define('page-title', [], function () { - var PageTitle = function (config) { + let PageTitle = function (config) { this.displayNotificationNumber = config.get('newNotificationCountInTitle') || false; this.title = $('head title').text() || ''; @@ -39,26 +39,32 @@ define('page-title', [], function () { _.extend(PageTitle.prototype, { setTitle: function (title) { this.title = title; + this.update(); }, setNotificationNumber: function (notificationNumber) { this.notificationNumber = notificationNumber; + if (this.displayNotificationNumber) { this.update(); } }, update: function () { - var value = ''; + let value = ''; + if (this.displayNotificationNumber && this.notificationNumber) { value = '(' + this.notificationNumber.toString() + ')'; - if (this.title) value += ' '; + + if (this.title) { + value += ' '; + } } value += this.title; - $('head title').text(value) + $('head title').text(value); }, }); diff --git a/client/src/pre-loader.js b/client/src/pre-loader.js index 5b64a20c8b..0b6b783115 100644 --- a/client/src/pre-loader.js +++ b/client/src/pre-loader.js @@ -28,11 +28,11 @@ define('pre-loader', [], function () { - var PreLoader = function (cache, viewFactory, basePath) { + let PreLoader = function (cache, viewFactory, basePath) { this.cache = cache; this.viewFactory = viewFactory; this.basePath = basePath || ''; - } + }; _.extend(PreLoader.prototype, { @@ -43,77 +43,89 @@ define('pre-loader', [], function () { viewFactory: null, load: function (callback, app) { + let bar = $( + '
' + + '
' + ).prependTo('body'); - var bar = $('
').prependTo('body');; bar = bar.children(); + bar.css({ 'transition': 'width .1s linear', '-webkit-transition': 'width .1s linear' }); - var self = this; + let count = 0; + let countLoaded = 0; + let classesLoaded = 0; + let layoutTypesLoaded = 0; + let templatesLoaded = 0; - var count = 0; - var countLoaded = 0; - var classesLoaded = 0; - var templatesLoaded = 0; - var layoutTypesLoaded = 0; + let updateBar = () => { + let percents = countLoaded / count * 100; - var updateBar = function () { - var percents = countLoaded / count * 100; bar.css('width', percents + '%').attr('aria-valuenow', percents); - } + }; - var checkIfReady = function () { + let checkIfReady = () => { if (countLoaded >= count) { clearInterval(timer); callback.call(app, app); } }; - var timer = setInterval(checkIfReady, 100); - var load = function (data) { + let timer = setInterval(checkIfReady, 100); + + let load = (data) => { data.classes = data.classes || []; data.templates = data.templates || []; data.layoutTypes = data.layoutTypes || []; - var d = []; - data.classes.forEach(function (item) { - if (item != 'views/fields/enum') { - d.push(item); // TODO remove this huck + let d = []; + + data.classes.forEach(item => { + if (item !== 'views/fields/enum') { + d.push(item); // TODO remove this hack } - }, this); + }); + data.classes = d; count = data.templates.length + data.layoutTypes.length+ data.classes.length; - var loadTemplates = function () { - data.templates.forEach(function (name) { - self.viewFactory._loader.load('template', name, function () { - layoutTypesLoaded++; + let loadTemplates = () => { + data.templates.forEach(name => { + this.viewFactory._loader.load('template', name, () => { + templatesLoaded++; countLoaded++; + updateBar(); }); }); - } - var loadLayoutTypes = function () { - data.layoutTypes.forEach(function (name) { - self.viewFactory._loader.load('layoutTemplate', name, function () { + }; + + let loadLayoutTypes = () => { + data.layoutTypes.forEach(name => { + this.viewFactory._loader.load('layoutTemplate', name, () => { layoutTypesLoaded++; countLoaded++; + updateBar(); }); }); - } - var loadClasses = function () { - data.classes.forEach(function (name) { - Espo.loader.require(name, function () { + }; + + let loadClasses = () => { + data.classes.forEach(name => { + Espo.loader.require(name, () => { classesLoaded++; countLoaded++; + updateBar(); }); }); - } + }; loadTemplates(); loadLayoutTypes(); @@ -124,13 +136,10 @@ define('pre-loader', [], function () { url: this.basePath + this.configUrl, dataType: 'json', local: true, - success: function (data) { - load(data); - } + success: data => load(data), }); } }); return PreLoader; - }); diff --git a/client/src/router.js b/client/src/router.js index 34e98873ee..1141056968 100644 --- a/client/src/router.js +++ b/client/src/router.js @@ -28,7 +28,7 @@ define('router', [], function () { - var Router = Backbone.Router.extend({ + let Router = Backbone.Router.extend({ routeList: [ { @@ -74,7 +74,7 @@ define('router', [], function () { route: "*actions", resolution: "home", order: 500 - } + }, ], _bindRoutes: function() {}, @@ -83,30 +83,34 @@ define('router', [], function () { this.routeParams = {}; if (this.options.routes) { - var routeList = []; - Object.keys(this.options.routes).forEach(function (route) { - var item = this.options.routes[route]; + let routeList = []; + + Object.keys(this.options.routes).forEach(route => { + let item = this.options.routes[route]; + routeList.push({ route: route, resolution: item.resolution || 'defaultRoute', order: item.order || 0 }); + this.routeParams[route] = item.params || {}; - }, this); + }); this.routeList = Espo.Utils.clone(this.routeList); - routeList.forEach(function (item) { + routeList.forEach(item => { this.routeList.push(item); - }, this); + }); - this.routeList = this.routeList.sort(function (v1, v2) { + this.routeList = this.routeList.sort((v1, v2) => { return (v1.order || 0) - (v2.order || 0); }); } - this.routeList.reverse().forEach(function (item) { + + this.routeList.reverse().forEach(item => { this.route(item.route, item.resolution); - }, this); + }); }, _last: null, @@ -127,51 +131,63 @@ define('router', [], function () { this.history = []; - var detectBackOrForward = function(onBack, onForward) { + let detectBackOrForward = (onBack, onForward) => { hashHistory = [window.location.hash]; historyLength = window.history.length; return function () { - var hash = window.location.hash, length = window.history.length; - if (hashHistory.length && historyLength == length) { - if (hashHistory[hashHistory.length - 2] == hash) { + let hash = window.location.hash, length = window.history.length; + + if (hashHistory.length && historyLength === length) { + if (hashHistory[hashHistory.length - 2] === hash) { + hashHistory = hashHistory.slice(0, -1); + if (onBack) { onBack(); } - } else { + } + else { hashHistory.push(hash); + if (onForward) { onForward(); } } - } else { + } + else { hashHistory.push(hash); historyLength = length; } - } + }; }; - window.addEventListener('hashchange', detectBackOrForward(function () { - this.backProcessed = true; - setTimeout(function () { - this.backProcessed = false; - }.bind(this), 50); - }.bind(this))); + window.addEventListener( + 'hashchange', + detectBackOrForward(() => { + this.backProcessed = true; - this.on('route', function (name, args) { + setTimeout(() => { + this.backProcessed = false; + }, 50); + }) + ); + + this.on('route', () => { this.history.push(Backbone.history.fragment); }); - window.addEventListener('beforeunload', function (e) { + window.addEventListener('beforeunload', (e) => { e = e || window.event; if (this.confirmLeaveOut) { e.preventDefault(); + e.returnValue = this.confirmLeaveOutMessage; + return this.confirmLeaveOutMessage; } - }.bind(this)); + }); }, getCurrentUrl: function () { @@ -181,66 +197,93 @@ define('router', [], function () { checkConfirmLeaveOut: function (callback, context, navigateBack) { if (this.confirmLeaveOutDisplayed) { this.navigateBack({trigger: false}); + this.confirmLeaveOutCanceled = true; + return; } + context = context || this; + if (this.confirmLeaveOut) { this.confirmLeaveOutDisplayed = true; this.confirmLeaveOutCanceled = false; - Espo.Ui.confirm(this.confirmLeaveOutMessage, { - confirmText: this.confirmLeaveOutConfirmText, - cancelText: this.confirmLeaveOutCancelText, - backdrop: true, - cancelCallback: function () { - this.confirmLeaveOutDisplayed = false; - if (navigateBack) { - this.navigateBack({trigger: false}); - } - }.bind(this) - }, function () { - this.confirmLeaveOutDisplayed = false; - this.confirmLeaveOut = false; - if (!this.confirmLeaveOutCanceled) { - callback.call(context); + Espo.Ui.confirm( + this.confirmLeaveOutMessage, + { + confirmText: this.confirmLeaveOutConfirmText, + cancelText: this.confirmLeaveOutCancelText, + backdrop: true, + cancelCallback: () => { + this.confirmLeaveOutDisplayed = false; + + if (navigateBack) { + this.navigateBack({trigger: false}); + } + }, + }, + () => { + this.confirmLeaveOutDisplayed = false; + this.confirmLeaveOut = false; + + if (!this.confirmLeaveOutCanceled) { + callback.call(context); + } } - }.bind(this)); - } else { + ); + } + else { callback.call(context); } }, route: function (route, name, callback) { - var routeOriginal = route; + let routeOriginal = route; + + if (!_.isRegExp(route)) { + route = this._routeToRegExp(route); + } - if (!_.isRegExp(route)) route = this._routeToRegExp(route); if (_.isFunction(name)) { callback = name; name = ''; } - if (!callback) callback = this[name]; - var router = this; - Backbone.history.route(route, function (fragment) { - var args = router._extractParameters(route, fragment); - var options = {}; + if (!callback) { + callback = this[name]; + } + + let router = this; + + Backbone.history.route(route, function (fragment) { + let args = router._extractParameters(route, fragment); + + let options = {}; + if (name === 'defaultRoute') { - var keyList = []; - routeOriginal.split('/').forEach(function (key) { - if (key && key.indexOf(':') === 0) keyList.push(key.substr(1)); + let keyList = []; + + routeOriginal.split('/').forEach(key => { + if (key && key.indexOf(':') === 0) { + keyList.push(key.substr(1)); + } }); - keyList.forEach(function (key, i) { + + keyList.forEach((key, i) => { options[key] = args[i]; }); } if (router.execute(callback, args, name, routeOriginal, options) !== false) { router.trigger.apply(router, ['route:' + name].concat(args)); + router.trigger('route', name, args); + Backbone.history.trigger('route', router, name, args); } }); + return this; }, @@ -248,24 +291,30 @@ define('router', [], function () { this.checkConfirmLeaveOut(function () { if (name === 'defaultRoute') { this.defaultRoute(this.routeParams[routeOriginal], options); + return; } + Backbone.Router.prototype.execute.call(this, callback, args, name); }, null, true); }, navigate: function (fragment, options) { this.history.push(fragment); + return Backbone.Router.prototype.navigate.call(this, fragment, options); }, navigateBack: function (options) { - var url; + let url; + if (this.history.length > 1) { url = this.history[this.history.length - 2]; - } else { + } + else { url = this.history[0]; } + this.navigate(url, options); }, @@ -278,29 +327,35 @@ define('router', [], function () { return string; } - var options = {}; + let options = {}; + if (typeof string !== 'undefined') { - string.split('&').forEach(function (item, i) { - var p = item.split('='); + string.split('&').forEach((item, i) => { + let p = item.split('='); + options[p[0]] = true; + if (p.length > 1) { options[p[0]] = p[1]; } }); } + return options; }, defaultRoute: function (params, options) { - var controller = params.controller || options.controller; - var action = params.action || options.action; + let controller = params.controller || options.controller; + let action = params.action || options.action; this.dispatch(controller, action, options); }, record: function (controller, action, id, options) { - var options = this._parseOptionsParams(options); + options = this._parseOptionsParams(options); + options.id = id; + this.dispatch(controller, action, options); }, @@ -330,6 +385,7 @@ define('router', [], function () { logout: function () { this.dispatch(null, 'logout'); + this.navigate('', {trigger: false}); }, @@ -338,18 +394,20 @@ define('router', [], function () { }, dispatch: function (controller, action, options) { - var o = { + let o = { controller: controller, action: action, options: options - } + }; + this._last = o; + this.trigger('routed', o); }, getLast: function () { return this._last; - } + }, }); return Router; @@ -357,15 +415,17 @@ define('router', [], function () { }); function isIOS9UIWebView() { - var userAgent = window.navigator.userAgent; + let userAgent = window.navigator.userAgent; + return /(iPhone|iPad|iPod).* OS 9_\d/.test(userAgent) && !/Version\/9\./.test(userAgent); } -//override the backbone.history.loadUrl() and backbone.history.navigate() -//to fix the navigation issue (location.hash not change immediately) on iOS9 +// Override `backbone.history.loadUrl()` and `backbone.history.navigate()` +// to fix the navigation issue (`location.hash` not changed immediately) on iOS9. if (isIOS9UIWebView()) { Backbone.history.loadUrl = function (fragment, oldHash) { fragment = this.fragment = this.getFragment(fragment); + return _.any(this.handlers, function (handler) { if (handler.route.test(fragment)) { function runCallback() { @@ -375,44 +435,71 @@ if (isIOS9UIWebView()) { function wait() { if (oldHash === location.hash) { window.setTimeout(wait, 50); - } else { + } + else { runCallback(); } } + wait(); + return true; } }); }; Backbone.history.navigate = function (fragment, options) { - var pathStripper = /#.*$/; - if (!Backbone.History.started) return false; - if (!options || options === true) options = { trigger: !!options }; + let pathStripper = /#.*$/; - var url = this.root + '#' + (fragment = this.getFragment(fragment || '')); + if (!Backbone.History.started) { + return false; + } + + if (!options || options === true) { + options = { + trigger: !!options + }; + } + + let url = this.root + '#' + (fragment = this.getFragment(fragment || '')); fragment = fragment.replace(pathStripper, ''); - if (this.fragment === fragment) return; + if (this.fragment === fragment) { + return; + } + this.fragment = fragment; - if (fragment === '' && url !== '/') url = url.slice(0, -1); - var oldHash = location.hash; + if (fragment === '' && url !== '/') { + url = url.slice(0, -1); + } + + let oldHash = location.hash; if (this._hasPushState) { this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url); - - } else if (this._wantsHashChange) { + } + else if (this._wantsHashChange) { this._updateHash(this.location, fragment, options.replace); - if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) { - if (!options.replace) this.iframe.document.open().close(); + + if ( + this.iframe && + (fragment !== this.getFragment(this.getHash(this.iframe))) + ) { + if (!options.replace) { + this.iframe.document.open().close(); + } + this._updateHash(this.iframe.location, fragment, options.replace); } - } else { + } + else { return this.location.assign(url); } - if (options.trigger) return this.loadUrl(fragment, oldHash); - } + if (options.trigger) { + return this.loadUrl(fragment, oldHash); + } + }; } diff --git a/client/src/search-manager.js b/client/src/search-manager.js index bf5ed4510c..aedcd912bf 100644 --- a/client/src/search-manager.js +++ b/client/src/search-manager.js @@ -28,7 +28,7 @@ define('search-manager', [], function () { - var SearchManager = function (collection, type, storage, dateTime, defaultData, emptyOnReset) { + let SearchManager = function (collection, type, storage, dateTime, defaultData, emptyOnReset) { this.collection = collection; this.scope = collection.name; this.storage = storage; @@ -45,7 +45,8 @@ define('search-manager', [], function () { if (defaultData) { this.defaultData = defaultData; - for (var p in this.emptyData) { + + for (let p in this.emptyData) { if (!(p in defaultData)) { defaultData[p] = Espo.Utils.clone(this.emptyData[p]); } @@ -65,18 +66,20 @@ define('search-manager', [], function () { if (!('advanced' in this.data)) { this.data.advanced = {}; } + if (!('bool' in this.data)) { this.data.bool = {}; } + if (!('textFilter' in this.data)) { this.data.textFilter = ''; } }, getWhere: function () { - var where = []; + let where = []; - if (this.data.textFilter && this.data.textFilter != '') { + if (this.data.textFilter && this.data.textFilter !== '') { where.push({ type: 'textFilter', value: this.data.textFilter @@ -84,37 +87,43 @@ define('search-manager', [], function () { } if (this.data.bool) { - var o = { + let o = { type: 'bool', value: [], }; - for (var name in this.data.bool) { + + for (let name in this.data.bool) { if (this.data.bool[name]) { o.value.push(name); } } + if (o.value.length) { where.push(o); } } if (this.data.primary) { - var o = { + let o = { type: 'primary', value: this.data.primary, }; + if (o.value.length) { where.push(o); } } if (this.data.advanced) { - for (var name in this.data.advanced) { - var defs = this.data.advanced[name]; + for (let name in this.data.advanced) { + let defs = this.data.advanced[name]; + if (!defs) { continue; } - var part = this.getWherePart(name, defs); + + let part = this.getWherePart(name, defs); + where.push(part); } } @@ -127,48 +136,60 @@ define('search-manager', [], function () { if ('where' in defs) { return defs.where; - } else { - var type = defs.type; - - if (type == 'or' || type == 'and') { - var a = []; - var value = defs.value || {}; - for (var n in value) { - a.push(this.getWherePart(n, value[n])); - } - return { - type: type, - value: a - }; - } - if ('field' in defs) { // for backward compatibility - attribute = defs.field; - } - if ('attribute' in defs) { - attribute = defs.attribute; - } - if (defs.dateTime) { - return { - type: type, - attribute: attribute, - value: defs.value, - dateTime: true, - timeZone: this.dateTime.timeZone || 'UTC' - }; - } else { - value = defs.value; - return { - type: type, - attribute: attribute, - value: value - }; - } } + + let type = defs.type; + + if (type === 'or' || type === 'and') { + let a = []; + + var value = defs.value || {}; + + for (let n in value) { + a.push(this.getWherePart(n, value[n])); + } + + return { + type: type, + value: a + }; + } + + if ('field' in defs) { // for backward compatibility + attribute = defs.field; + } + + if ('attribute' in defs) { + attribute = defs.attribute; + } + + if (defs.dateTime) { + return { + type: type, + attribute: attribute, + value: defs.value, + dateTime: true, + timeZone: this.dateTime.timeZone || 'UTC', + }; + } + + value = defs.value; + + return { + type: type, + attribute: attribute, + value: value + }; }, loadStored: function () { - this.data = this.storage.get(this.type + 'Search', this.scope) || Espo.Utils.clone(this.defaultData) || Espo.Utils.clone(this.emptyData); + this.data = + this.storage.get(this.type + 'Search', this.scope) || + Espo.Utils.clone(this.defaultData) || + Espo.Utils.clone(this.emptyData); + this.sanitizeData(); + return this; }, @@ -178,21 +199,25 @@ define('search-manager', [], function () { setAdvanced: function (advanced) { this.data = Espo.Utils.clone(this.data); + this.data.advanced = advanced; }, setBool: function (bool) { this.data = Espo.Utils.clone(this.data); + this.data.bool = bool; }, setPrimary: function (primary) { this.data = Espo.Utils.clone(this.data); + this.data.primary = primary; }, set: function (data) { this.data = data; + if (this.storage) { this.storage.set(this.type + 'Search', this.scope, data); } @@ -200,6 +225,7 @@ define('search-manager', [], function () { empty: function () { this.data = Espo.Utils.clone(this.emptyData); + if (this.storage) { this.storage.clear(this.type + 'Search', this.scope); } @@ -208,9 +234,12 @@ define('search-manager', [], function () { reset: function () { if (this.emptyOnReset) { this.empty(); + return; } + this.data = Espo.Utils.clone(this.defaultData) || Espo.Utils.clone(this.emptyData); + if (this.storage) { this.storage.clear(this.type + 'Search', this.scope); } @@ -220,52 +249,105 @@ define('search-manager', [], function () { var where = { field: field }; + if (!value && ~['on', 'before', 'after'].indexOf(type)) { return null; } + let start, from, to; + switch (type) { case 'today': where.type = 'between'; - var start = this.dateTime.getNowMoment().startOf('day').utc(); - var from = start.format(this.dateTime.internalDateTimeFormat); - var to = start.add(1, 'days').format(this.dateTime.internalDateTimeFormat); + start = this.dateTime.getNowMoment().startOf('day').utc(); + + from = start.format(this.dateTime.internalDateTimeFormat); + to = start.add(1, 'days').format(this.dateTime.internalDateTimeFormat); + where.value = [from, to]; + break; + case 'past': where.type = 'before'; + where.value = this.dateTime.getNowMoment().utc().format(this.dateTime.internalDateTimeFormat); + break; + case 'future': where.type = 'after'; + where.value = this.dateTime.getNowMoment().utc().format(this.dateTime.internalDateTimeFormat); + break; + case 'on': where.type = 'between'; - var start = moment(value, this.dateTime.internalDateFormat, this.timeZone).utc(); - var from = start.format(this.dateTime.internalDateTimeFormat); - var to = start.add(1, 'days').format(this.dateTime.internalDateTimeFormat); + start = moment(value, this.dateTime.internalDateFormat, this.timeZone).utc(); + + from = start.format(this.dateTime.internalDateTimeFormat); + to = start.add(1, 'days').format(this.dateTime.internalDateTimeFormat); where.value = [from, to]; + break; + case 'before': where.type = 'before'; - where.value = moment(value, this.dateTime.internalDateFormat, this.timeZone).utc().format(this.dateTime.internalDateTimeFormat); + where.value = + moment( + value, + this.dateTime.internalDateFormat, + this.timeZone + ) + .utc() + .format(this.dateTime.internalDateTimeFormat ); + break; + case 'after': where.type = 'after'; - where.value = moment(value, this.dateTime.internalDateFormat, this.timeZone).utc().format(this.dateTime.internalDateTimeFormat); + where.value = + moment( + value, + this.dateTime.internalDateFormat, + this.timeZone + ) + .utc() + .format(this.dateTime.internalDateTimeFormat); + break; + case 'between': where.type = 'between'; + if (value[0] && value[1]) { - var from = moment(value[0], this.dateTime.internalDateFormat, this.timeZone).utc().format(this.dateTime.internalDateTimeFormat); - var to = moment(value[1], this.dateTime.internalDateFormat, this.timeZone).utc().format(this.dateTime.internalDateTimeFormat); + let from = + moment( + value[0], + this.dateTime.internalDateFormat, + this.timeZone + ) + .utc() + .format(this.dateTime.internalDateTimeFormat); + + let to = + moment( + value[1], + this.dateTime.internalDateFormat, + this.timeZone + ) + .utc() + .format(this.dateTime.internalDateTimeFormat); + where.value = [from, to]; } + break; + default: where.type = type; } diff --git a/client/src/session-storage.js b/client/src/session-storage.js index 3d2bddf1cb..91b8e9f1c7 100644 --- a/client/src/session-storage.js +++ b/client/src/session-storage.js @@ -35,23 +35,30 @@ define('session-storage', ['storage'], function (Dep) { get: function (name) { try { var stored = this.storageObject.getItem(name); - } catch (error) { + } + catch (error) { console.error(error); + return null; } if (stored) { - var result = stored; + let result = stored; + if (stored.length > 9 && stored.substr(0, 9) === '__JSON__:') { - var jsonString = stored.substr(9); + let jsonString = stored.substr(9); + try { result = JSON.parse(jsonString); - } catch (error) { + } + catch (error) { result = stored; } } + return result; } + return null; }, @@ -59,9 +66,11 @@ define('session-storage', ['storage'], function (Dep) { if (value instanceof Object || Array.isArray(value) || value === true || value === false) { value = '__JSON__:' + JSON.stringify(value); } + try { this.storageObject.setItem(name, value); - } catch (error) { + } + catch (error) { console.error(error); } }, @@ -71,12 +80,12 @@ define('session-storage', ['storage'], function (Dep) { }, clear: function (name) { - for (var i in this.storageObject) { + for (let i in this.storageObject) { if (i === name) { delete this.storageObject[i]; } } - } + }, }); }); diff --git a/client/src/storage.js b/client/src/storage.js index fbb44e12ca..4b1095b982 100644 --- a/client/src/storage.js +++ b/client/src/storage.js @@ -28,8 +28,7 @@ define('storage', [], function () { - var Storage = function () { - }; + let Storage = function () {}; _.extend(Storage.prototype, { @@ -46,14 +45,15 @@ define('storage', [], function () { }, checkType: function (type) { - if (typeof type === 'undefined' && toString.call(type) != '[object String]' || type == 'cache') { + if (typeof type === 'undefined' && toString.call(type) !== '[object String]' || type === 'cache') { throw new TypeError("Bad type \"" + type + "\" passed to Espo.Storage."); } }, has: function (type, name) { this.checkType(type); - var key = this.composeKey(type, name); + + let key = this.composeKey(type, name); return this.storageObject.getItem(key) !== null; }, @@ -61,65 +61,81 @@ define('storage', [], function () { get: function (type, name) { this.checkType(type); - var key = this.composeKey(type, name); + let key = this.composeKey(type, name); try { var stored = this.storageObject.getItem(key); - } catch (error) { + } + catch (error) { console.error(error); + return null; } if (stored) { - var result = stored; + let result = stored; if (stored.length > 9 && stored.substr(0, 9) === '__JSON__:') { - var jsonString = stored.substr(9); + let jsonString = stored.substr(9); + try { result = JSON.parse(jsonString); - } catch (error) { - result = stored; } - } else if (stored[0] == "{" || stored[0] == "[") { // for backward compatibility - try { - result = JSON.parse(stored); - } catch (error) { + catch (error) { result = stored; } } + else if (stored[0] === "{" || stored[0] === "[") { // for backward compatibility + try { + result = JSON.parse(stored); + } + catch (error) { + result = stored; + } + } + return result; } + return null; }, set: function (type, name, value) { this.checkType(type); - var key = this.composeKey(type, name); + let key = this.composeKey(type, name); + if (value instanceof Object || Array.isArray(value) || value === true || value === false) { value = '__JSON__:' + JSON.stringify(value); } + try { this.storageObject.setItem(key, value); - } catch (error) { + } + catch (error) { console.error(error); return null; } }, clear: function (type, name) { - var reText; + let reText; + if (typeof type !== 'undefined') { if (typeof name === 'undefined') { reText = '^' + this.composeFullPrefix(type); - } else { + } + else { reText = '^' + this.composeKey(type, name); } - } else { + } + else { reText = '^' + this.prefix + '-'; } - var re = new RegExp(reText); - for (var i in this.storageObject) { + + let re = new RegExp(reText); + + for (let i in this.storageObject) { if (re.test(i)) { delete this.storageObject[i]; } diff --git a/client/src/theme-manager.js b/client/src/theme-manager.js index 96fc2986c9..d5ece34304 100644 --- a/client/src/theme-manager.js +++ b/client/src/theme-manager.js @@ -28,7 +28,7 @@ define('theme-manager', [], function () { - var ThemeManager = function (config, preferences, metadata) { + let ThemeManager = function (config, preferences, metadata) { this.config = config; this.preferences = preferences; this.metadata = metadata; @@ -39,45 +39,60 @@ define('theme-manager', [], function () { defaultParams: { screenWidthXs: 768, dashboardCellHeight: 155, - dashboardCellMargin: 19 + dashboardCellMargin: 19, }, getName: function () { if (!this.config.get('userThemesDisabled')) { - var name = this.preferences.get('theme'); + let name = this.preferences.get('theme'); + if (name && name !== '') { return name; } } + return this.config.get('theme'); }, getAppliedName: function () { - var name = window.getComputedStyle(document.body).getPropertyValue('--theme-name'); - if (!name) return null; + let name = window.getComputedStyle(document.body).getPropertyValue('--theme-name'); + + if (!name) { + return null; + } + return name.trim(); }, isApplied: function () { - var appliedName = this.getAppliedName(); - if (!appliedName) return true; + let appliedName = this.getAppliedName(); + + if (!appliedName) { + return true; + } + return this.getName() === appliedName; }, getStylesheet: function () { - var link = this.metadata.get(['themes', this.getName(), 'stylesheet']) || 'client/css/espo/espo.css'; + let link = this.metadata.get(['themes', this.getName(), 'stylesheet']) || 'client/css/espo/espo.css'; + if (this.config.get('cacheTimestamp')) { link += '?r=' + this.config.get('cacheTimestamp').toString(); } - return link + + return link; }, getIframeStylesheet: function () { - var link = this.metadata.get(['themes', this.getName(), 'stylesheetIframe']) || 'client/css/espo/espo-iframe.css'; + let link = this.metadata.get(['themes', this.getName(), 'stylesheetIframe']) || + 'client/css/espo/espo-iframe.css'; + if (this.config.get('cacheTimestamp')) { link += '?r=' + this.config.get('cacheTimestamp').toString(); } - return link + + return link; }, getParam: function (name) { @@ -86,13 +101,15 @@ define('theme-manager', [], function () { isUserTheme: function () { if (!this.config.get('userThemesDisabled')) { - var name = this.preferences.get('theme'); + let name = this.preferences.get('theme'); + if (name && name !== '') { if (name !== this.config.get('theme')) { return true; } } } + return false; } diff --git a/client/src/ui.js b/client/src/ui.js index 924a27ea2d..036d7ea50a 100644 --- a/client/src/ui.js +++ b/client/src/ui.js @@ -42,7 +42,7 @@ define('ui', [], function () { this.dropdownItemList = []; this.removeOnClose = true; this.draggable = false; - this.container = 'body' + this.container = 'body'; this.onRemove = function () {}; this.options = options; @@ -65,11 +65,12 @@ define('ui', [], function () { 'container', 'onRemove' ]; - params.forEach(function (param) { + + params.forEach(param => { if (param in options) { this[param] = options[param]; } - }.bind(this)); + }); if (this.buttons && this.buttons.length) { this.buttonList = this.buttons; @@ -82,15 +83,23 @@ define('ui', [], function () { } this.contents = ''; + if (this.header) { - var headerClassName = ''; + let headerClassName = ''; + if (this.options.fixedHeaderHeight) { headerClassName = ' fixed-height'; } - this.contents += ''; + + this.contents += ''; } var body = ''; @@ -103,25 +112,27 @@ define('ui', [], function () { if (this.options.footerAtTheTop) { this.contents += footerHtml + body; - } else { + } + else { this.contents += body + footerHtml; } - this.contents = '' + this.contents = ''; - $('
').attr('id', this.id) - .attr('class', this.className + ' modal') - .attr('role', 'dialog') - .attr('tabindex', '-1') - .html(this.contents) - .appendTo($(this.container)); + $('
') + .attr('id', this.id) + .attr('class', this.className + ' modal') + .attr('role', 'dialog') + .attr('tabindex', '-1') + .html(this.contents) + .appendTo($(this.container)); this.$el = $('#' + this.id); this.el = this.$el.get(0); - this.$el.find('header a.close').on('click', function () { + this.$el.find('header a.close').on('click', () => { //this.close(); - }.bind(this)); + }); this.initButtonEvents(); @@ -140,53 +151,56 @@ define('ui', [], function () { } if (this.removeOnClose) { - this.$el.on('hidden.bs.modal', function (e) { - if (this.$el.get(0) == e.target) { + this.$el.on('hidden.bs.modal', e => { + if (this.$el.get(0) === e.target) { + if (this.skipRemove) { return; } this.remove(); } - }.bind(this)); + }); } $window = $(window); - this.$el.on('shown.bs.modal', function (e, r) { + this.$el.on('shown.bs.modal', (e, r) => { $('.modal-backdrop').not('.stacked').addClass('stacked'); - var headerHeight = this.$el.find('.modal-header').outerHeight(); - var footerHeight = this.$el.find('.modal-footer').outerHeight(); - var diffHeight = headerHeight + footerHeight; + let headerHeight = this.$el.find('.modal-header').outerHeight(); + let footerHeight = this.$el.find('.modal-footer').outerHeight(); + + let diffHeight = headerHeight + footerHeight; if (!options.fullHeight) { diffHeight = diffHeight + options.bodyDiffHeight; } - var h = $window.height(); - if (this.fitHeight || options.fullHeight) { - var processResize = function () { - var windowHeight = window.innerHeight; - var windowWidth = $window.width(); + let processResize = () => { + let windowHeight = window.innerHeight; + let windowWidth = $window.width(); if (!options.fullHeight && windowHeight < 512) { this.$el.find('div.modal-body').css({ maxHeight: 'none', overflow: 'auto', - height: 'none' + height: 'none', }); + return; } - var cssParams = { - overflow: 'auto' + let cssParams = { + overflow: 'auto', }; + if (options.fullHeight) { cssParams.height = (windowHeight - diffHeight) + 'px'; this.$el.css('paddingRight', 0); - } else { + } + else { if (windowWidth <= options.screenWidthXs) { cssParams.maxHeight = 'none'; } else { @@ -195,78 +209,99 @@ define('ui', [], function () { } this.$el.find('div.modal-body').css(cssParams); - }.bind(this); + }; + $window.off('resize.modal-height'); $window.on('resize.modal-height', processResize); + processResize(); } - }.bind(this)); + }); - var $body = $(document.body); + let $body = $(document.body); - this.$el.on('hidden.bs.modal', function (e) { + this.$el.on('hidden.bs.modal', e => { if ($('.modal:visible').length > 0) { $body.addClass('modal-open'); } }); - - } + }; Dialog.prototype.initButtonEvents = function () { - this.buttonList.forEach(function (o) { - if (typeof o.onClick == 'function') { - $('#' + this.id + ' .modal-footer button[data-name="' + o.name + '"]').on('click', function () { - o.onClick(this); - }.bind(this)); + this.buttonList.forEach(o => { + if (typeof o.onClick === 'function') { + $('#' + this.id + ' .modal-footer button[data-name="' + o.name + '"]') + .on('click', () => { + o.onClick(this); + }); } - }.bind(this)); + }); - this.dropdownItemList.forEach(function (o) { - if (typeof o.onClick == 'function') { - $('#' + this.id + ' .modal-footer a[data-name="' + o.name + '"]').on('click', function () { - o.onClick(this); - }.bind(this)); + this.dropdownItemList.forEach(o => { + if (typeof o.onClick === 'function') { + $('#' + this.id + ' .modal-footer a[data-name="' + o.name + '"]') + .on('click', () => { + o.onClick(this); + }); } - }.bind(this)); - } + }); + }; Dialog.prototype.getFooterHtml = function () { - var footer = ''; + let footer = ''; if (this.buttonList.length || this.dropdownItemList.length) { - var rightPart = ''; - this.buttonList.forEach(function (o) { - if (o.pullLeft) return; - var className = ''; + let rightPart = ''; + + this.buttonList.forEach(o => { + if (o.pullLeft) { + return; + } + + let className = ''; + if (o.className) { className = ' ' + o.className; } + rightPart += ' '; - }, this); - var leftPart = ''; - this.buttonList.forEach(function (o) { - if (!o.pullLeft) return; - var className = ''; + }); + + let leftPart = ''; + + this.buttonList.forEach(o => { + if (!o.pullLeft) { + return; + } + + let className = ''; + if (o.className) { className = ' ' + o.className; } + leftPart += ' '; - }, this); + }); + if (leftPart !== '') { leftPart = '
'+leftPart+'
'; + footer += leftPart; } if (this.dropdownItemList.length) { - var visibleCount = 0; + let visibleCount = 0; + this.dropdownItemList.forEach(function (o) { if (!o.hidden) { visibleCount++; @@ -275,16 +310,21 @@ define('ui', [], function () { rightPart += '
'; rightPart += '' + rightPart += ''; + rightPart += ''; rightPart += '' + + this.dropdownItemList.forEach(o => { + rightPart += + '
  • ' + + ''+(o.html || o.text)+'
  • '; + }); + + rightPart += ''; rightPart += '
    '; } + if (rightPart !== '') { rightPart = '
    '+rightPart+'
    '; footer += rightPart; @@ -292,38 +332,45 @@ define('ui', [], function () { } return footer; - } + }; Dialog.prototype.show = function () { this.$el.modal({ backdrop: this.backdrop, keyboard: this.keyboard }); + this.$el.find('.modal-content').removeClass('hidden'); - var $modalBackdrop = $('.modal-backdrop'); - $modalBackdrop.each(function (i, el) { + let $modalBackdrop = $('.modal-backdrop'); + + $modalBackdrop.each((i, el) => { if (i < $modalBackdrop.length - 1) { $(el).addClass('hidden'); } - }.bind(this)); + }); - var $modalConainer = $('.modal-container'); - $modalConainer.each(function (i, el) { + let $modalConainer = $('.modal-container'); + + $modalConainer.each((i, el) => { if (i < $modalConainer.length - 1) { $(el).addClass('overlaid'); } - }.bind(this)); + }); this.$el.off('click.dismiss.bs.modal'); - this.$el.on('click.dismiss.bs.modal', '> div.modal-dialog > div.modal-content > header [data-dismiss="modal"]', function () { - this.close(); - }.bind(this)); - this.$el.on('click.dismiss.bs.modal', function (e) { + + this.$el.on( + 'click.dismiss.bs.modal', + '> div.modal-dialog > div.modal-content > header [data-dismiss="modal"]', + () => this.close() + ); + + this.$el.on('click.dismiss.bs.modal', (e) => { if (e.target === e.currentTarget) { - return this.backdrop == 'static' ? this.$el[0].focus() : this.close(); + return this.backdrop === 'static' ? this.$el[0].focus() : this.close(); } - }.bind(this)); + }); $('body > .popover').addClass('hidden'); }; @@ -333,19 +380,21 @@ define('ui', [], function () { }; Dialog.prototype.hideWithBackdrop = function () { - var $modalBackdrop = $('.modal-backdrop'); + let $modalBackdrop = $('.modal-backdrop'); + $modalBackdrop.last().addClass('hidden'); $($modalBackdrop.get($modalBackdrop.length - 2)).removeClass('hidden'); - var $modalConainer = $('.modal-container'); + let $modalConainer = $('.modal-container'); + $($modalConainer.get($modalConainer.length - 2)).removeClass('overlaid'); this.skipRemove = true; - setTimeout(function () { + setTimeout(() => { this.skipRemove = false; - }.bind(this), 50); + }, 50); this.$el.modal('hide'); @@ -353,34 +402,41 @@ define('ui', [], function () { }; Dialog.prototype.close = function () { - var $modalBackdrop = $('.modal-backdrop'); + let $modalBackdrop = $('.modal-backdrop'); + $modalBackdrop.last().removeClass('hidden'); - var $modalConainer = $('.modal-container'); + let $modalConainer = $('.modal-container'); + $($modalConainer.get($modalConainer.length - 2)).removeClass('overlaid'); this.$el.modal('hide'); + $(this).trigger('dialog:close'); }; Dialog.prototype.remove = function () { this.onRemove(); + this.$el.remove(); + $(this).off(); $(window).off('resize.modal-height'); }; - var Ui = Espo.Ui = Espo.ui = { + let Ui = Espo.Ui = Espo.ui = { Dialog: Dialog, confirm: function (message, o, callback, context) { o = o || {}; + var confirmText = o.confirmText; var cancelText = o.cancelText; var confirmStyle = o.confirmStyle || 'danger'; var backdrop = o.backdrop; + if (typeof backdrop === 'undefined') { backdrop = false; } @@ -446,11 +502,21 @@ define('ui', [], function () { }).on('shown.bs.popover', function () { if (view) { $('body').off('click.popover-' + view.cid); + $('body').on('click.popover-' + view.cid, function (e) { - if ($(e.target).closest('.popover-content').get(0)) return; - if ($.contains($el.get(0), e.target)) return; - if ($el.get(0) === e.target) return; + if ($(e.target).closest('.popover-content').get(0)) { + return; + } + + if ($.contains($el.get(0), e.target)) { + return; + } + if ($el.get(0) === e.target) { + return; + } + $('body').off('click.popover-' + view.cid); + $el.popover('hide'); }); } @@ -467,6 +533,7 @@ define('ui', [], function () { $el.popover('destroy'); $('body').off('click.popover-' + view.cid); }); + view.on('render', function () { $el.popover('destroy'); $('body').off('click.popover-' + view.cid); @@ -479,22 +546,26 @@ define('ui', [], function () { if (message) { type = type || 'warning'; - if (typeof closeButton == 'undefined') { + if (typeof closeButton === 'undefined') { closeButton = false; } - if (type == 'error') { + if (type === 'error') { type = 'danger'; } - var el = $('
    ').css({ - position: 'fixed', - top: '0px', - 'z-index': 2000, - }).html(message); + var el = $('
    ') + .css({ + position: 'fixed', + top: '0px', + 'z-index': 2000, + }) + .html(message); if (closeButton) { - el.append(''); + el.append( + '' + ); } if (timeout) { @@ -523,7 +594,7 @@ define('ui', [], function () { info: function (message) { Espo.Ui.notify(message, 'info', 2000); }, - } + }; return Ui; }); diff --git a/client/src/utils.js b/client/src/utils.js index 54e52ee821..a43159ddb3 100644 --- a/client/src/utils.js +++ b/client/src/utils.js @@ -28,7 +28,7 @@ define('utils', [], function () { - var Utils = Espo.utils = Espo.Utils = { + let Utils = Espo.utils = Espo.Utils = { handleAction: function (viewObject, e) { var $target = $(e.currentTarget); @@ -170,6 +170,7 @@ define('utils', [], function () { } } } + if (item.teamIdList) { if (user && !(allowAllForAdmin && user.isAdmin())) { var inTeam = false; @@ -185,6 +186,7 @@ define('utils', [], function () { } } } + if (item.portalIdList) { if (user && !(allowAllForAdmin && user.isAdmin())) { var inPortal = false; @@ -200,6 +202,7 @@ define('utils', [], function () { } } } + if (item.isPortalOnly) { if (user && !(allowAllForAdmin && user.isAdmin())) { if (!user.isPortal()) { @@ -223,6 +226,7 @@ define('utils', [], function () { } } } + return true; }, @@ -278,6 +282,7 @@ define('utils', [], function () { data[i] = this.cloneDeep(data[i]); } } + return data; }, @@ -391,5 +396,4 @@ define('utils', [], function () { }; return Utils; - }); diff --git a/client/src/view-helper.js b/client/src/view-helper.js index 9977949e10..71570624a6 100644 --- a/client/src/view-helper.js +++ b/client/src/view-helper.js @@ -28,7 +28,7 @@ define('view-helper', ['lib!client/lib/purify.min.js'], function () { - var ViewHelper = function () { + let ViewHelper = function () { this._registerHandlebarsHelpers(); this.mdBeforeList = [ @@ -55,7 +55,8 @@ define('view-helper', ['lib!client/lib/purify.min.js'], function () { if (node instanceof HTMLAnchorElement) { if (node.getAttribute('target')) { node.targetBlack = true; - } else { + } + else { node.targetBlack = false; } } @@ -286,7 +287,8 @@ define('view-helper', ['lib!client/lib/purify.min.js'], function () { var checkOption = function (name) { if (multiple) { return value.indexOf(name) !== -1; - } else { + } + else { return value === name; } }; @@ -315,7 +317,8 @@ define('view-helper', ['lib!client/lib/purify.min.js'], function () { if (typeof translationHash !== 'object') { translationHash = {}; } - } else { + } + else { translationHash = {}; } } diff --git a/client/src/view-record-helper.js b/client/src/view-record-helper.js index 10042f66ab..eae1250daf 100644 --- a/client/src/view-record-helper.js +++ b/client/src/view-record-helper.js @@ -28,13 +28,15 @@ define('view-record-helper', [], function () { - var ViewRecordHelper = function (defaultFieldStates, defaultPanelStates) { + let ViewRecordHelper = function (defaultFieldStates, defaultPanelStates) { if (defaultFieldStates) { this.defaultFieldStates = defaultFieldStates; } + if (defaultPanelStates) { this.defaultPanelStates = defaultPanelStates; } + this.fieldStateMap = {}; this.panelStateMap = {}; @@ -63,11 +65,14 @@ define('view-record-helper', [], function () { case 'hidden': if (value) { this.hiddenFields[field] = true; - } else { + } + else { delete this.hiddenFields[field]; } + break; } + this.fieldStateMap[field] = this.fieldStateMap[field] || {}; this.fieldStateMap[field][name] = value; }, @@ -78,9 +83,11 @@ define('view-record-helper', [], function () { return this.fieldStateMap[field][name]; } } + if (name in this.defaultFieldStates) { return this.defaultFieldStates[name]; } + return null; }, @@ -94,6 +101,7 @@ define('view-record-helper', [], function () { } break; } + this.panelStateMap[panel] = this.panelStateMap[panel] || {}; this.panelStateMap[panel][name] = value; }, @@ -104,9 +112,11 @@ define('view-record-helper', [], function () { return this.panelStateMap[panel][name]; } } + if (name in this.defaultPanelStates) { return this.defaultPanelStates[name]; } + return null; }, @@ -124,8 +134,7 @@ define('view-record-helper', [], function () { hasFieldOptionList: function (field) { return (field in this.fieldOptionListMap); - } - + }, }); return ViewRecordHelper; diff --git a/client/src/view.js b/client/src/view.js index a6150534f9..af4c570484 100644 --- a/client/src/view.js +++ b/client/src/view.js @@ -44,14 +44,19 @@ define('view', [], function () { notify: function (label, type, timeout, scope) { if (label == false) { Espo.Ui.notify(false); + return; } + scope = scope || null; timeout = timeout || 2000; + if (!type) { timeout = null; } - var text = this.getLanguage().translate(label, 'labels', scope); + + let text = this.getLanguage().translate(label, 'labels', scope); + Espo.Ui.notify(text, type, timeout); }, @@ -179,7 +184,8 @@ define('view', [], function () { }, ajaxRequest: function (url, type, data, options) { - var options = options || {}; + options = options || {}; + options.type = type; options.url = url; options.context = this; @@ -188,23 +194,16 @@ define('view', [], function () { options.data = data; } - var xhr = $.ajax(options); + let xhr = $.ajax(options); return xhr; - - var obj = { - then: xhr.then, - fail: xhr.fail, - catch: xhr.fail - }; - - return obj; }, ajaxPostRequest: function (url, data, options) { if (data) { data = JSON.stringify(data); } + return this.ajaxRequest(url, 'POST', data, options); }, @@ -212,6 +211,7 @@ define('view', [], function () { if (data) { data = JSON.stringify(data); } + return this.ajaxRequest(url, 'PATCH', data, options); }, @@ -219,6 +219,7 @@ define('view', [], function () { if (data) { data = JSON.stringify(data); } + return this.ajaxRequest(url, 'PUT', data, options); }, @@ -230,25 +231,31 @@ define('view', [], function () { if (data) { data = JSON.stringify(data); } + return this.ajaxRequest(url, 'DELETE', data, options); }, confirm: function (o, callback, context) { + let message; + if (typeof o === 'string' || o instanceof String) { - var message = o; + message = o; + o = {}; - } else { + } + else { o = o || {}; - var message = o.message; + + message = o.message; } if (message) { message = this.getHelper().transfromMarkdownText(message, {linksInNewTab: true}).toString(); } - var confirmText = o.confirmText || this.translate('Yes'); - var confirmStyle = o.confirmStyle || null; - var cancelText = o.cancelText || this.translate('Cancel'); + let confirmText = o.confirmText || this.translate('Yes'); + let confirmStyle = o.confirmStyle || null; + let cancelText = o.cancelText || this.translate('Cancel'); return Espo.Ui.confirm(message, { confirmText: confirmText, diff --git a/client/src/web-socket-manager.js b/client/src/web-socket-manager.js index 0815c1e754..a03474de67 100644 --- a/client/src/web-socket-manager.js +++ b/client/src/web-socket-manager.js @@ -28,10 +28,10 @@ define('web-socket-manager', [], function () { - var WebSocketManager = function (config) { + let WebSocketManager = function (config) { this.config = config; - var url = this.config.get('webSocketUrl'); + let url = this.config.get('webSocketUrl'); if (url) { if (url.indexOf('wss://') === 0) { @@ -42,8 +42,9 @@ define('web-socket-manager', [], function () { this.url = url.substr(5); this.protocolPart = 'ws://'; } - } else { - var siteUrl = this.config.get('siteUrl') || ''; + } + else { + let siteUrl = this.config.get('siteUrl') || ''; if (siteUrl.indexOf('https://') === 0) { this.url = siteUrl.substr(8); @@ -54,19 +55,13 @@ define('web-socket-manager', [], function () { this.protocolPart = 'ws://'; } - if (~this.url.indexOf('/')) { this.url = this.url.replace(/\/$/, ''); } - if (this.protocolPart === 'wss://') { - var port = 443; - } - else { - var port = 8080; - } + let port = this.protocolPart === 'wss://' ? 443 : 8080; - var si = this.url.indexOf('/'); + let si = this.url.indexOf('/'); if (~si) { this.url = this.url.substr(0, si) + ':' + port; @@ -86,43 +81,44 @@ define('web-socket-manager', [], function () { _.extend(WebSocketManager.prototype, { connect: function (auth, userId) { + let authArray = Base64.decode(auth).split(':'); + + let authToken = authArray[1]; + + let url = this.protocolPart + this.url; + + url += '?authToken=' + authToken + '&userId=' + userId; + try { - var authArray = Base64.decode(auth).split(':'); - - var authToken = authArray[1]; - - var url = this.protocolPart + this.url; - - url += '?authToken=' + authToken + '&userId=' + userId; - this.connection = new ab.Session( url, - function () { + () => { this.isConnected = true; - this.subscribeQueue.forEach(function (item) { + this.subscribeQueue.forEach(item => { this.subscribe(item.category, item.callback); - }, this); + }); this.subscribeQueue = []; - }.bind(this), - function (e) { + }, + e => { if (e === ab.CONNECTION_CLOSED) { this.subscribeQueue = []; } if (e === ab.CONNECTION_LOST || e === ab.CONNECTION_UNREACHABLE) { setTimeout( - function () { + () => { this.connect(auth, userId); - }.bind(this), + }, 3000 ); } - }.bind(this), + }, {skipSubprotocolCheck: true} ); - } catch (e) { + } + catch (e) { console.error(e.message); this.connection = null; @@ -158,7 +154,7 @@ define('web-socket-manager', [], function () { return; } - this.subscribeQueue = this.subscribeQueue.filter(function (item) { + this.subscribeQueue = this.subscribeQueue.filter(item => { return item.category !== category && item.callback !== callback; });