diff --git a/frontend/client/modules/crm/src/views/lead/record/panels/converted-to.js b/frontend/client/modules/crm/src/views/lead/record/panels/converted-to.js index 0e36e1aa85..80da26434c 100644 --- a/frontend/client/modules/crm/src/views/lead/record/panels/converted-to.js +++ b/frontend/client/modules/crm/src/views/lead/record/panels/converted-to.js @@ -30,7 +30,7 @@ Espo.define('crm:views/lead/record/panels/converted-to', 'views/record/panels/si return Dep.extend({ - setup: function () { + setupFields: function () { this.fieldList = []; if (this.getAcl().check('Account') && !this.getMetadata().get('scopes.Account.disabled')) { @@ -43,8 +43,6 @@ Espo.define('crm:views/lead/record/panels/converted-to', 'views/record/panels/si if (this.getAcl().check('Opportunity') && !this.getMetadata().get('scopes.Opportunity.disabled')) { this.fieldList.push('createdOpportunity'); } - - Dep.prototype.setup.call(this); } }); diff --git a/frontend/client/modules/crm/src/views/meeting/record/panels/attendees.js b/frontend/client/modules/crm/src/views/meeting/record/panels/attendees.js index aa02dc2a98..c730da7872 100644 --- a/frontend/client/modules/crm/src/views/meeting/record/panels/attendees.js +++ b/frontend/client/modules/crm/src/views/meeting/record/panels/attendees.js @@ -30,7 +30,7 @@ Espo.define('crm:views/meeting/record/panels/attendees', 'views/record/panels/si return Dep.extend({ - setup: function () { + setupFields: function () { this.fieldList = []; this.fieldList.push('users'); @@ -41,8 +41,6 @@ Espo.define('crm:views/meeting/record/panels/attendees', 'views/record/panels/si if (this.getAcl().check('Lead') && !this.getMetadata().get('scopes.Lead.disabled')) { this.fieldList.push('leads'); } - - Dep.prototype.setup.call(this); } }); diff --git a/frontend/client/src/view-record-helper.js b/frontend/client/src/view-record-helper.js index 2b280de280..54baa42253 100644 --- a/frontend/client/src/view-record-helper.js +++ b/frontend/client/src/view-record-helper.js @@ -28,10 +28,10 @@ Espo.define('view-record-helper', [], function () { var ViewRecordHelper = function (defaultFieldStates, defaultPanelStates) { - if (this.defaultFieldStates) { + if (defaultFieldStates) { this.defaultFieldStates = defaultFieldStates; } - if (this.defaultPanelStates) { + if (defaultPanelStates) { this.defaultPanelStates = defaultPanelStates; } this.fieldStateMap = {}; @@ -43,14 +43,9 @@ Espo.define('view-record-helper', [], function () { _.extend(ViewRecordHelper.prototype, { - defaultFieldStates: { - hidden: false, - readOnly: false - }, + defaultFieldStates: {}, - defaultPanelStates: { - hidden: false - }, + defaultPanelStates: {}, getHiddenFields: function () { return this.hiddenFields; @@ -79,10 +74,9 @@ Espo.define('view-record-helper', [], function () { if (name in this.fieldStateMap[field]) { return this.fieldStateMap[field][name]; } - } else { - if (name in this.defaultFieldStates) { - return this.defaultFieldStates[name]; - } + } + if (name in this.defaultFieldStates) { + return this.defaultFieldStates[name]; } return null; }, @@ -106,10 +100,9 @@ Espo.define('view-record-helper', [], function () { if (name in this.panelStateMap[panel]) { return this.panelStateMap[panel][name]; } - } else { - if (name in this.defaultPanelStates) { - return this.defaultPanelStates[name]; - } + } + if (name in this.defaultPanelStates) { + return this.defaultPanelStates[name]; } return null; } diff --git a/frontend/client/src/views/record/base.js b/frontend/client/src/views/record/base.js index 3ba1b56a74..912d631df7 100644 --- a/frontend/client/src/views/record/base.js +++ b/frontend/client/src/views/record/base.js @@ -42,15 +42,6 @@ Espo.define('views/record/base', ['view', 'view-record-helper'], function (Dep, fieldList: null, - defaultFieldStates: { - hidden: false, - readOnly: false - }, - - defaultPanelStates: { - hidden: false - }, - hideField: function (name) { this.recordHelper.setFieldStateParam(name, 'hidden', true); @@ -206,7 +197,7 @@ Espo.define('views/record/base', ['view', 'view-record-helper'], function (Dep, throw new Error('Model has not been injected into record view.'); } - this.recordHelper = new ViewRecordHelper(this.defaultFieldStates, this.defaultFieldStates); + this.recordHelper = new ViewRecordHelper(); this.on('remove', function () { if (this.isChanged) { diff --git a/frontend/client/src/views/record/detail-bottom.js b/frontend/client/src/views/record/detail-bottom.js index e1e658f01a..a8eeddfe52 100644 --- a/frontend/client/src/views/record/detail-bottom.js +++ b/frontend/client/src/views/record/detail-bottom.js @@ -79,6 +79,7 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) { var view = this.getView(name); if (view) { view.$el.closest('.panel').removeClass('hidden'); + view.disabled = false; } if (callback) { callback.call(this); @@ -108,6 +109,7 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) { var view = this.getView(name); if (view) { view.$el.closest('.panel').addClass('hidden'); + view.disabled = true; } if (callback) { callback.call(this); @@ -124,40 +126,34 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) { setupPanels: function () { var scope = this.scope; - this.recordHelper = this.options.recordHelper; - - var panelList = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + scope + '.bottomPanels.' + this.mode) || []); + this.panelList = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + scope + '.bottomPanels.' + this.mode) || this.panelList || []); if (this.streamPanel && this.getMetadata().get('scopes.' + scope + '.stream')) { - var streamAllowed = this.getAcl().checkModel(this.model, 'stream'); - if (streamAllowed === null) { - this.listenToOnce(this.model, 'sync', function () { - streamAllowed = this.getAcl().checkModel(this.model, 'stream'); - if (streamAllowed) { - this.showPanel('stream', function () { - this.getView('stream').collection.fetch(); - }); - } - }, this); - } - if (streamAllowed !== false) { - panelList.push({ - "name":"stream", - "label":"Stream", - "view":"views/stream/panel", - "sticked": true, - "hidden": !streamAllowed - }); - } + this.setupStreamPanel(); } + }, - this.panelList = this.panelList.map(function (p) { - var item = Espo.Utils.clone(p); - if (this.recordHelper.getPanelStateParam(p.name, 'hidden') !== null) { - item.hidden = this.recordHelper.getPanelStateParam(p.name, 'hidden'); - } - return item; - }, this); + setupStreamPanel: function () { + var streamAllowed = this.getAcl().checkModel(this.model, 'stream'); + if (streamAllowed === null) { + this.listenToOnce(this.model, 'sync', function () { + streamAllowed = this.getAcl().checkModel(this.model, 'stream'); + if (streamAllowed) { + this.showPanel('stream', function () { + this.getView('stream').collection.fetch(); + }); + } + }, this); + } + if (streamAllowed !== false) { + this.panelList.push({ + "name":"stream", + "label":"Stream", + "view":"views/stream/panel", + "sticked": true, + "hidden": !streamAllowed + }); + } }, setupPanelViews: function () { @@ -169,7 +165,8 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) { el: this.options.el + ' .panel[data-name="' + name + '"] > .panel-body', defs: p, mode: this.mode, - recordHelper: this.recordHelper + recordHelper: this.recordHelper, + disabled: p.hidden || false }, function (view) { if ('getActionList' in view) { p.actionList = this.filterActions(view.getActionList()); @@ -186,15 +183,29 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) { }, this); }, + init: function () { + this.recordHelper = this.options.recordHelper; + this.scope = this.model.name; + }, + setup: function () { this.panelList = []; - this.scope = this.model.name; + + this.setupPanels(); + + this.panelList = this.panelList.map(function (p) { + var item = Espo.Utils.clone(p); + if (this.recordHelper.getPanelStateParam(p.name, 'hidden') !== null) { + item.hidden = this.recordHelper.getPanelStateParam(p.name, 'hidden'); + } else { + this.recordHelper.setPanelStateParam(p.name, item.hidden || false); + } + return item; + }, this); this.wait(true); var proceed = function () { - this.setupPanels(); - this.panelList = this.panelList.filter(function (p) { if (p.aclScope) { if (!this.getAcl().checkScope(p.aclScope)) { @@ -268,12 +279,16 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) { p = _.extend(p, defs); + if (this.recordHelper.getPanelStateParam(p.name, 'hidden') !== null) { + p.hidden = this.recordHelper.getPanelStateParam(p.name, 'hidden'); + } else { + this.recordHelper.setPanelStateParam(p.name, p.hidden || false); + } + this.panelList.push(p); }, this); - }, - filterActions: function (actions) { var filtered = []; actions.forEach(function (item) { diff --git a/frontend/client/src/views/record/detail-middle.js b/frontend/client/src/views/record/detail-middle.js new file mode 100644 index 0000000000..a419efd939 --- /dev/null +++ b/frontend/client/src/views/record/detail-middle.js @@ -0,0 +1,61 @@ +/************************************************************************ + * This file is part of EspoCRM. + * + * EspoCRM - Open Source CRM application. + * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko + * Website: http://www.espocrm.com + * + * EspoCRM is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * EspoCRM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with EspoCRM. If not, see http://www.gnu.org/licenses/. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU General Public License version 3. + * + * In accordance with Section 7(b) of the GNU General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +Espo.define('views/record/detail-middle', 'view', function (Dep) { + + return Dep.extend({ + + init: function () { + this.recordHelper = this.options.recordHelper; + this.scope = this.model.name; + }, + + data: function () { + return { + hiddenPanels: this.recordHelper.getHiddenPanels(), + hiddenFields: this.recordHelper.getHiddenFields() + }; + }, + + showPanel: function (name) { + if (this.isRendered()) { + this.$el.find('.panel[data-name="'+name+'"]').removeClass('hidden'); + } + this.recordHelper.setPanelStateParam(name, 'hidden', false); + }, + + hidePanel: function (name) { + if (this.isRendered()) { + this.$el.find('.panel[data-name="'+name+'"]').addClass('hidden'); + } + this.recordHelper.setPanelStateParam(name, 'hidden', true); + } + }); +}); + + diff --git a/frontend/client/src/views/record/detail-side.js b/frontend/client/src/views/record/detail-side.js index 92cb482f62..e84a21d13c 100644 --- a/frontend/client/src/views/record/detail-side.js +++ b/frontend/client/src/views/record/detail-side.js @@ -89,9 +89,6 @@ Espo.define('views/record/detail-side', 'view', function (Dep) { this.panelList = this.options.panelList || this.panelList; this.scope = this.options.model.name; - this.panelStateMap = this.options.panelStateMap; - this.fieldStateMap = this.options.fieldStateMap; - this.recordHelper = this.options.recordHelper; this.panelList = _.clone(this.panelList); @@ -108,7 +105,6 @@ Espo.define('views/record/detail-side', 'view', function (Dep) { }, setupPanels: function () { - }, setup: function () { @@ -137,10 +133,16 @@ Espo.define('views/record/detail-side', 'view', function (Dep) { var item = Espo.Utils.clone(p); if (this.recordHelper.getPanelStateParam(p.name, 'hidden') !== null) { item.hidden = this.recordHelper.getPanelStateParam(p.name, 'hidden'); + } else { + this.recordHelper.setPanelStateParam(p.name, item.hidden || false); } return item; }, this); + this.setupPanelViews(); + }, + + setupPanelViews: function () { this.panelList.forEach(function (p) { var o = { model: this.options.model, @@ -149,7 +151,8 @@ Espo.define('views/record/detail-side', 'view', function (Dep) { inlineEditDisabled: this.inlineEditDisabled, mode: this.mode, recordHelper: this.recordHelper, - defs: p + defs: p, + disabled: p.hidden || false }; o = _.extend(o, p.options); this.createView(p.name, p.view, o, function (view) { @@ -217,6 +220,7 @@ Espo.define('views/record/detail-side', 'view', function (Dep) { var view = this.getView(name); if (view) { view.$el.closest('.panel').removeClass('hidden'); + view.disabled = false; } if (callback) { callback.call(this); @@ -246,6 +250,7 @@ Espo.define('views/record/detail-side', 'view', function (Dep) { var view = this.getView(name); if (view) { view.$el.closest('.panel').addClass('hidden'); + view.disabled = true; } if (callback) { callback.call(this); diff --git a/frontend/client/src/views/record/detail.js b/frontend/client/src/views/record/detail.js index 4329c4f66d..85651e4e12 100644 --- a/frontend/client/src/views/record/detail.js +++ b/frontend/client/src/views/record/detail.js @@ -91,6 +91,8 @@ Espo.define('views/record/detail', ['views/record/base', 'view-record-helper'], returnDispatchParams: null, + middleView: 'views/record/detail-middle', + sideView: 'views/record/detail-side', bottomView: 'views/record/detail-bottom', @@ -164,9 +166,7 @@ Espo.define('views/record/detail', ['views/record/base', 'view-record-helper'], var middleView = this.getView('middle'); if (middleView) { - if (this.isRendered()) { - middleView.$el.find('.panel[data-name="'+name+'"]').removeClass('hidden'); - } + middleView.showPanel(name); } var bottomView = this.getView('bottom'); @@ -189,9 +189,7 @@ Espo.define('views/record/detail', ['views/record/base', 'view-record-helper'], var middleView = this.getView('middle'); if (middleView) { - if (this.isRendered()) { - middleView.$el.find('.panel[data-name="'+name+'"]').addClass('hidden'); - } + middleView.hidePanel(name); } var bottomView = this.getView('bottom'); @@ -569,7 +567,6 @@ Espo.define('views/record/detail', ['views/record/base', 'view-record-helper'], this.build(); - if (this.duplicateAction) { if (this.getAcl().checkModel(this.model, 'edit')) { this.dropdownItemList.push({ @@ -849,26 +846,23 @@ Espo.define('views/record/detail', ['views/record/base', 'view-record-helper'], }.bind(this)); }, - build: function (callback) { - this.waitForView('middle'); - - var self = this; - + createSideView: function () { var el = this.options.el || '#' + (this.id); + this.createView('side', this.sideView, { + model: this.model, + el: el + ' .side', + type: this.type, + readOnly: this.readOnly, + inlineEditDisabled: this.inlineEditDisabled, + recordHelper: this.recordHelper + }); + }, - if (this.sideView) { - this.createView('side', this.sideView, { - model: this.model, - el: el + ' .side', - type: this.type, - readOnly: this.readOnly, - inlineEditDisabled: this.inlineEditDisabled, - recordHelper: this.recordHelper - }); - } - + createMiddleView: function (callback) { + var el = this.options.el || '#' + (this.id); + this.waitForView('middle'); this.getGridLayout(function (layout) { - this.createView('middle', 'Base', { + this.createView('middle', this.middleView, { model: this.model, _layout: layout, el: el + ' .middle', @@ -876,30 +870,40 @@ Espo.define('views/record/detail', ['views/record/base', 'view-record-helper'], model: this.model, columnCount: this.columnCount }, - data: function () { - return { - hiddenPanels: this.recordHelper.getHiddenPanels(), - hiddenFields: this.recordHelper.getHiddenFields() - } - }.bind(this) + recordHelper: this.recordHelper }, callback); }.bind(this)); + }, + createBottomView: function () { + var el = this.options.el || '#' + (this.id); + this.createView('bottom', this.bottomView, { + model: this.model, + el: el + ' .bottom', + notToRender: true, + readOnly: this.readOnly, + inlineEditDisabled: this.inlineEditDisabled, + recordHelper: this.recordHelper + }, function (view) { + if (this.isRendered()) { + view.render(); + } + }, this, false); + }, + + build: function (callback) { + if (this.sideView) { + this.createSideView(); + } + + if (this.middleView) { + this.createMiddleView(callback); + } if (this.bottomView) { this.once('after:render', function () { - this.createView('bottom', this.bottomView, { - model: this.model, - el: el + ' .bottom', - notToRender: true, - readOnly: this.readOnly, - inlineEditDisabled: this.inlineEditDisabled, - recordHelper: this.recordHelper - }, function (view) { - view.render(); - }, this, false); + this.createBottomView(); }, this); - } }, diff --git a/frontend/client/src/views/record/panels/bottom.js b/frontend/client/src/views/record/panels/bottom.js index 357ebd810c..e328867dd8 100644 --- a/frontend/client/src/views/record/panels/bottom.js +++ b/frontend/client/src/views/record/panels/bottom.js @@ -42,6 +42,8 @@ Espo.define('views/record/panels/bottom', 'view', function (Dep) { fieldList: null, + disabled: false, + events: { 'click .action': function (e) { var $el = $(e.currentTarget); @@ -69,12 +71,20 @@ Espo.define('views/record/panels/bottom', 'view', function (Dep) { this.defs = this.options.defs || {}; this.recordHelper = this.options.recordHelper; + if ('disabled' in this.options) { + this.disabled = this.options.disabled; + } + this.mode = this.options.mode || this.mode; this.buttonList = _.clone(this.defs.buttonList || this.buttonList || []); this.actionList = _.clone(this.defs.actionList || this.actionList || []); this.fieldList = this.options.fieldList || this.fieldList || []; + }, + + setup: function () { + this.setupFields(); this.fieldList = this.fieldList.map(function (d) { var item = d; @@ -87,19 +97,22 @@ Espo.define('views/record/panels/bottom', 'view', function (Dep) { if (this.recordHelper.getFieldStateParam(item.name, 'hidden') !== null) { item.hidden = this.recordHelper.getFieldStateParam(item.name, 'hidden'); + } else { + this.recordHelper.setFieldStateParam(item.name, item.hidden || false); } return item; }, this); this.fieldList = this.fieldList.filter(function (item) { if (!item.name) return; - if (!(item.name in ((this.model.defs || {}).fields) || {})) return; + if (!(item.name in (((this.model.defs || {}).fields) || {}))) return; return true; }, this); + + this.createFields(); }, - setup: function () { - + setupFields: function () { }, getButtonList: function () { diff --git a/frontend/client/src/views/record/panels/relationship.js b/frontend/client/src/views/record/panels/relationship.js index 04422f47f5..5e0b8b9426 100644 --- a/frontend/client/src/views/record/panels/relationship.js +++ b/frontend/client/src/views/record/panels/relationship.js @@ -45,6 +45,8 @@ Espo.define('views/record/panels/relationship', ['views/record/panels/bottom', ' }, setup: function () { + Dep.prototype.setup.call(this); + this.link = this.panelName; if (!this.scope && !(this.link in this.model.defs.links)) { diff --git a/frontend/client/src/views/record/panels/side.js b/frontend/client/src/views/record/panels/side.js index cc2bbaf594..8d7436bd1f 100644 --- a/frontend/client/src/views/record/panels/side.js +++ b/frontend/client/src/views/record/panels/side.js @@ -64,18 +64,40 @@ Espo.define('views/record/panels/side', 'view', function (Dep) { inlineEditDisabled: false, + disabled: false, + init: function () { this.panelName = this.options.panelName; this.defs = this.options.defs || {}; this.recordHelper = this.options.recordHelper; + if ('disabled' in this.options) { + this.disabled = this.options.disabled; + } + this.buttonList = _.clone(this.defs.buttonList || this.buttonList || []); this.actionList = _.clone(this.defs.actionList || this.actionList || []); this.fieldList = this.options.fieldList || this.fieldList || []; + + this.mode = this.options.mode || this.mode; + + if (!this.readOnly) { + if ('readOnly' in this.options) { + this.readOnly = this.options.readOnly; + } + } + + if (!this.inlineEditDisabled) { + if ('inlineEditDisabled' in this.options) { + this.inlineEditDisabled = this.options.inlineEditDisabled; + } + } }, setup: function () { + this.setupFields(); + this.fieldList = this.fieldList.map(function (d) { var item = d; if (typeof item !== 'object') { @@ -87,30 +109,25 @@ Espo.define('views/record/panels/side', 'view', function (Dep) { if (this.recordHelper.getFieldStateParam(item.name, 'hidden') !== null) { item.hidden = this.recordHelper.getFieldStateParam(item.name, 'hidden'); + } else { + this.recordHelper.setFieldStateParam(item.name, item.hidden || false); } return item; }, this); this.fieldList = this.fieldList.filter(function (item) { if (!item.name) return; - if (!(item.name in ((this.model.defs || {}).fields) || {})) return; + if (!(item.name in (((this.model.defs || {}).fields) || {}))) return; return true; }, this); - this.mode = this.options.mode || this.mode; - if (!this.readOnly) { - if ('readOnly' in this.options) { - this.readOnly = this.options.readOnly; - } - } - if (!this.inlineEditDisabled) { - if ('inlineEditDisabled' in this.options) { - this.inlineEditDisabled = this.options.inlineEditDisabled; - } - } + this.createFields(); }, + setupFields: function () { + }, + createField: function (field, readOnly, viewName) { var type = this.model.getFieldType(field) || 'base'; viewName = viewName || this.model.getFieldParam(field, 'view') || this.getFieldManager().getViewName(type);