diff --git a/client/src/views/fields/colorpicker.js b/client/src/views/fields/colorpicker.js index 1e7351b868..09ea24b14b 100644 --- a/client/src/views/fields/colorpicker.js +++ b/client/src/views/fields/colorpicker.js @@ -26,43 +26,47 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/fields/colorpicker', ['views/fields/varchar'], function (Dep) { +import VarcharFieldView from 'views/fields/varchar'; - return Dep.extend({ +class ColorpickerFieldView extends VarcharFieldView { - type: 'varchar', + type = 'varchar' - detailTemplate: 'fields/colorpicker/detail', - listTemplate: 'fields/colorpicker/detail', - editTemplate: 'fields/colorpicker/edit', + detailTemplate = 'fields/colorpicker/detail' + listTemplate = 'fields/colorpicker/detail' + editTemplate = 'fields/colorpicker/edit' - setup: function () { - Dep.prototype.setup.call(this); + setup() { + super.setup(); - this.wait(Espo.loader.requirePromise('lib!Colorpicker')); - }, + this.wait(Espo.loader.requirePromise('lib!Colorpicker')); + } - afterRender: function () { - Dep.prototype.afterRender.call(this); + afterRender() { + super.afterRender(); - if (this.isEditMode()) { - var isModal = !!this.$el.closest('.modal').length; + if (this.isEditMode()) { + let isModal = !!this.$el.closest('.modal').length; - this.$element.parent().colorpicker({ - format: 'hex', - container: isModal ? this.$el : false, - }); + // noinspection JSUnresolvedReference + this.$element.parent().colorpicker({ + format: 'hex', + container: isModal ? this.$el : false, + }); - if (isModal) { - this.$el.find('.colorpicker').css('position', 'relative').addClass('pull-right'); - } - - this.$element.on('change', () => { - if (this.$element.val() === '') { - this.$el.find('.input-group-addon > i').css('background-color', 'transparent'); - } - }); + if (isModal) { + this.$el.find('.colorpicker') + .css('position', 'relative') + .addClass('pull-right'); } - }, - }); -}); + + this.$element.on('change', () => { + if (this.$element.val() === '') { + this.$el.find('.input-group-addon > i').css('background-color', 'transparent'); + } + }); + } + } +} + +export default ColorpickerFieldView; diff --git a/client/src/views/fields/formula.js b/client/src/views/fields/formula.js index 41f5262db7..7bc9e9c9d9 100644 --- a/client/src/views/fields/formula.js +++ b/client/src/views/fields/formula.js @@ -26,400 +26,405 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/fields/formula', ['views/fields/text'], function (Dep) { +import TextFieldView from 'views/fields/text'; - return Dep.extend({ +let ace; - detailTemplate: 'fields/formula/detail', - editTemplate: 'fields/formula/edit', +class FormulaFieldView extends TextFieldView { - height: 300, - maxLineDetailCount: 80, - maxLineEditCount: 200, - insertDisabled: false, - checkSyntaxDisabled: false, + detailTemplate ='fields/formula/detail' + editTemplate = 'fields/formula/edit' - events: { - 'click [data-action="addAttribute"]': function () { - this.addAttribute(); - }, - 'click [data-action="addFunction"]': function () { - this.addFunction(); - }, - 'click [data-action="checkSyntax"]': function () { - this.checkSyntax(); - }, + height = 300 + maxLineDetailCount = 80 + maxLineEditCount = 200 + insertDisabled = false + checkSyntaxDisabled = false + + events = { + /** @this FormulaFieldView */ + 'click [data-action="addAttribute"]': function () { + this.addAttribute(); }, + /** @this FormulaFieldView */ + 'click [data-action="addFunction"]': function () { + this.addFunction(); + }, + /** @this FormulaFieldView */ + 'click [data-action="checkSyntax"]': function () { + this.checkSyntax(); + }, + } - setup: function () { - Dep.prototype.setup.call(this); + setup() { + super.setup(); - this.height = this.options.height || this.params.height || this.height; + this.height = this.options.height || this.params.height || this.height; - this.maxLineDetailCount = - this.options.maxLineDetailCount || - this.params.maxLineDetailCount || - this.maxLineDetailCount; + this.maxLineDetailCount = + this.options.maxLineDetailCount || + this.params.maxLineDetailCount || + this.maxLineDetailCount; - this.maxLineEditCount = - this.options.maxLineEditCount || - this.params.maxLineEditCount || - this.maxLineEditCount; + this.maxLineEditCount = + this.options.maxLineEditCount || + this.params.maxLineEditCount || + this.maxLineEditCount; - this.targetEntityType = - this.options.targetEntityType || - this.params.targetEntityType || - this.targetEntityType; + this.targetEntityType = + this.options.targetEntityType || + this.params.targetEntityType || + this.targetEntityType; - this.insertDisabled = this.insertDisabled || this.options.insertDisabled; - this.checkSyntaxDisabled = this.checkSyntaxDisabled || this.options.checkSyntaxDisabled; + this.insertDisabled = this.insertDisabled || this.options.insertDisabled; + this.checkSyntaxDisabled = this.checkSyntaxDisabled || this.options.checkSyntaxDisabled; - this.containerId = 'editor-' + Math.floor((Math.random() * 10000) + 1).toString(); + this.containerId = 'editor-' + Math.floor((Math.random() * 10000) + 1).toString(); - if (this.mode === 'edit' || this.mode === 'detail') { - this.wait( - this.requireAce() - ); + if (this.mode === this.MODE_EDIT || this.mode === this.MODE_DETAIL) { + this.wait( + this.requireAce() + ); + } + + this.on('remove', () => { + if (this.editor) { + this.editor.destroy(); } + }); + } - this.on('remove', () => { - if (this.editor) { - this.editor.destroy(); - } - }); - }, + requireAce() { + return Espo.loader.requirePromise('lib!ace') + .then(lib => { + ace = /** window.ace */lib; - requireAce: function () { - return Espo.loader - .requirePromise('lib!ace') - .then(() => { - let list = [ - Espo.loader.requirePromise('lib!ace-mode-javascript'), - Espo.loader.requirePromise('lib!ace-ext-language_tools'), - ]; - - if (this.getThemeManager().getParam('isDark')) { - list.push( - Espo.loader.requirePromise('lib!ace-theme-tomorrow_night') - ); - } - - return Promise.all(list); - }); - }, - - data: function () { - var data = Dep.prototype.data.call(this); - - data.containerId = this.containerId; - data.targetEntityType = this.targetEntityType; - data.hasSide = !this.insertDisabled && !this.checkSyntaxDisabled; - - data.hasInsert = !this.insertDisabled; - data.hasCheckSyntax = !this.checkSyntaxDisabled; - - return data; - }, - - afterRender: function () { - Dep.prototype.setup.call(this); - - this.$editor = this.$el.find('#' + this.containerId); - - if ( - this.$editor.length & - (this.mode === 'edit' || this.mode === 'detail' || this.mode === 'list') - ) { - this.$editor - .css('fontSize', '14px'); - - if (this.mode === 'edit') { - this.$editor.css('minHeight', this.height + 'px'); - } - - var editor = this.editor = ace.edit(this.containerId); - - editor.setOptions({ - maxLines: this.mode === 'edit' ? this.maxLineEditCount : this.maxLineDetailCount, - }); + let list = [ + Espo.loader.requirePromise('lib!ace-mode-javascript'), + Espo.loader.requirePromise('lib!ace-ext-language_tools'), + ]; if (this.getThemeManager().getParam('isDark')) { - editor.setOptions({ - theme: 'ace/theme/tomorrow_night', - }); + list.push( + Espo.loader.requirePromise('lib!ace-theme-tomorrow_night') + ); } - if (this.isEditMode()) { - editor.getSession().on('change', () => { - this.trigger('change', {ui: true}); - }); - - editor.getSession().setUseWrapMode(true); - } - - if (this.isReadMode()) { - editor.setReadOnly(true); - editor.renderer.$cursorLayer.element.style.display = "none"; - editor.renderer.setShowGutter(false); - } - - editor.setShowPrintMargin(false); - editor.getSession().setUseWorker(false); - editor.commands.removeCommand('find'); - editor.setHighlightActiveLine(false); - - var JavaScriptMode = ace.require('ace/mode/javascript').Mode; - - editor.session.setMode(new JavaScriptMode()); - - if (!this.insertDisabled && !this.isReadMode()) { - this.initAutocomplete(); - } - } - }, - - fetch: function () { - var data = {}; - - let value = this.editor.getValue(); - - if (value === '') { - value = null; - } - - data[this.name] = value; - - return data; - }, - - addAttribute: function () { - this.createView('dialog', 'views/admin/formula/modals/add-attribute', { - scope: this.targetEntityType - }, (view) => { - view.render(); - - this.listenToOnce(view, 'add', (attribute) => { - this.editor.insert(attribute); - - this.clearView('dialog'); - }); + return Promise.all(list); }); - }, + } - addFunction: function () { - this.createView('dialog', 'views/admin/formula/modals/add-function', { - scope: this.targetEntityType, - functionDataList: this.getFunctionDataList(), - }, (view) => { - view.render(); + data() { + let data = super.data(); - this.listenToOnce(view, 'add', (string) => { - this.editor.insert(string); + data.containerId = this.containerId; + data.targetEntityType = this.targetEntityType; + data.hasSide = !this.insertDisabled && !this.checkSyntaxDisabled; + data.hasInsert = !this.insertDisabled; + data.hasCheckSyntax = !this.checkSyntaxDisabled; - this.clearView('dialog'); - }); - }); - }, + return data; + } - getFunctionDataList: function () { - let list = Espo.Utils.clone( - this.getMetadata().get(['app', 'formula', 'functionList']) || [] - ); + afterRender() { + super.afterRender(); - if (this.options.additionalFunctionDataList) { - list = list.concat(this.options.additionalFunctionDataList); + this.$editor = this.$el.find('#' + this.containerId); + + if ( + this.$editor.length && + ( + this.mode === this.MODE_EDIT || + this.mode === this.MODE_DETAIL || + this.mode === this.MODE_LIST + ) + ) { + this.$editor.css('fontSize', '14px'); + + if (this.mode === this.MODE_EDIT) { + this.$editor.css('minHeight', this.height + 'px'); } - if (!this.targetEntityType) { - list = list.filter(item => { - if (item.name.indexOf('entity\\') === 0) { + let editor = this.editor = ace.edit(this.containerId); + + editor.setOptions({ + maxLines: this.mode === this.MODE_EDIT ? + this.maxLineEditCount : + this.maxLineDetailCount, + }); + + if (this.getThemeManager().getParam('isDark')) { + editor.setOptions({ + theme: 'ace/theme/tomorrow_night', + }); + } + + if (this.isEditMode()) { + editor.getSession().on('change', () => { + this.trigger('change', {ui: true}); + }); + + editor.getSession().setUseWrapMode(true); + } + + if (this.isReadMode()) { + editor.setReadOnly(true); + editor.renderer.$cursorLayer.element.style.display = "none"; + editor.renderer.setShowGutter(false); + } + + editor.setShowPrintMargin(false); + editor.getSession().setUseWorker(false); + editor.commands.removeCommand('find'); + editor.setHighlightActiveLine(false); + + let JavaScriptMode = ace.require('ace/mode/javascript').Mode; + + editor.session.setMode(new JavaScriptMode()); + + if (!this.insertDisabled && !this.isReadMode()) { + this.initAutocomplete(); + } + } + } + + fetch() { + let data = {}; + + let value = this.editor.getValue(); + + if (value === '') { + value = null; + } + + data[this.name] = value; + + return data; + } + + addAttribute() { + this.createView('dialog', 'views/admin/formula/modals/add-attribute', { + scope: this.targetEntityType + }, view => { + view.render(); + + this.listenToOnce(view, 'add', (attribute) => { + this.editor.insert(attribute); + + this.clearView('dialog'); + }); + }); + } + + addFunction() { + this.createView('dialog', 'views/admin/formula/modals/add-function', { + scope: this.targetEntityType, + functionDataList: this.getFunctionDataList(), + }, view => { + view.render(); + + this.listenToOnce(view, 'add', (string) => { + this.editor.insert(string); + + this.clearView('dialog'); + }); + }); + } + + getFunctionDataList() { + let list = Espo.Utils.clone( + this.getMetadata().get(['app', 'formula', 'functionList']) || [] + ); + + if (this.options.additionalFunctionDataList) { + list = list.concat(this.options.additionalFunctionDataList); + } + + if (!this.targetEntityType) { + list = list.filter(item => { + if (item.name.indexOf('entity\\') === 0) { + return false; + } + + return true; + }); + } + + return list; + } + + initAutocomplete() { + let functionItemList = this.getFunctionDataList().filter(item => item.insertText); + + let attributeList = this.getAttributeList(); + + ace.require('ace/ext/language_tools'); + + this.editor.setOptions({ + enableBasicAutocompletion: true, + enableLiveAutocompletion: true, + }); + + // noinspection JSUnusedGlobalSymbols + let completer = { + identifierRegexps: [/[\\a-zA-Z0-9{}\[\].$'"]/], + + getCompletions: function (editor, session, pos, prefix, callback) { + let matchedFunctionItemList = functionItemList + .filter((originalItem) => { + let text = originalItem.name; + + if (text.indexOf(prefix) === 0) { + return true; + } + + let parts = text.split('\\'); + + if (parts[parts.length - 1].indexOf(prefix) === 0) { + return true; + } + return false; - } - - return true; - }); - } - - return list; - }, - - initAutocomplete: function () { - var functionItemList = - this.getFunctionDataList() - .filter(item => { - return item.insertText; }); - var attributeList = this.getAttributeList(); + let itemList = matchedFunctionItemList.map((item) => { + return { + caption: item.name + '()', + value: item.insertText, + meta: item.returnType || null, + completer: { + insertMatch: (editor, data) => { + editor.completer.insertMatch({value: data.value}); - var languageTools = ace.require("ace/ext/language_tools"); + let index = data.value.indexOf('('); - this.editor.setOptions({ - enableBasicAutocompletion: true, - enableLiveAutocompletion: true, - }); + if (!~index) { + return; + } - var completer = { - identifierRegexps: [/[\\a-zA-Z0-9{}\[\]\.\$\'\"]/], + if (~data.value.indexOf('()')) { + return; + } - getCompletions: function (editor, session, pos, prefix, callback) { + let pos = editor.selection.getCursor(); - var matchedFunctionItemList = functionItemList - .filter((originalItem) => { - var text = originalItem.name; - - if (text.indexOf(prefix) === 0) { - return true; - } - - var parts = text.split('\\'); - - if (parts[parts.length - 1].indexOf(prefix) === 0) { - return true; - } - - return false; - }); - - var itemList = matchedFunctionItemList.map((item) => { - return { - caption: item.name + '()', - value: item.insertText, - meta: item.returnType || null, - completer: { - insertMatch: (editor, data) => { - editor.completer.insertMatch({value: data.value}); - - let index = data.value.indexOf('('); - - if (!~index) { - return; - } - - if (~data.value.indexOf('()')) { - return; - } - - let pos = editor.selection.getCursor(); - - editor.gotoLine( - pos.row + 1, - pos.column - data.value.length + index + 1 - ); - }, + editor.gotoLine( + pos.row + 1, + pos.column - data.value.length + index + 1 + ); }, - }; - }); - - var matchedAttributeList = attributeList - .filter((item) => { - if (item.indexOf(prefix) === 0) { - return true; - } - - return false; - }); - - var itemAttributeList = matchedAttributeList.map((item) => { - return { - name: item, - value: item, - meta: 'attribute', - }; - }); - - itemList = itemList.concat(itemAttributeList); - - callback(null, itemList); - } - }; - - this.editor.completers = [completer]; - }, - - getAttributeList: function () { - if (!this.targetEntityType) { - return []; - } - - var attributeList = this.getFieldManager() - .getEntityTypeAttributeList(this.targetEntityType) - .concat(['id']) - .sort(); - - var links = this.getMetadata().get(['entityDefs', this.targetEntityType, 'links']) || {}; - - var linkList = []; - - Object.keys(links).forEach((link) => { - var type = links[link].type; - - if (!type) { - return; - } - - if (~['belongsToParent', 'hasOne', 'belongsTo'].indexOf(type)) { - linkList.push(link); - } - }); - - linkList.sort(); - - linkList.forEach((link) => { - var scope = links[link].entity; - - if (!scope) { - return; - } - - if (links[link].disabled) { - return; - } - - var linkAttributeList = this.getFieldManager() - .getEntityTypeAttributeList(scope) - .sort(); - - linkAttributeList.forEach((item) => { - attributeList.push(link + '.' + item); + }, + }; }); - }); - return attributeList; - }, + let matchedAttributeList = attributeList + .filter((item) => { + if (item.indexOf(prefix) === 0) { + return true; + } - checkSyntax: function () { - let expression = this.editor.getValue(); + return false; + }); - if (!expression) { - Espo.Ui.success( - this.translate('checkSyntaxSuccess', 'messages', 'Formula') - ); + let itemAttributeList = matchedAttributeList.map((item) => { + return { + name: item, + value: item, + meta: 'attribute', + }; + }); + itemList = itemList.concat(itemAttributeList); + + callback(null, itemList); + } + }; + + this.editor.completers = [completer]; + } + + getAttributeList() { + if (!this.targetEntityType) { + return []; + } + + let attributeList = this.getFieldManager() + .getEntityTypeAttributeList(this.targetEntityType) + .concat(['id']) + .sort(); + + let links = this.getMetadata().get(['entityDefs', this.targetEntityType, 'links']) || {}; + + let linkList = []; + + Object.keys(links).forEach((link) => { + var type = links[link].type; + + if (!type) { return; } - Espo.Ajax - .postRequest('Formula/action/checkSyntax', { - expression: expression, - }) - .then(response => { - if (response.isSuccess) { - Espo.Ui.success( - this.translate('checkSyntaxSuccess', 'messages', 'Formula') - ); + if (~['belongsToParent', 'hasOne', 'belongsTo'].indexOf(type)) { + linkList.push(link); + } + }); - return; - } + linkList.sort(); - let message = this.translate('checkSyntaxError', 'messages', 'Formula'); + linkList.forEach((link) => { + var scope = links[link].entity; - if (response.message) { - message += ' ' + response.message; - } + if (!scope) { + return; + } - Espo.Ui.error(message); - }); - }, - }); -}); + if (links[link].disabled) { + return; + } + + let linkAttributeList = this.getFieldManager() + .getEntityTypeAttributeList(scope) + .sort(); + + linkAttributeList.forEach((item) => { + attributeList.push(link + '.' + item); + }); + }); + + return attributeList; + } + + checkSyntax() { + let expression = this.editor.getValue(); + + if (!expression) { + Espo.Ui.success( + this.translate('checkSyntaxSuccess', 'messages', 'Formula') + ); + + return; + } + + Espo.Ajax + .postRequest('Formula/action/checkSyntax', {expression: expression}) + .then(response => { + if (response.isSuccess) { + Espo.Ui.success( + this.translate('checkSyntaxSuccess', 'messages', 'Formula') + ); + + return; + } + + let message = this.translate('checkSyntaxError', 'messages', 'Formula'); + + if (response.message) { + message += ' ' + response.message; + } + + Espo.Ui.error(message); + }); + } +} + +export default FormulaFieldView;