diff --git a/client/src/search-manager.js b/client/src/search-manager.js index b89ecea501..3cd15c679b 100644 --- a/client/src/search-manager.js +++ b/client/src/search-manager.js @@ -57,9 +57,9 @@ * @typedef {Object} module:search-manager~advancedFilter * * @property {string} type A type. E.g. `equals`. - * @property {string} attribute An attribute. + * @property {string} [attribute] An attribute. * @property {*} [value] A value. - * @property {Object.} [data] Additional data for UI. + * @property {Object.} [data] Additional data for UI. */ /** @@ -306,7 +306,7 @@ class SearchManager { /** * Set advanced filters. * - * @param {{string: module:search-manager~advancedFilter}} advanced Advanced filters. + * @param {Object.} advanced Advanced filters. * Pairs of field => advancedFilter. */ setAdvanced(advanced) { diff --git a/client/src/views/modal.js b/client/src/views/modal.js index ec0b119471..492b5678e8 100644 --- a/client/src/views/modal.js +++ b/client/src/views/modal.js @@ -64,7 +64,7 @@ class ModalView extends View { * @property {'default'|'danger'|'success'|'warning'} [style='default'] A style. * @property {boolean} [hidden=false] Is hidden. * @property {boolean} [disabled=false] Disabled. - * @property {function():void} [onClick] Called on click. If not defined, then + * @property {function(module:ui.Dialog): void} [onClick] Called on click. If not defined, then * the `action` class method will be called. * @property {string} [className] An additional class name. */ diff --git a/client/src/views/modals/kanban-move-over.js b/client/src/views/modals/kanban-move-over.js index a66deebb50..ecb502ea5b 100644 --- a/client/src/views/modals/kanban-move-over.js +++ b/client/src/views/modals/kanban-move-over.js @@ -26,83 +26,93 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/kanban-move-over', ['views/modal'], function (Dep) { +import ModalView from 'views/modal'; - return Dep.extend({ +class KanbanMoveOverModalView extends ModalView { - template: 'modals/kanban-move-over', + template = 'modals/kanban-move-over' - data: function () { - return { - optionDataList: this.optionDataList - }; + /** @inheritDoc */ + backdrop = true + + data() { + return { + optionDataList: this.optionDataList, + }; + } + + events = { + /** @this KanbanMoveOverModalView */ + 'click [data-action="move"]': function (e) { + let value = $(e.currentTarget).data('value'); + + this.moveTo(value); }, + } - events: { - 'click [data-action="move"]': function (e) { - var value = $(e.currentTarget).data('value'); - this.moveTo(value); - } - }, + setup() { + this.scope = this.model.name; - setup: function () { - this.scope = this.model.name; - var iconHtml = this.getHelper().getScopeColorIconHtml(this.scope); + let iconHtml = this.getHelper().getScopeColorIconHtml(this.scope); - this.statusField = this.options.statusField; + this.statusField = this.options.statusField; - this.$header = $(''); + this.$header = $(''); + this.$header.append( + $('').text(this.getLanguage().translate(this.scope, 'scopeNames')) + ); + + if (this.model.get('name')) { + this.$header.append(' '); this.$header.append( - $('').text(this.getLanguage().translate(this.scope, 'scopeNames')) - ); + $('').text(this.model.get('name')) + ) + } - if (this.model.get('name')) { - this.$header.append(' '); - this.$header.append( - $('').text(this.model.get('name')) - ) + this.$header.prepend(iconHtml); + + this.buttonList = [ + { + name: 'cancel', + label: 'Cancel' } + ]; - this.$header.prepend(iconHtml); + this.optionDataList = []; - this.buttonList = [ + ( + this.getMetadata() + .get(['entityDefs', this.scope, 'fields', this.statusField, 'options']) || [] + ) + .forEach((item) => { + this.optionDataList.push({ + value: item, + label: this.getLanguage().translateOption(item, this.statusField, this.scope), + }); + }); + } + + moveTo(status) { + var attributes = {}; + + attributes[this.statusField] = status; + + this.model + .save( + attributes, { - name: 'cancel', - label: 'Cancel' + patch: true, + isMoveTo: true, } - ]; + ) + .then(() => { + Espo.Ui.success(this.translate('Done')); + }); - this.optionDataList = []; + this.close(); + } +} - (this.getMetadata() - .get(['entityDefs', this.scope, 'fields', this.statusField, 'options']) || []) - .forEach((item) => { - this.optionDataList.push({ - value: item, - label: this.getLanguage().translateOption(item, this.statusField, this.scope), - }); - }); - }, - - moveTo: function (status) { - var attributes = {}; - - attributes[this.statusField] = status; - - this.model - .save( - attributes, - { - patch: true, - isMoveTo: true, - } - ) - .then(() => { - Espo.Ui.success(this.translate('Done')); - }); - - this.close(); - }, - }); -}); +// noinspection JSUnusedGlobalSymbols +export default KanbanMoveOverModalView; diff --git a/client/src/views/modals/last-viewed.js b/client/src/views/modals/last-viewed.js index 29b489dd7e..bf0bc1f63c 100644 --- a/client/src/views/modals/last-viewed.js +++ b/client/src/views/modals/last-viewed.js @@ -26,69 +26,70 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/last-viewed', ['views/modal', 'search-manager'], function (Dep) { +import ModalView from 'views/modal'; - return Dep.extend({ +class LastViewedModalView extends ModalView { - header: false, - scope: 'ActionHistoryRecord', - className: 'dialog dialog-record', - template: 'modals/last-viewed', - backdrop: true, - - setup: function () { - Dep.prototype.setup.call(this); - - this.events['click .list .cell > a'] = () => { - this.close(); - }; - - this.$header = $('') - .attr('href', '#LastViewed') - .attr('data-action', 'listView') - .addClass('action') - .text(this.getLanguage().translate('LastViewed', 'scopeNamesPlural')); - - this.waitForView('list'); - - this.getCollectionFactory().create(this.scope, (collection) => { - collection.maxSize = this.getConfig().get('recordsPerPage'); - this.collection = collection; - - collection.url = 'LastViewed'; - - this.loadList(); - collection.fetch(); - }); - }, - - actionListView: function () { - this.getRouter().navigate('#LastViewed', {trigger: true}); + scope = 'ActionHistoryRecord' + className = 'dialog dialog-record' + template = 'modals/last-viewed' + backdrop = true + setup() { + this.events['click .list .cell > a'] = () => { this.close(); - }, + }; - loadList: function () { - var viewName = - this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.listLastViewed') || - 'views/record/list'; + this.$header = $('') + .attr('href', '#LastViewed') + .attr('data-action', 'listView') + .addClass('action') + .text(this.getLanguage().translate('LastViewed', 'scopeNamesPlural')); - this.listenToOnce(this.collection, 'sync', function () { - this.createView('list', viewName, { - collection: this.collection, - el: this.containerSelector + ' .list-container', - selectable: false, - checkboxes: false, - massActionsDisabled: true, - rowActionsView: false, - searchManager: this.searchManager, - checkAllResultDisabled: true, - buttonsDisabled: true, - headerDisabled: true, - layoutName: 'listForLastViewed', - layoutAclDisabled: true, - }); - }, this); - }, - }); -}); + this.waitForView('list'); + + this.getCollectionFactory().create(this.scope, collection => { + collection.maxSize = this.getConfig().get('recordsPerPage'); + collection.url = 'LastViewed'; + + this.collection = collection; + + this.loadList(); + + collection.fetch(); + }); + } + + // noinspection JSUnusedGlobalSymbols + actionListView() { + this.getRouter().navigate('#LastViewed', {trigger: true}); + + this.close(); + } + + loadList() { + let viewName = + this.getMetadata().get('clientDefs.' + this.scope + '.recordViews.listLastViewed') || + 'views/record/list'; + + this.listenToOnce(this.collection, 'sync', () => { + this.createView('list', viewName, { + collection: this.collection, + el: this.containerSelector + ' .list-container', + selectable: false, + checkboxes: false, + massActionsDisabled: true, + rowActionsView: false, + searchManager: this.searchManager, + checkAllResultDisabled: true, + buttonsDisabled: true, + headerDisabled: true, + layoutName: 'listForLastViewed', + layoutAclDisabled: true, + }); + }); + } +} + +// noinspection JSUnusedGlobalSymbols +export default LastViewedModalView; diff --git a/client/src/views/modals/mass-action.js b/client/src/views/modals/mass-action.js index ae3a0f6c08..8009dcc3e4 100644 --- a/client/src/views/modals/mass-action.js +++ b/client/src/views/modals/mass-action.js @@ -26,129 +26,129 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/mass-action', ['views/modal', 'model'], function (Dep, Model) { +import ModalView from 'views/modal'; +import Model from 'model'; - return Dep.extend({ +class MassActionModalView extends ModalView { - className: 'dialog dialog-record', + template = 'modals/mass-action' - template: 'modals/mass-action', + className = 'dialog dialog-record' + checkInterval = 4000 - checkInterval: 4000, + data() { + return { + infoText: this.translate('infoText', 'messages', 'MassAction'), + }; + } - data: function () { - return { - infoText: this.translate('infoText', 'messages', 'MassAction'), - }; - }, + setup() { + this.action = this.options.action; + this.id = this.options.id; + this.status = 'Pending'; - setup: function () { - this.action = this.options.action; - this.id = this.options.id; - this.status = 'Pending'; + this.headerText = + this.translate('Mass Action', 'scopeNames') + ': ' + + this.translate(this.action, 'massActions', this.options.scope); - this.headerText = - this.translate('Mass Action', 'scopeNames') + ': ' + - this.translate(this.action, 'massActions', this.options.scope); + this.model = new Model(); + this.model.name = 'MassAction'; - this.model = new Model(); - this.model.name = 'MassAction'; + this.model.setDefs({ + fields: { + 'status': { + type: 'enum', + readOnly: true, + options: [ + 'Pending', + 'Running', + 'Success', + 'Failed', + ], + style: { + 'Success': 'success', + 'Failed': 'danger', + }, + }, + 'processedCount': { + type: 'int', + readOnly: true, + }, + } + }); - this.model.setDefs({ - fields: { - 'status': { - type: 'enum', - readOnly: true, - options: [ - 'Pending', - 'Running', - 'Success', - 'Failed', + this.model.set({ + status: this.status, + processedCount: null, + }); + + this.createView('record', 'views/record/edit-for-modal', { + scope: 'None', + model: this.model, + el: this.getSelector() + ' .record', + detailLayout: [ + { + rows: [ + [ + { + name: 'status', + labelText: this.translate('status', 'fields', 'MassAction'), + }, + { + name: 'processedCount', + labelText: this.translate('processedCount', 'fields', 'MassAction'), + }, ], - style: { - 'Success': 'success', - 'Failed': 'danger', - }, - }, - 'processedCount': { - type: 'int', - readOnly: true, - }, - } - }); + ], + }, + ], + }); - this.model.set({ - status: this.status, - processedCount: null, - }); + this.on('close', () => { + let status = this.model.get('status'); - this.createView('record', 'views/record/edit-for-modal', { - scope: 'None', - model: this.model, - el: this.getSelector() + ' .record', - detailLayout: [ - { - rows: [ - [ - { - name: 'status', - labelText: this.translate('status', 'fields', 'MassAction'), - }, - { - name: 'processedCount', - labelText: this.translate('processedCount', 'fields', 'MassAction'), - } - ] - ] - } - ], - }); + if ( + status !== 'Pending' && + status !== 'Running' + ) { + return; + } - this.on('close', () => { - let status = this.model.get('status'); + Espo.Ajax.postRequest(`MassAction/${this.id}/subscribe`); + }); + + this.checkStatus(); + } + + checkStatus() { + Espo.Ajax + .getRequest(`MassAction/${this.id}/status`) + .then(response => { + let status = response.status; + + this.model.set('status', status); + + if (status === 'Pending' || status === 'Running') { + setTimeout(() => this.checkStatus(), this.checkInterval); - if ( - status !== 'Pending' && - status !== 'Running' - ) { return; } - Espo.Ajax.postRequest(`MassAction/${this.id}/subscribe`); - }); - - this.checkStatus(); - }, - - checkStatus: function () { - Espo.Ajax - .getRequest(`MassAction/${this.id}/status`) - .then(response => { - let status = response.status; - - this.model.set('status', status); - - if (status === 'Pending' || status === 'Running') { - setTimeout(() => this.checkStatus(), this.checkInterval); - - return; - } - - this.model.set({ - processedCount: response.processedCount, - }); - - if (status === 'Success') { - this.trigger('success', { - count: response.processedCount, - }); - } - - if (this.$el) { - this.$el.find('.info-text').addClass('hidden'); - } + this.model.set({ + processedCount: response.processedCount, }); - }, - }); -}); + if (status === 'Success') { + this.trigger('success', { + count: response.processedCount, + }); + } + + if (this.$el) { + this.$el.find('.info-text').addClass('hidden'); + } + }); + } +} + +export default MassActionModalView; diff --git a/client/src/views/modals/mass-update.js b/client/src/views/modals/mass-update.js index 48db40d8e7..bf25a798b9 100644 --- a/client/src/views/modals/mass-update.js +++ b/client/src/views/modals/mass-update.js @@ -26,323 +26,331 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/mass-update', ['views/modal', 'helpers/mass-action'], function (Dep, MassActionHelper) { +import ModalView from 'views/modal'; +import MassActionHelper from 'helpers/mass-action'; - return Dep.extend({ +class MassUpdateModalView extends ModalView { - cssName: 'mass-update', + template = 'modals/mass-update' - className: 'dialog dialog-record', + cssName = 'mass-update' + className = 'dialog dialog-record' + layoutName = 'massUpdate' - template: 'modals/mass-update', + ACTION_UPDATE = 'update' + //ACTION_ADD = 'add' + //ACTION_REMOVE = 'remove' - layoutName: 'massUpdate', + data() { + return { + scope: this.scope, + fieldList: this.fieldList, + entityType: this.entityType, + }; + } - ACTION_UPDATE: 'update', + events = { + /** @this MassUpdateModalView */ + 'click a[data-action="add-field"]': function (e) { + let field = $(e.currentTarget).data('name'); - ACTION_ADD: 'add', - - ACTION_REMOVE: 'remove', - - data: function () { - return { - scope: this.scope, - fieldList: this.fieldList, - entityType: this.entityType, - }; + this.addField(field); }, + /** @this MassUpdateModalView */ + 'click button[data-action="reset"]': function () { + this.reset(); + } + } - events: { - 'click button[data-action="update"]': function () { - this.update(); + setup() { + this.buttonList = [ + { + name: 'update', + label: 'Update', + style: 'danger', + disabled: true, }, - 'click a[data-action="add-field"]': function (e) { - var field = $(e.currentTarget).data('name'); - this.addField(field); - }, - 'click button[data-action="reset"]': function (e) { - this.reset(); + { + name: 'cancel', + label: 'Cancel', } - }, + ]; - setup: function () { - this.buttonList = [ - { - name: 'update', - label: 'Update', - style: 'danger', - disabled: true, - }, - { - name: 'cancel', - label: 'Cancel', - } - ]; + this.entityType = this.options.entityType || this.options.scope; + this.scope = this.options.scope || this.entityType; - this.entityType = this.options.entityType || this.options.scope; - this.scope = this.options.scope || this.entityType; + this.ids = this.options.ids; + this.where = this.options.where; + this.searchParams = this.options.searchParams; + this.byWhere = this.options.byWhere; - this.ids = this.options.ids; - this.where = this.options.where; - this.searchParams = this.options.searchParams; - this.byWhere = this.options.byWhere; + this.hasActionMap = {}; - this.hasActionMap = {}; + let totalCount = this.options.totalCount; - let totalCount = this.options.totalCount; + this.helper = new MassActionHelper(this); - this.helper = new MassActionHelper(this); + this.idle = this.byWhere && this.helper.checkIsIdle(totalCount); - this.idle = this.byWhere && this.helper.checkIsIdle(totalCount); + this.$header = $('') + .append( + $('').text(this.translate(this.scope, 'scopeNamesPlural')), + ' ', + $('').text(this.translate('Mass Update')) + ) - this.$header = $('') - .append( - $('').text(this.translate(this.scope, 'scopeNamesPlural')), - ' ', - $('').text(this.translate('Mass Update')) - ) + var forbiddenList = this.getAcl().getScopeForbiddenFieldList(this.entityType, 'edit') || []; - var forbiddenList = this.getAcl().getScopeForbiddenFieldList(this.entityType, 'edit') || []; + this.wait(true); - this.wait(true); + this.getModelFactory().create(this.entityType, (model) => { + this.model = model; - this.getModelFactory().create(this.entityType, (model) => { - this.model = model; + this.getHelper().layoutManager.get(this.entityType, this.layoutName, (layout) => { + layout = layout || []; - this.getHelper().layoutManager.get(this.entityType, this.layoutName, (layout) => { - layout = layout || []; + this.fieldList = []; - this.fieldList = []; + layout.forEach((field) => { + if (~forbiddenList.indexOf(field)) { + return; + } - layout.forEach((field) => { - if (~forbiddenList.indexOf(field)) { - return; - } - - if (model.hasField(field)) { - this.fieldList.push(field); - } - }); - - this.wait(false); + if (model.hasField(field)) { + this.fieldList.push(field); + } }); + + this.wait(false); + }); + }); + + this.addedFieldList = []; + } + + addField(name) { + this.$el.find('[data-action="reset"]').removeClass('hidden'); + + this.$el.find('ul.filter-list li[data-name="'+name+'"]').addClass('hidden'); + + if (this.$el.find('ul.filter-list li:not(.hidden)').length === 0) { + this.$el.find('button.select-field').addClass('disabled').attr('disabled', 'disabled'); + } + + this.addedFieldList.push(name); + + let label = this.getHelper().escapeString( + this.translate(name, 'fields', this.entityType) + ); + + let $cell = + $('
') + .addClass('cell form-group') + .attr('data-name', name) + .append( + $('
') + .addClass('field') + .attr('data-name', name) + ); + + let $row = + $('
') + .addClass('item grid-auto-fill-md') + .attr('data-name', name) + .append($cell); + + this.$el.find('.fields-container').append($row); + + let type = this.model.getFieldType(name); + let viewName = this.model.getFieldParam(name, 'view') || this.getFieldManager().getViewName(type); + + let actionList = this.getMetadata().get(['entityDefs', this.entityType, name, 'massUpdateActionList']) || + this.getMetadata().get(['fields', type, 'massUpdateActionList']); + + let hasActionDropdown = actionList !== null; + + this.hasActionMap[name] = hasActionDropdown; + + this.disableButton('update'); + + this.createView(name, viewName, { + model: this.model, + el: this.getSelector() + ' .field[data-name="' + name + '"]', + defs: { + name: name, + }, + mode: 'edit', + }, view => { + this.enableButton('update'); + + view.render(); + }); + + if (hasActionDropdown) { + let $select = + $('') - .addClass('item-action form-control') - .attr('data-name', name); - - actionList.forEach(action => { - let label = this.translate(Espo.Utils.upperCaseFirst(action)); - - $select.append( - $('
') - .addClass('cell call-action form-group') - .attr('data-name', name) - .append( - $('
') - .addClass('field') - .attr('data-name', name) - .append($select) - ); + _.extend(attributes, itemActualAttributes); + }); - $row.append($cellAction); - } - }, + this.model.set(attributes); - actionUpdate: function () { - this.disableButton('update'); + let notValid = false; - let attributes = {}; - let actions = {}; + this.addedFieldList.forEach(field => { + let view = this.getFieldView(field); - this.addedFieldList.forEach(field => { - let action = this.fetchAction(field); - let itemAttributes = this.getView(field).fetch(); + notValid = view.validate() || notValid; + }); - let itemActualAttributes = {}; + if (notValid) { + Espo.Ui.error(this.translate('Not valid')) - this.getFieldManager() - .getEntityTypeFieldActualAttributeList(this.entityType, field) - .forEach(attribute => { - actions[attribute] = action; + this.enableButton('update'); - itemActualAttributes[attribute] = itemAttributes[attribute]; - }); + return; + } - _.extend(attributes, itemActualAttributes); - }); + Espo.Ui.notify(this.translate('saving', 'messages')); - this.model.set(attributes); + Espo.Ajax + .postRequest('MassAction', { + action: 'update', + entityType: this.entityType, + params: { + ids: this.ids || null, + where: (!this.ids || this.ids.length === 0) ? this.options.where : null, + searchParams: (!this.ids || this.ids.length === 0) ? this.options.searchParams : null, + }, + data: { + values: attributes, + actions: actions, + }, + idle: this.idle, + }) + .then(result => { + result = result || {}; - let notValid = false; + if (result.id) { + this.helper + .process(result.id, 'update') + .then(view => { + this.listenToOnce(view, 'close', () => this.close()); - this.addedFieldList.forEach(field => { - let view = this.getView(field); - - notValid = view.validate() || notValid; - }); - - if (notValid) { - this.notify('Not valid', 'error'); - this.enableButton('update'); - - return; - } - - Espo.Ui.notify(this.translate('saving', 'messages')); - - Espo.Ajax - .postRequest('MassAction', { - action: 'update', - entityType: this.entityType, - params: { - ids: this.ids || null, - where: (!this.ids || this.ids.length === 0) ? this.options.where : null, - searchParams: (!this.ids || this.ids.length === 0) ? this.options.searchParams : null, - }, - data: { - values: attributes, - actions: actions, - }, - idle: this.idle, - }) - .then(result => { - result = result || {}; - - if (result.id) { - this.helper - .process(result.id, 'update') - .then(view => { - this.listenToOnce(view, 'close', () => this.close()); - - this.listenToOnce(view, 'success', result => { - this.trigger('after:update', { - count: result.count, - idle: true, - }); + this.listenToOnce(view, 'success', result => { + this.trigger('after:update', { + count: result.count, + idle: true, }); }); + }); - return; - } + return; + } - this.trigger('after:update', { - count: result.count, - }); - }) - .catch(() => { - this.enableButton('update'); + this.trigger('after:update', { + count: result.count, }); - }, - - fetchAction: function (name) { - if (!this.hasActionMap[name]) { - return this.ACTION_UPDATE; - } - - let $dropdown = this.$el.find('select.item-action[data-name="'+name+'"]'); - - return $dropdown.val() || this.ACTION_UPDATE; - }, - - reset: function () { - this.addedFieldList.forEach(field => { - this.clearView(field); - - this.$el.find('.item[data-name="'+field+'"]').remove(); + }) + .catch(() => { + this.enableButton('update'); }); + } - this.addedFieldList = []; - this.hasActionMap = {}; + fetchAction(name) { + if (!this.hasActionMap[name]) { + return this.ACTION_UPDATE; + } - this.model.clear(); + let $dropdown = this.$el.find('select.item-action[data-name="' + name + '"]'); - this.$el.find('[data-action="reset"]').addClass('hidden'); - this.$el.find('button.select-field').removeClass('disabled').removeAttr('disabled'); - this.$el.find('ul.filter-list').find('li').removeClass('hidden'); + return $dropdown.val() || this.ACTION_UPDATE; + } - this.disableButton('update'); - }, - }); -}); + reset() { + this.addedFieldList.forEach(field => { + this.clearView(field); + + this.$el.find('.item[data-name="'+field+'"]').remove(); + }); + + this.addedFieldList = []; + this.hasActionMap = {}; + + this.model.clear(); + + this.$el.find('[data-action="reset"]').addClass('hidden'); + this.$el.find('button.select-field').removeClass('disabled').removeAttr('disabled'); + this.$el.find('ul.filter-list').find('li').removeClass('hidden'); + + this.disableButton('update'); + } +} + +export default MassUpdateModalView; diff --git a/client/src/views/modals/password-change-request.js b/client/src/views/modals/password-change-request.js index ddc72ec1bc..3834e9473d 100644 --- a/client/src/views/modals/password-change-request.js +++ b/client/src/views/modals/password-change-request.js @@ -26,170 +26,169 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/password-change-request', ['views/modal'], function (Dep) { +import ModalView from 'views/modal'; - return Dep.extend({ +class PasswordChangeRequestModalView extends ModalView { - cssName: 'password-change-request', + template = 'modals/password-change-request' - className: 'dialog dialog-centered', + cssName = 'password-change-request' + className = 'dialog dialog-centered' + noFullHeight = true + footerAtTheTop = false - template: 'modals/password-change-request', + setup() { + this.buttonList = [ + { + name: 'submit', + label: 'Submit', + style: 'danger', + className: 'btn-s-wide', + }, + { + name: 'cancel', + label: 'Close', + pullLeft: true, + className: 'btn-s-wide', + } + ]; - noFullHeight: true, + this.headerText = this.translate('Password Change Request', 'labels', 'User'); - footerAtTheTop: false, + this.once('close remove', () => { + if (this.$userName) { + this.$userName.popover('destroy'); + } - setup: function () { + if (this.$emailAddress) { + this.$emailAddress.popover('destroy'); + } + }); + } - this.buttonList = [ - { - name: 'submit', - label: 'Submit', - style: 'danger', - className: 'btn-s-wide', - }, - { - name: 'cancel', - label: 'Close', - pullLeft: true, - className: 'btn-s-wide', - } - ]; + afterRender() { + this.$userName = this.$el.find('input[name="username"]'); + this.$emailAddress = this.$el.find('input[name="emailAddress"]'); + } - this.headerText = this.translate('Password Change Request', 'labels', 'User'); + // noinspection JSUnusedGlobalSymbols + actionSubmit() { + let $userName = this.$userName; + let $emailAddress = this.$emailAddress; - this.once('close remove', () => { - if (this.$userName) { - this.$userName.popover('destroy'); + let userName = $userName.val(); + let emailAddress = $emailAddress.val(); + + let isValid = true; + + if (userName === '') { + isValid = false; + + var message = this.getLanguage().translate('userCantBeEmpty', 'messages', 'User'); + + this.isPopoverUserNameDestroyed = false; + + $userName.popover({ + container: 'body', + placement: 'bottom', + content: message, + trigger: 'manual', + }).popover('show'); + + let $cellUserName = $userName.closest('.form-group'); + + $cellUserName.addClass('has-error'); + + $userName.one('mousedown click', () => { + $cellUserName.removeClass('has-error'); + + if (this.isPopoverUserNameDestroyed) { + return; } - if (this.$emailAddress) { - this.$emailAddress.popover('destroy'); - } + $userName.popover('destroy'); + this.isPopoverUserNameDestroyed = true; }); - }, + } - afterRender: function () { - this.$userName = this.$el.find('input[name="username"]'); - this.$emailAddress = this.$el.find('input[name="emailAddress"]'); - }, + if (emailAddress === '') { + isValid = false; - actionSubmit: function () { - let $userName = this.$userName; - let $emailAddress = this.$emailAddress; + let message = this.getLanguage().translate('emailAddressCantBeEmpty', 'messages', 'User'); - let userName = $userName.val(); - let emailAddress = $emailAddress.val(); + this.isPopoverEmailAddressDestroyed = false; - let isValid = true; + $emailAddress.popover({ + container: 'body', + placement: 'bottom', + content: message, + trigger: 'manual', + }).popover('show'); - if (userName === '') { - isValid = false; + let $cellEmailAddress = $emailAddress.closest('.form-group'); - var message = this.getLanguage().translate('userCantBeEmpty', 'messages', 'User'); + $cellEmailAddress.addClass('has-error'); - this.isPopoverUserNameDestroyed = false; + $emailAddress.one('mousedown click', () => { + $cellEmailAddress.removeClass('has-error'); - $userName.popover({ - container: 'body', - placement: 'bottom', - content: message, - trigger: 'manual', - }).popover('show'); + if (this.isPopoverEmailAddressDestroyed) { + return; + } - let $cellUserName = $userName.closest('.form-group'); + $emailAddress.popover('destroy'); - $cellUserName.addClass('has-error'); + this.isPopoverEmailAddressDestroyed = true; + }); + } - $userName.one('mousedown click', () => { - $cellUserName.removeClass('has-error'); + if (!isValid) { + return; + } - if (this.isPopoverUserNameDestroyed) { - return; - } + let $submit = this.$el.find('button[data-name="submit"]'); - $userName.popover('destroy'); - this.isPopoverUserNameDestroyed = true; - }); - } + $submit.addClass('disabled'); - if (emailAddress === '') { - isValid = false; + Espo.Ui.notify(this.translate('pleaseWait', 'messages')); - let message = this.getLanguage().translate('emailAddressCantBeEmpty', 'messages', 'User'); + Espo.Ajax + .postRequest('User/passwordChangeRequest', { + userName: userName, + emailAddress: emailAddress, + url: this.options.url, + }) + .then(() => { + Espo.Ui.notify(false); - this.isPopoverEmailAddressDestroyed = false; + let msg = this.translate('uniqueLinkHasBeenSent', 'messages', 'User'); - $emailAddress.popover({ - container: 'body', - placement: 'bottom', - content: message, - trigger: 'manual', - }).popover('show'); + msg += ' ' + this.translate('passwordRecoverySentIfMatched', 'messages', 'User'); - let $cellEmailAddress = $emailAddress.closest('.form-group'); + this.$el.find('.cell-userName').addClass('hidden'); + this.$el.find('.cell-emailAddress').addClass('hidden'); - $cellEmailAddress.addClass('has-error'); + $submit.addClass('hidden'); - $emailAddress.one('mousedown click', () => { - $cellEmailAddress.removeClass('has-error'); + this.$el.find('.msg-box').removeClass('hidden'); + this.$el.find('.msg-box').html('' + msg + ''); + }) + .catch(xhr => { + if (xhr.status === 404) { + Espo.Ui.error(this.translate('userNameEmailAddressNotFound', 'messages', 'User')); - if (this.isPopoverEmailAddressDestroyed) { - return; - } + xhr.errorIsHandled = true; + } - $emailAddress.popover('destroy'); - this.isPopoverEmailAddressDestroyed = true; - }); - } + if (xhr.status === 403 && xhr.getResponseHeader('X-Status-Reason') === 'Already-Sent') { + Espo.Ui.error(this.translate('forbidden', 'messages', 'User'), true); - if (!isValid) { - return; - } + xhr.errorIsHandled = true; + } - let $submit = this.$el.find('button[data-name="submit"]'); + $submit.removeClass('disabled'); + }); + } +} - $submit.addClass('disabled'); - - Espo.Ui.notify(this.translate('pleaseWait', 'messages')); - - Espo.Ajax - .postRequest('User/passwordChangeRequest', { - userName: userName, - emailAddress: emailAddress, - url: this.options.url, - }) - .then(() => { - Espo.Ui.notify(false); - - let msg = this.translate('uniqueLinkHasBeenSent', 'messages', 'User'); - - msg += ' ' + this.translate('passwordRecoverySentIfMatched', 'messages', 'User'); - - this.$el.find('.cell-userName').addClass('hidden'); - this.$el.find('.cell-emailAddress').addClass('hidden'); - - $submit.addClass('hidden'); - - this.$el.find('.msg-box').removeClass('hidden'); - this.$el.find('.msg-box').html('' + msg + ''); - }) - .catch(xhr => { - if (xhr.status === 404) { - Espo.Ui.error(this.translate('userNameEmailAddressNotFound', 'messages', 'User')); - - xhr.errorIsHandled = true; - } - - if (xhr.status === 403 && xhr.getResponseHeader('X-Status-Reason') === 'Already-Sent') { - Espo.Ui.error(this.translate('forbidden', 'messages', 'User'), true); - - xhr.errorIsHandled = true; - } - - $submit.removeClass('disabled'); - }); - }, - }); -}); +export default PasswordChangeRequestModalView; diff --git a/client/src/views/modals/resolve-save-conflict.js b/client/src/views/modals/resolve-save-conflict.js index 2f6958dfed..d6bd71c83a 100644 --- a/client/src/views/modals/resolve-save-conflict.js +++ b/client/src/views/modals/resolve-save-conflict.js @@ -26,158 +26,158 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/resolve-save-conflict', ['views/modal'], function (Dep) { +import ModalView from 'views/modal'; - return Dep.extend({ +class ResolveSaveConflictModalView extends ModalView { - backdrop: true, + template = 'modals/resolve-save-conflict' - fitHeight: true, + backdrop = true - template: 'modals/resolve-save-conflict', + resolutionList = [ + 'current', + 'actual', + 'original', + ] - resolutionList: [ - 'current', - 'actual', - 'original', - ], + defaultResolution = 'current' - defaultResolution: 'current', + data() { + let dataList = []; - data: function () { - var dataList = []; - - this.fieldList.forEach(item => { - var o = { - field: item, - viewKey: item + 'Field', - resolution: this.defaultResolution, - }; - - dataList.push(o); - }); - - return { - dataList: dataList, - entityType: this.entityType, - resolutionList: this.resolutionList, + this.fieldList.forEach(item => { + let o = { + field: item, + viewKey: item + 'Field', + resolution: this.defaultResolution, }; - }, - setup: function () { - this.headerText = this.translate('Resolve Conflict'); + dataList.push(o); + }); - this.buttonList = [ - { - name: 'apply', - label: 'Apply', - style: 'danger', - }, - { - name: 'cancel', - label: 'Cancel', - }, - ]; + return { + dataList: dataList, + entityType: this.entityType, + resolutionList: this.resolutionList, + }; + } - this.entityType = this.model.entityType; + setup() { + this.headerText = this.translate('Resolve Conflict'); - this.originalModel = this.model; + this.buttonList = [ + { + name: 'apply', + label: 'Apply', + style: 'danger', + }, + { + name: 'cancel', + label: 'Cancel', + }, + ]; - this.originalAttributes = Espo.Utils.cloneDeep(this.options.originalAttributes); - this.currentAttributes = Espo.Utils.cloneDeep(this.options.currentAttributes); - this.actualAttributes = Espo.Utils.cloneDeep(this.options.actualAttributes); + this.entityType = this.model.entityType; - var attributeList = this.options.attributeList; + this.originalModel = this.model; - var fieldList = []; + this.originalAttributes = Espo.Utils.cloneDeep(this.options.originalAttributes); + this.currentAttributes = Espo.Utils.cloneDeep(this.options.currentAttributes); + this.actualAttributes = Espo.Utils.cloneDeep(this.options.actualAttributes); - this.getFieldManager() - .getEntityTypeFieldList(this.entityType) - .forEach(field => { - var fieldAttributeList = this.getFieldManager() - .getEntityTypeFieldAttributeList(this.entityType, field); + let attributeList = this.options.attributeList; - var intersect = attributeList.filter(value => fieldAttributeList.includes(value)); + let fieldList = []; - if (intersect.length) { - fieldList.push(field); - } - }); + this.getFieldManager() + .getEntityTypeFieldList(this.entityType) + .forEach(field => { + let fieldAttributeList = this.getFieldManager() + .getEntityTypeFieldAttributeList(this.entityType, field); - this.fieldList = fieldList; + let intersect = attributeList.filter(value => fieldAttributeList.includes(value)); - this.wait( - this.getModelFactory().create(this.entityType) - .then(model => { - this.model = model; - - this.fieldList.forEach(field => { - this.setResolution(field, this.defaultResolution); - }); - - this.fieldList.forEach(field => { - this.createField(field); - }); - }) - ); - }, - - setResolution: function (field, resolution) { - let attributeList = this.getFieldManager() - .getEntityTypeFieldAttributeList(this.entityType, field); - - let values = {}; - - let source = this.currentAttributes; - - if (resolution === 'actual') { - source = this.actualAttributes; - } - else if (resolution === 'original') { - source = this.originalAttributes; - } - - for (let attribute of attributeList) { - values[attribute] = source[attribute] || null; - } - - this.model.set(values); - }, - - createField: function (field) { - let type = this.model.getFieldType(field); - - let viewName = - this.model.getFieldParam(field, 'view') || - this.getFieldManager().getViewName(type); - - this.createView(field + 'Field', viewName, { - readOnly: true, - model: this.model, - name: field, - el: this.getSelector() + ' [data-name="field"][data-field="' + field + '"]', - mode: 'list', + if (intersect.length) { + fieldList.push(field); + } }); - }, - afterRender: function () { - this.$el.find('[data-name="resolution"]').on('change', e => { - let $el = $(e.currentTarget); + this.fieldList = fieldList; - let field = $el.attr('data-field'); - let resolution = $el.val(); + this.wait( + this.getModelFactory().create(this.entityType) + .then(model => { + this.model = model; - this.setResolution(field, resolution); - }); - }, + this.fieldList.forEach(field => { + this.setResolution(field, this.defaultResolution); + }); - actionApply: function () { - let attributes = this.model.attributes; + this.fieldList.forEach(field => { + this.createField(field); + }); + }) + ); + } - this.originalModel.set(attributes); + setResolution(field, resolution) { + let attributeList = this.getFieldManager() + .getEntityTypeFieldAttributeList(this.entityType, field); - this.trigger('resolve'); - this.close(); - }, - }); -}); + let values = {}; + + let source = this.currentAttributes; + + if (resolution === 'actual') { + source = this.actualAttributes; + } + else if (resolution === 'original') { + source = this.originalAttributes; + } + + for (let attribute of attributeList) { + values[attribute] = source[attribute] || null; + } + + this.model.set(values); + } + + createField(field) { + let type = this.model.getFieldType(field); + + let viewName = + this.model.getFieldParam(field, 'view') || + this.getFieldManager().getViewName(type); + + this.createView(field + 'Field', viewName, { + readOnly: true, + model: this.model, + name: field, + el: this.getSelector() + ' [data-name="field"][data-field="' + field + '"]', + mode: 'list', + }); + } + + afterRender() { + this.$el.find('[data-name="resolution"]').on('change', e => { + let $el = $(e.currentTarget); + + let field = $el.attr('data-field'); + let resolution = $el.val(); + + this.setResolution(field, resolution); + }); + } + + // noinspection JSUnusedGlobalSymbols + actionApply() { + let attributes = this.model.attributes; + + this.originalModel.set(attributes); + + this.trigger('resolve'); + this.close(); + } +} + +export default ResolveSaveConflictModalView; diff --git a/client/src/views/modals/save-filters.js b/client/src/views/modals/save-filters.js index e9b97e6d54..57daa900c1 100644 --- a/client/src/views/modals/save-filters.js +++ b/client/src/views/modals/save-filters.js @@ -26,63 +26,72 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/save-filters', ['views/modal', 'model'], function (Dep, Model) { +import ModalView from 'views/modal'; +import Model from 'model'; - return Dep.extend({ +class SaveFiltersModalView extends ModalView { - cssName: 'save-filters', + template = 'modals/save-filters' - template: 'modals/save-filters', + cssName = 'save-filters' - data: function () { - return { - dashletList: this.dashletList, - }; - }, + data() { + return { + dashletList: this.dashletList, + }; + } - setup: function () { - this.buttonList = [ - { - name: 'save', - label: 'Save', - style: 'primary' - }, - { - name: 'cancel', - label: 'Cancel' + setup() { + this.buttonList = [ + { + name: 'save', + label: 'Save', + style: 'primary', + }, + { + name: 'cancel', + label: 'Cancel', + }, + ]; + + this.headerText = this.translate('Save Filter'); + + let model = new Model(); + + this.createView('name', 'views/fields/varchar', { + el: this.options.el + ' .field[data-name="name"]', + defs: { + name: 'name', + params: { + required: true } - ]; + }, + mode: 'edit', + model: model, + }); + } - this.headerText = this.translate('Save Filter'); + /** + * @param {string} field + * @return {module:views/fields/base} + */ + getFieldView(field) { + return this.getView(field); + } - var model = new Model(); + actionSave() { + let nameView = this.getFieldView('name'); - this.createView('name', 'views/fields/varchar', { - el: this.options.el + ' .field[data-name="name"]', - defs: { - name: 'name', - params: { - required: true - } - }, - mode: 'edit', - model: model, - }); - }, + nameView.fetchToModel(); - actionSave: function () { - var nameView = this.getView('name'); - nameView.fetchToModel(); + if (nameView.validate()) { + return; + } - if (nameView.validate()) { - return; - } - - this.trigger('save', nameView.model.get('name')); - - return true; - }, - }); -}); + this.trigger('save', nameView.model.get('name')); + return true; + } +} +export default SaveFiltersModalView; diff --git a/client/src/views/modals/select-category-tree-records.js b/client/src/views/modals/select-category-tree-records.js index 5a794fa4b0..6c106d2714 100644 --- a/client/src/views/modals/select-category-tree-records.js +++ b/client/src/views/modals/select-category-tree-records.js @@ -26,124 +26,126 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/select-category-tree-records', ['views/modals/select-records'], function (Dep) { +import SelectRecordsModalView from 'views/modals/select-records'; - return Dep.extend({ +class SelectCategoryTreeRecordsModalView extends SelectRecordsModalView { - setup: function () { - this.filters = this.options.filters || {}; - this.boolFilterList = this.options.boolFilterList || {}; - this.primaryFilterName = this.options.primaryFilterName || null; + setup() { + this.filters = this.options.filters || {}; + this.boolFilterList = this.options.boolFilterList || {}; + this.primaryFilterName = this.options.primaryFilterName || null; - if ('multiple' in this.options) { - this.multiple = this.options.multiple; + if ('multiple' in this.options) { + this.multiple = this.options.multiple; + } + + this.createButton = false; + this.massRelateEnabled = this.options.massRelateEnabled; + + this.buttonList = [ + { + name: 'cancel', + label: 'Cancel' } + ]; - this.createButton = false; - this.massRelateEnabled = this.options.massRelateEnabled; + if (this.multiple) { + this.buttonList.unshift({ + name: 'select', + style: 'danger', + label: 'Select', + onClick: dialog => { + let listView = this.getRecordView(); - this.buttonList = [ - { - name: 'cancel', - label: 'Cancel' + if (listView.allResultIsChecked) { + this.trigger('select', { + massRelate: true, + where: this.collection.getWhere(), + searchParams: this.collection.data, + }); + } + else { + var list = listView.getSelected(); + if (list.length) { + this.trigger('select', list); + } + } + + dialog.close(); + }, + }); + } + + this.scope = this.options.scope; + + this.$header = $(''); + + this.$header.append( + $('').text( + this.translate('Select') + ': ' + + this.getLanguage().translate(this.scope, 'scopeNamesPlural') + ) + ); + + this.$header.prepend( + this.getHelper().getScopeColorIconHtml(this.scope) + ); + + this.waitForView('list'); + + Espo.loader.require('search-manager', SearchManager => { + this.getCollectionFactory().create(this.scope, collection => { + collection.maxSize = this.getConfig().get('recordsPerPageSelect') || 5; + + this.collection = collection; + + var searchManager = new SearchManager(collection, 'listSelect', null, this.getDateTime()); + + searchManager.emptyOnReset = true; + + if (this.filters) { + searchManager.setAdvanced(this.filters); } - ]; - if (this.multiple) { - this.buttonList.unshift({ - name: 'select', - style: 'danger', - label: 'Select', - onClick: (dialog) => { - var listView = this.getView('list'); + if (this.boolFilterList) { + searchManager.setBool(this.boolFilterList); + } - if (listView.allResultIsChecked) { - this.trigger('select', { - massRelate: true, - where: this.collection.getWhere(), - searchParams: this.collection.data, - }); - } - else { - var list = listView.getSelected(); - if (list.length) { - this.trigger('select', list); - } - } + if (this.primaryFilterName) { + searchManager.setPrimary(this.primaryFilterName); + } - dialog.close(); - }, - }); - } + collection.where = searchManager.getWhere(); + collection.url = collection.entityType + '/action/listTree'; - this.scope = this.options.scope; + var viewName = this.getMetadata() + .get('clientDefs.' + this.scope + '.recordViews.listSelectCategoryTree') || + 'views/record/list-tree'; - this.$header = $(''); - - this.$header.append( - $('').text( - this.translate('Select') + ': ' + - this.getLanguage().translate(this.scope, 'scopeNamesPlural') - ) - ); - - this.$header.prepend( - this.getHelper().getScopeColorIconHtml(this.scope) - ); - - this.waitForView('list'); - - Espo.loader.require('search-manager', SearchManager => { - this.getCollectionFactory().create(this.scope, collection => { - collection.maxSize = this.getConfig().get('recordsPerPageSelect') || 5; - - this.collection = collection; - - var searchManager = new SearchManager(collection, 'listSelect', null, this.getDateTime()); - - searchManager.emptyOnReset = true; - - if (this.filters) { - searchManager.setAdvanced(this.filters); - } - - if (this.boolFilterList) { - searchManager.setBool(this.boolFilterList); - } - - if (this.primaryFilterName) { - searchManager.setPrimary(this.primaryFilterName); - } - - collection.where = searchManager.getWhere(); - collection.url = collection.entityType + '/action/listTree'; - - var viewName = this.getMetadata() - .get('clientDefs.' + this.scope + '.recordViews.listSelectCategoryTree') || - 'views/record/list-tree'; - - this.listenToOnce(collection, 'sync', () => { - this.createView('list', viewName, { - collection: collection, - el: this.containerSelector + ' .list-container', - readOnly: true, - selectable: true, - checkboxes: this.multiple, - massActionsDisabled: true, - searchManager: searchManager, - checkAllResultDisabled: true, - buttonsDisabled: true, - }, listView => { - listView.once('select', model => { - this.trigger('select', model); - this.close(); - }); + this.listenToOnce(collection, 'sync', () => { + this.createView('list', viewName, { + collection: collection, + el: this.containerSelector + ' .list-container', + readOnly: true, + selectable: true, + checkboxes: this.multiple, + massActionsDisabled: true, + searchManager: searchManager, + checkAllResultDisabled: true, + buttonsDisabled: true, + }, listView => { + listView.once('select', model => { + this.trigger('select', model); + this.close(); }); }); - - collection.fetch(); }); + + collection.fetch(); }); - }, - }); -}); + }); + } +} + +// noinspection JSUnusedGlobalSymbols +export default SelectCategoryTreeRecordsModalView; diff --git a/client/src/views/modals/select-records-with-categories.js b/client/src/views/modals/select-records-with-categories.js index 34f01b99cc..2d5e95853a 100644 --- a/client/src/views/modals/select-records-with-categories.js +++ b/client/src/views/modals/select-records-with-categories.js @@ -29,7 +29,7 @@ import SelectRecordsModal from 'views/modals/select-records'; import ListWithCategories from 'views/list-with-categories'; -class SelectRecordsWithCategoriesModal extends SelectRecordsModal { +class SelectRecordsWithCategoriesModalView extends SelectRecordsModal { template = 'modals/select-records-with-categories' @@ -117,9 +117,11 @@ class SelectRecordsWithCategoriesModal extends SelectRecordsModal { ListWithCategories.prototype.applyCategoryToCollection.call(this); } + // noinspection JSUnusedGlobalSymbols isCategoryMultiple() { ListWithCategories.prototype.isCategoryMultiple.call(this); } } -export default SelectRecordsWithCategoriesModal; +// noinspection JSUnusedGlobalSymbols +export default SelectRecordsWithCategoriesModalView; diff --git a/client/src/views/modals/select-records.js b/client/src/views/modals/select-records.js index e166bf2309..1ea208b4d2 100644 --- a/client/src/views/modals/select-records.js +++ b/client/src/views/modals/select-records.js @@ -34,14 +34,13 @@ import SearchManager from 'search-manager'; /** * A select-records modal. */ -class SelectRecordsModal extends ModalView { +class SelectRecordsModalView extends ModalView { template = 'modals/select-records' cssName = 'select-modal' className = 'dialog dialog-record' multiple = false - header = false createButton = true searchPanel = true scope = '' @@ -49,34 +48,34 @@ class SelectRecordsModal extends ModalView { /** @inheritDoc */ shortcutKeys = { - /** @this SelectRecordsModal */ + /** @this SelectRecordsModalView */ 'Control+Enter': function (e) { this.handleShortcutKeyCtrlEnter(e); }, - /** @this SelectRecordsModal */ + /** @this SelectRecordsModalView */ 'Control+Space': function (e) { this.handleShortcutKeyCtrlSpace(e); }, - /** @this SelectRecordsModal */ + /** @this SelectRecordsModalView */ 'Control+Slash': function (e) { this.handleShortcutKeyCtrlSlash(e); }, - /** @this SelectRecordsModal */ + /** @this SelectRecordsModalView */ 'Control+Comma': function (e) { this.handleShortcutKeyCtrlComma(e); }, - /** @this SelectRecordsModal */ + /** @this SelectRecordsModalView */ 'Control+Period': function (e) { this.handleShortcutKeyCtrlPeriod(e); }, } events = { - /** @this SelectRecordsModal */ + /** @this SelectRecordsModalView */ 'click button[data-action="create"]': function () { this.create(); }, - /** @this SelectRecordsModal */ + /** @this SelectRecordsModalView */ 'click .list a': function (e) { e.preventDefault(); }, @@ -459,9 +458,8 @@ class SelectRecordsModal extends ModalView { /** * @protected - * @param {JQueryKeyEventObject} e */ - handleShortcutKeyCtrlComma(e) { + handleShortcutKeyCtrlComma() { if (!this.getSearchView()) { return; } @@ -471,9 +469,8 @@ class SelectRecordsModal extends ModalView { /** * @protected - * @param {JQueryKeyEventObject} e */ - handleShortcutKeyCtrlPeriod(e) { + handleShortcutKeyCtrlPeriod() { if (!this.getSearchView()) { return; } @@ -482,4 +479,4 @@ class SelectRecordsModal extends ModalView { } } -export default SelectRecordsModal; +export default SelectRecordsModalView; diff --git a/client/src/views/modals/select-template.js b/client/src/views/modals/select-template.js index 4219f97665..e593e31297 100644 --- a/client/src/views/modals/select-template.js +++ b/client/src/views/modals/select-template.js @@ -26,43 +26,38 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/select-template', ['views/modals/select-records'], function (Dep) { +import SelectRecordsModalView from 'views/modals/select-records'; - return Dep.extend({ +class SelectTemplateModalView extends SelectRecordsModalView { - multiple: false, + multiple = false + createButton = false + searchPanel = false + scope = 'Template' - createButton: false, + loadSearch() { + super.loadSearch(); - searchPanel: false, + this.searchManager.setAdvanced({ + entityType: { + type: 'equals', + value: this.options.entityType, + }, + }); - scope: 'Template', + this.collection.where = this.searchManager.getWhere(); + } - setup: function () { - Dep.prototype.setup.call(this); - }, + afterRender() { + super.afterRender(); - loadSearch: function () { - Dep.prototype.loadSearch.call(this); + let firstLinkElement = this.$el.find('a.link').first().get(0); - this.searchManager.setAdvanced({ - entityType: { - type: 'equals', - value: this.options.entityType, - } - }); + if (firstLinkElement) { + // noinspection JSUnresolvedReference + setTimeout(() => firstLinkElement.focus({preventScroll: true}), 10); + } + } +} - this.collection.where = this.searchManager.getWhere(); - }, - - afterRender: function () { - Dep.prototype.afterRender.call(this); - - let firstLinkElement = this.$el.find('a.link').first().get(0); - - if (firstLinkElement) { - setTimeout(() => firstLinkElement.focus({preventScroll: true}), 10); - } - }, - }); -}); +export default SelectTemplateModalView; diff --git a/client/src/views/modals/view-map.js b/client/src/views/modals/view-map.js index d39b368f7f..a032ee93f6 100644 --- a/client/src/views/modals/view-map.js +++ b/client/src/views/modals/view-map.js @@ -26,46 +26,36 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -define('views/modals/view-map', ['views/modal'], function (Dep) { +import ModalView from 'views/modal'; - return Dep.extend({ +class ViewMapModalView extends ModalView { - backdrop: true, + templateContent = `
{{{map}}}
` - fitHeight: true, + backdrop = true - templateContent: '
{{{map}}}
', + setup() { + let field = this.options.field; - setup: function () { - this.buttonList = [ - { - name: 'close', - label: 'Close', - } - ]; - }, + let url = '#AddressMap/view/' + this.model.entityType + '/' + this.model.id + '/' + field; + let fieldLabel = this.translate(field, 'fields', this.model.entityType); - setup: function () { - let field = this.options.field; + this.headerElement = + $('
') + .attr('href', '#' + url) + .text(fieldLabel) + .get(0); - let url = '#AddressMap/view/' + this.model.entityType + '/' + this.model.id + '/' + field; - let fieldLabel = this.translate(field, 'fields', this.model.entityType); + let viewName = this.model.getFieldParam(field + 'Map', 'view') || + this.getFieldManager().getViewName('map'); - this.headerElement = - $('') - .attr('href', '#' + url) - .text(fieldLabel) - .get(0); + this.createView('map', viewName, { + model: this.model, + name: field + 'Map', + el: this.getSelector() + ' .map-container', + height: 'auto', + }); + } +} - let viewName = this.model.getFieldParam(field + 'Map', 'view') || - this.getFieldManager().getViewName('map'); - - this.createView('map', viewName, { - model: this.model, - name: field + 'Map', - el: this.getSelector() + ' .map-container', - height: 'auto', - }); - }, - }); -}); +export default ViewMapModalView;