File: /home/barbeatleanalyti/www/public_html/webmail/modules/AdminPanelWebclient/js/views/SettingsView.js
'use strict';
var
_ = require('underscore'),
$ = require('jquery'),
ko = require('knockout'),
Promise = require("bluebird"),
Text = require('%PathToCoreWebclientModule%/js/utils/Text.js'),
Types = require('%PathToCoreWebclientModule%/js/utils/Types.js'),
App = require('%PathToCoreWebclientModule%/js/App.js'),
Screens = require('%PathToCoreWebclientModule%/js/Screens.js'),
Routing = require('%PathToCoreWebclientModule%/js/Routing.js'),
CAbstractScreenView = require('%PathToCoreWebclientModule%/js/views/CAbstractScreenView.js'),
Links = require('modules/%ModuleName%/js/utils/Links.js'),
Cache = require('modules/%ModuleName%/js/Cache.js'),
EntitiesTabs = require('modules/%ModuleName%/js/EntitiesTabs.js'),
Settings = require('modules/%ModuleName%/js/Settings.js'),
CEntitiesView = require('modules/%ModuleName%/js/views/CEntitiesView.js')
;
/**
* Constructor of admin panel settings view.
*
* @constructor
*/
function CSettingsView()
{
CAbstractScreenView.call(this, '%ModuleName%');
this.tenants = Cache.tenants;
this.selectedTenant = Cache.selectedTenant;
this.currentEntityType = ko.observable('');
this.currentEntitiesId = ko.observable({});
this.lastSavedEntitiesId = ko.observable({});
this.showTenantsSelector = ko.computed(function () {
return Settings.EnableMultiTenant && this.tenants().length > 1;
}, this);
this.aScreens = [
{
linkHash: ko.observable(Routing.buildHashFromArray(Links.get(''))),
sLinkText: Text.i18n('%MODULENAME%/HEADING_SYSTEM_SETTINGS_TABNAME'),
sType: '',
oView: null
}
];
_.each(EntitiesTabs.getData(), _.bind(function (oEntityData) {
var
oView = new CEntitiesView(oEntityData.Type),
fChangeEntity = _.bind(function (sType, iEntityId, sTabName) {
if (sTabName === 'create')
{
this.createEntity();
}
else if (sType === this.currentEntityType())
{
this.changeEntity(sType, iEntityId, sTabName || '');
}
else
{
var oEntitiesId = _.clone(this.currentEntitiesId());
if (Types.isNumber(iEntityId))
{
if (sType)
{
oEntitiesId[sType] = iEntityId;
delete oEntitiesId[this.currentEntityType()];
}
}
else if (oEntitiesId[sType])
{
delete oEntitiesId[sType];
}
Routing.replaceHash(Links.get(this.currentEntityType(), oEntitiesId, ''));
}
}, this)
;
oView.setChangeEntityHandler(fChangeEntity);
this.aScreens.push({
linkHash: ko.computed(function () {
var oEntitiesId = _.clone(this.lastSavedEntitiesId());
_.extend(oEntitiesId, this.currentEntitiesId());
return Routing.buildHashFromArray(Links.get(oEntityData.Type, oEntitiesId));
}, this),
sLinkText: Text.i18n(oEntityData.LinkTextKey),
sType: oEntityData.Type,
oView: oView
});
}, this));
this.currentEntitiesView = ko.computed(function () {
var
sCurrType = this.currentEntityType(),
oCurrEntitiesData = _.find(this.aScreens, function (oData) {
return oData.sType === sCurrType;
})
;
return oCurrEntitiesData ? oCurrEntitiesData.oView : null;
}, this);
this.currentEntitiesView.subscribe(function(){
if (this.currentEntitiesView())
{
this.currentEntitiesView().onHide();
}
}, this, 'beforeChange');
this.currentEntitiesView.subscribe(function () {
if (this.currentEntitiesView())
{
this.currentEntitiesView().onShow();
}
}, this);
this.tabs = ko.observableArray([]);
this.visibleTabsCount = ko.computed(function () {
var iCount = 0;
_.each(this.tabs(), function (oTab) {
if (oTab.view && (typeof(oTab.view.visible) === 'undefined' || oTab.view.visible()))
{
iCount++;
}
});
return iCount;
}, this);
this.showModulesTabs = ko.computed(function () {
return this.currentEntityType() === '' || this.currentEntitiesView().hasSelectedEntity();
}, this);
this.currentTab = ko.observable(null);
this.aStartErrors = [];
App.subscribeEvent('SendAjaxRequest::before', this.onAjaxSend.bind(this));
App.broadcastEvent('%ModuleName%::ConstructView::after', {'Name': this.ViewConstructorName, 'View': this});
}
_.extendOwn(CSettingsView.prototype, CAbstractScreenView.prototype);
CSettingsView.prototype.ViewTemplate = '%ModuleName%_SettingsView';
CSettingsView.prototype.ViewConstructorName = 'CSettingsView';
CSettingsView.prototype.onAjaxSend = function (oParams)
{
if (this.currentEntityType() !== '' && !oParams.Parameters.TenantId)
{
oParams.Parameters.TenantId = Cache.selectedTenantId();
}
};
CSettingsView.prototype.selectTenant = function (iId)
{
var oEntitiesId = _.clone(this.currentEntitiesId());
oEntitiesId['Tenant'] = iId;
Routing.setHash(Links.get(this.currentEntityType(), oEntitiesId));
};
/**
* Registers admin panel tab.
*
* @param {Function} fGetTabView Function that returns Promise which resolves into view model of the tab.
* @param {Object} oTabName Tab name.
* @param {Object} oTabTitle Tab title.
*/
CSettingsView.prototype.registerTab = function (fGetTabView, oTabName, oTabTitle)
{
if (_.isFunction(fGetTabView))
{
var aTabs = this.tabs;
return new Promise(fGetTabView).then(function (oTabView) {
aTabs.push({
view: oTabView,
name: oTabName,
title: oTabTitle
});
}, function (error) {
console.log('failed to load settings tab', error);
});
}
return false;
};
/**
* Sorts tabs by some modules order list
*/
CSettingsView.prototype.sortRegisterTabs = function ()
{
this.tabs(_.sortBy(this.tabs(), function (oTab) {
var iIndex = _.indexOf(Settings.TabsOrder, oTab.name);
return iIndex !== -1 ? iIndex : Settings.TabsOrder.length;
}));
};
CSettingsView.prototype.registerTabSection = function (fGetSectionView, sTabName) {
var
oTab = _.findWhere(this.tabs(), {'name': sTabName}),
oSection = fGetSectionView()
;
if (oTab)
{
oTab.view.addSettingsSection(oSection);
}
};
/**
* Sets hash without creating entity.
*/
CSettingsView.prototype.cancelCreatingEntity = function ()
{
Routing.setHash(Links.get(this.currentEntityType(), this.currentEntitiesId(), ''));
};
/**
* Sets hash for creating entity.
*/
CSettingsView.prototype.createEntity = function ()
{
var oEntitiesId = _.clone(this.currentEntitiesId());
delete oEntitiesId[this.currentEntityType()];
if (this.currentEntityType() !== 'Tenant' && !oEntitiesId['Tenant'] && Cache.selectedTenantId())
{
oEntitiesId['Tenant'] = Cache.selectedTenantId();
}
Routing.setHash(Links.get(this.currentEntityType(), oEntitiesId, 'create'));
};
/**
* Sets hash to route to screen with specified entity type and|or entity identifier and|or settings tab.
*
* @param {string} sEntityName Entity type to display.
* @param {number} iEntityId Identifier of entity to display.
* @param {string} sTabName Name of settings tab to display.
*/
CSettingsView.prototype.changeEntity = function (sEntityName, iEntityId, sTabName)
{
var
oEntitiesId = _.clone(this.currentEntitiesId()),
bHasTab = !!_.find(this.tabs(), function (oTab) {
return oTab.name === sTabName;
}),
sCurrTabName = this.currentTab() ? this.currentTab().name : ''
;
if (sEntityName)
{
oEntitiesId[sEntityName] = iEntityId;
}
if (sEntityName !== 'Tenant' && Cache.selectedTenantId())
{
oEntitiesId['Tenant'] = Cache.selectedTenantId();
}
Routing.setHash(Links.get(sEntityName, oEntitiesId, bHasTab ? sTabName : sCurrTabName));
};
/**
* Runs after knockout binding. Checks if settings tab have error to show on start and shows them.
*/
CSettingsView.prototype.onBind = function ()
{
_.each(this.tabs(), _.bind(function (oTab) {
if (oTab.view && _.isFunction(oTab.view.getStartError))
{
var koError = oTab.view.getStartError();
if (_.isFunction(koError))
{
koError.subscribe(function () {
this.showStartError();
}, this);
this.aStartErrors.push(koError);
}
}
}, this));
this.showStartError();
};
CSettingsView.prototype.showStartError = function ()
{
var aErrors = [];
_.each(this.aStartErrors, function (koError) {
var sError = koError();
if (sError !== '')
{
aErrors.push(sError);
}
});
Screens.showError(aErrors.join('<br /><br />'), true);
};
/**
* Parses parameters from url hash, hides current admin panel tab if nessessary and after that finds a new one and shows it.
*
* @param {Array} aParams Parameters from url hash.
*/
CSettingsView.prototype.onRoute = function (aParams)
{
var
oParams = Links.parse(aParams),
aTabParams = aParams.slice(1),
bSameType = this.currentEntityType() === oParams.CurrentType,
bSameId = this.currentEntitiesId()[oParams.CurrentType] === oParams.Entities[oParams.CurrentType],
bSameTab = this.currentTab() && this.currentTab().name === oParams.Last,
bSameEntities = JSON.stringify(this.currentEntitiesId()) === JSON.stringify(oParams.Entities),
oCurrentTab = this.currentTab(),
fAfterTabHide = _.bind(function () {
this.showNewScreenView(oParams);
this.showNewTabView(oParams.Last, aTabParams); // only after showing new entities view
}, this),
fAfterRefuseTabHide = _.bind(function () {
if (oCurrentTab)
{
Routing.replaceHashDirectly(Links.get(this.currentEntityType(), this.currentEntitiesId(), this.currentTab() ? this.currentTab().name : ''));
}
}, this)
;
if (!bSameType || !bSameId || !bSameTab || !bSameEntities)
{
if (oCurrentTab && $.isFunction(oCurrentTab.view.hide))
{
oCurrentTab.view.hide(fAfterTabHide, fAfterRefuseTabHide);
}
else
{
fAfterTabHide();
}
}
else if (oCurrentTab)
{
oCurrentTab.view.onRoute(aTabParams, this.currentEntitiesId());
}
};
/**
* Shows new screen view.
*
* @param {Object} oParams Parameters with information about new screen.
*/
CSettingsView.prototype.showNewScreenView = function (oParams)
{
var
oCurrentEntityData = _.find(this.aScreens, function (oData) {
return oData.sType === oParams.CurrentType;
})
;
this.currentEntityType(oParams.CurrentType);
this.currentEntitiesId(oParams.Entities);
if (!_.isEmpty(oParams.Entities))
{
this.lastSavedEntitiesId(oParams.Entities);
}
Cache.setSelectedTenant(oParams.Entities['Tenant']);
if (oCurrentEntityData && oCurrentEntityData.oView)
{
if (oParams.Last === 'create')
{
oCurrentEntityData.oView.openCreateForm();
}
else
{
oCurrentEntityData.oView.cancelCreatingEntity();
}
oCurrentEntityData.oView.changeEntity(oParams.Entities[oParams.CurrentType], oParams.Entities);
}
};
/**
* Shows tab with specified tab name. Should be called only after calling showNewScreenView method.
*
* @param {string} sNewTabName New tab name.
* @param {array} aTabParams
*/
CSettingsView.prototype.showNewTabView = function (sNewTabName, aTabParams)
{
// Sets access level to all tabs so they can correct their visibilities
_.each(this.tabs(), _.bind(function (oTab) {
if (oTab.view && _.isFunction(oTab.view.setAccessLevel))
{
oTab.view.setAccessLevel(this.currentEntityType(), this.currentEntitiesId()[this.currentEntityType()]);
}
}, this));
// Finds tab with name from the url hash
var oNewTab = _.find(this.tabs(), function (oTab) {
return oTab.name === sNewTabName;
});
// If the tab wasn't found finds the first available visible tab
if (!oNewTab || !(oNewTab.view && oNewTab.view.visible()))
{
oNewTab = _.find(this.tabs(), function (oTab) {
return oTab.view && oTab.view.visible();
});
}
// If tab was found calls its onRoute function and sets new current tab
if (oNewTab)
{
if ($.isFunction(oNewTab.view.onRoute))
{
oNewTab.view.onRoute(aTabParams, this.currentEntitiesId());
}
this.currentTab(oNewTab);
}
};
/**
* Sets hash for showing another admin panel tab.
*
* @param {string} sTabName Tab name.
*/
CSettingsView.prototype.changeTab = function (sTabName)
{
var oEntitiesId = this.currentEntityType() ? this.currentEntitiesId() : {};
Routing.setHash(Links.get(this.currentEntityType(), oEntitiesId, sTabName));
};
/**
* Calls logout function of application.
*/
CSettingsView.prototype.logout = function ()
{
App.logout();
};
/**
* Deletes current entity.
*/
CSettingsView.prototype.deleteCurrentEntity = function ()
{
if (this.currentEntitiesView())
{
this.currentEntitiesView().deleteCurrentEntity();
}
};
/**
* @param {Array} aAddHash
*/
CSettingsView.prototype.setAddHash = function (aAddHash)
{
Routing.setHash(_.union([Settings.HashModuleName, this.currentTab() ? this.currentTab().name : ''], aAddHash));
};
module.exports = new CSettingsView();