SmartIT_Extensions/BMC/smart-it-full-helix/scripts/app/main-controller.js

633 lines
33 KiB
JavaScript

"use strict";
(function () {
'use strict';
angular.module('myitsmApp')
.controller('MainController', ['$scope', '$state', '$filter', 'session', 'l10nModel', 'authModel', 'ccsModel', 'userModel', 'searchModel', 'studioModel', '$window', 'AUTH_EVENTS', '$timeout', 'chatModel', 'emailModel', 'mobileClientCheckerService', 'systemAlertService', 'i18nService', '$rootScope', '$http', '$modal', '$cookies', '$sce', 'events', 'personModel', 'localStorageService', 'utilityFunctions', 'configurationModel', '$q', '$location', 'browser', 'gainsightModel',
function ($scope, $state, $filter, session, l10nModel, authModel, ccsModel, userModel, searchModel, studioModel, $window, AUTH_EVENTS, $timeout, chatModel, emailModel, mobileClientCheckerService, systemAlertService, i18nService, $rootScope, $http, $modal, $cookies, $sce, events, personModel, localStorageService, utilityFunctions, configurationModel, $q, $location, browser, gainsightModel) {
'ngInject';
var APP_STATES = {
INDETERMINATE: -1,
SHOW_LOGIN: 0,
SHOW_MAIN: 1,
SHOW_WINDOW: 2
}, ANCHORS = {
DashBoardWithHash: '#/',
'Ticket Console': 'ticket-consoleStudio',
'Asset Console': 'asset-consoleStudio',
'Knowledge Console': 'knowledge-console',
'Smart Recorder': 'create/smart-recorder',
'Calendar': 'calendarStudio'
};
$scope.homeServerDefer = $q.defer();
$scope.isMobile = browser.isMobile;
$scope.insideChangeCalendar = false;
$scope.$on(events.INSIDE_CHANGE_CALENDAR, function (event) {
$scope.insideChangeCalendar = true;
});
$scope.studioCCSDetailsDefer = $q.defer();
$rootScope.showStudioFrame = false;
//$scope.studioFrameUrl = $sce.trustAsResourceUrl('https://smtdev1-is.dsmlab.bmc.com/helix/index.html#/com.bmc.arsys.rx.innovationstudio/workspace');
$rootScope.studioFrameUrl = $sce.trustAsResourceUrl('');
function callKeepAlive() {
$http({
method: 'GET',
url: '/smartit/rest/keepAlive'
}).then(function () { }, function (response) {
console.error('keepAlive : ' + response);
});
}
function callKeepAlive() {
$http({
method: 'GET',
url: '/smartit/rest/keepAlive'
}).then(function () { }, function (response) {
console.error('keepAlive : ' + response);
});
}
window.onmessage = handleMessage;
function handleMessage(e) {
if (typeof e.data === 'string' && utilityFunctions.checkIfJson(e.data)) {
var parcelObject = JSON.parse(e.data);
if (parcelObject.action && parcelObject.action === 'keepAlive') {
// ' just a dummy call, keeping the session Alive for PWA');
callKeepAlive();
}
else if (parcelObject.homeServer) {
localStorage.setItem('homeServer', parcelObject.homeServer);
// If SSO enabled send a message to PV once homeServer is set.
if (authModel.isSSOEnabled()) {
$scope.sendMessageToPwaDomain({ isSsoEnabled: true });
}
$scope.homeServerDefer.resolve();
}
// hide navigation bar if Smart IT is embedded in another app
if (parcelObject.parent && parcelObject.action && parcelObject.action === 'hideNavigationBar') {
$rootScope.hasParent = true;
$rootScope.hideNavigationBar = true;
}
}
}
$scope.iframeLoadedCallBack = function () {
$scope.pwaFrameLoaded = true;
$rootScope.$broadcast(events.PWA_IFRAME_LOADED);
};
function checkMidtierUrl(url) {
var lastSlashIndex = url.lastIndexOf('/');
if (lastSlashIndex === url.length - 1) {
url = url.substr(0, lastSlashIndex);
}
if (url.search('/arsys') > -1) {
return url;
}
return url + '/arsys';
}
$scope.midTierUrlDeferred = $q.defer();
// Setting the PWA home for logout and login synchronization.
$rootScope.$on(events.MIDTIER_URL_LOADED, function (event, data) {
var midtierUrl = authModel.getMidtierUrl();
var midtierUrlArsys = checkMidtierUrl(midtierUrl);
localStorage.setItem('midtierUrl', midtierUrlArsys);
localStorage.setItem('pwaDomain', (midtierUrl.search('arsys') > -1) ? midtierUrl.substr(0, midtierUrl.lastIndexOf("/")) : midtierUrl);
if (midtierUrl) {
$scope.pwaHomeSrc = $sce.trustAsResourceUrl(midtierUrlArsys + '/pwa/login-light.html?origin=' + window.location.origin);
}
$scope.midTierUrlDeferred.resolve();
});
$scope.APP_STATES = APP_STATES;
$scope.appState = APP_STATES.INDETERMINATE;
$scope.state = $state;
var unbind = $rootScope.$on('i18nResourcesUpdated', function () {
mobileClientCheckerService.checkForMobileDevice();
});
$scope.$on('$destroy', function () {
console.log('destroy root scope events bound from here');
unbind();
});
$(document).ready(function () {
if (window.localStorage.tabCount) {
window.localStorage.tabCount++;
}
else {
window.localStorage.tabCount = 1;
}
});
window.addEventListener('beforeunload', function (evt) {
if (window.localStorage.tabCount) {
window.localStorage.tabCount--;
}
if (window.localStorage.tabCount == 0 && window.localStorage.sessionActive == 'true') {
if (navigator.sendBeacon) {
navigator.sendBeacon('/smartit/rest/arlicense/timeout/register');
}
else {
var request = new XMLHttpRequest();
request.open('POST', '/smartit/rest/arlicense/timeout/register', false);
request.send();
}
}
});
// just a dummy call, keeping the session Alive for PV
setInterval(function () {
if (window.localStorage.smartITActivity == "true") {
$scope.sendMessageToPwaDomain({ keepAlive: 'true' });
window.localStorage.smartITActivity = "false";
}
}, 60000);
function setPwaFrameUrl() {
var pwaFrame = document.getElementsByClassName('app__pwa-iframe');
console.info('Inside setPwaFrameUrl method - url : ' + $scope.finalUrl);
if (pwaFrame && pwaFrame.length !== 0) {
if ($scope.finalUrl) {
setTimeout(function () {
pwaFrame[0].contentWindow.location.replace($scope.finalUrl);
});
console.info('Inside setPwaFrameUrl method - location url changed');
}
}
else {
console.error('Inside setPwaFrameUrl method : pwa iframe not loaded');
}
}
// IS has to provide the blank fake url
function setFakeStudioFrameUrl() {
if (studioModel.enableISCalendar || studioModel.enableSharedConsole || studioModel.enableISAssetConsole) {
var studioFrame = document.getElementsByClassName('app__studio-iframe');
console.info('Inside setStudioFrameUrl method - url : Setting iframe blank');
if (studioFrame && studioFrame.length !== 0) {
var studioFrameUrl = studioModel.baseUrlForIS + '/helix/index.html#/com.bmc.dsm.itsm-applications/iview/com.bmc.dsm.itsm-applications:Placeholder%20view%20for%20nav%20items';
//var studioFrameUrl = "about:blank";
setTimeout(function () {
studioFrame[0].contentWindow.location.replace(studioFrameUrl);
});
console.info('Inside setStudioFrameUrl method - Setting iframe blank: ' + studioFrameUrl);
}
else {
setTimeout(function () {
var studioFrame = document.getElementsByClassName('app__studio-iframe');
console.info('Inside setStudioFrameUrl method - url : Setting iframe blank');
if (studioFrame && studioFrame.length !== 0) {
var studioFrameUrl = studioModel.baseUrlForIS + '/helix/index.html#/com.bmc.dsm.itsm-applications/iview/com.bmc.dsm.itsm-applications:Placeholder%20view%20for%20nav%20items';
studioFrame[0].contentWindow.location.replace(studioFrameUrl);
console.info('Inside setStudioFrameUrl method - Setting iframe blank: ' + studioFrameUrl);
}
else {
console.error('Inside setStudioFrameUrl method : studio iframe not loaded');
}
}, 1000);
}
}
}
function getContext(toState, crossLaunchContext) {
switch (toState.name) {
case 'pwaDraftIncident':
if (crossLaunchContext) {
return crossLaunchContext + '_CREATEINCIDENT';
}
return 'SMARTRECORDER_CREATEINCIDENT';
case 'pwaDraftWorkorder':
if (crossLaunchContext) {
return crossLaunchContext + '_CREATEWORKORDER';
}
return 'SMARTRECORDER_CREATEWORKORDER';
case 'pwaDraftProblem':
if (crossLaunchContext) {
return crossLaunchContext + '_CREATEPROBLEM';
}
return '';
case 'pwaDraftKnownerror':
if (crossLaunchContext) {
return crossLaunchContext + '_CREATEKNOWNERROR';
}
return '';
case 'pwaDraftChange':
if (crossLaunchContext) {
return crossLaunchContext + '_CREATECHANGE';
}
return '';
break;
default:
return '';
}
}
function stateChangeSuccess(event, toState, toParams) {
$rootScope.hideNavigationBar = $rootScope.hasParent ? true : (toState && toState.name.indexOf('changeCalendar') !== -1);
if (toState && toState.name && _.endsWith(toState.name, 'Studio')) {
$rootScope.showStudioFrame = true;
$scope.finalUrl = getPwaBaseUrl();
}
else if (localStorage.getItem('midtierUrl')) {
$rootScope.showStudioFrame = false;
if (studioModel.ccsFetched) {
setFakeStudioFrameUrl();
}
else {
$scope.studioCCSDetailsDefer.promise.then(function () {
setFakeStudioFrameUrl();
});
}
var guid = toParams && toParams.id ? toParams.id : null;
if (toState && (toState.name === 'assetPV' || toState.name === 'editAssetPV')) {
guid = toParams.assetId + '|' + toParams.assetClassId;
}
var crossLaunchContext = toParams && toParams.crossLaunchContext ? toParams.crossLaunchContext : '';
var isPvState = toState && toState.name && (_.endsWith(toState.name, 'PV') || toState.name.indexOf('pwaDraft') >= 0);
var excludeStates = ['search.incidentPV', 'search.workorderPV', 'search.taskPV', 'search.problemPV', 'search.problemPV', 'search.knownerrorPV', 'search.personPV', 'search.assetPV', 'search.changePV'];
if (isPvState && !_.includes(excludeStates, toState.name)) {
var finalUrl = getPwaBaseUrl(toState);
if (toState.data.targetForm) {
finalUrl += '&targetForm=' + toState.data.targetForm;
}
if (toState.data.targetView) {
finalUrl += '&targetView=' + toState.data.targetView;
}
if (toState.data.mode) {
finalUrl += '&mode=' + toState.data.mode;
}
if (guid) {
if (toState.data.targetForm) {
finalUrl += '&targetId=' + guid;
}
else {
finalUrl += '&guid=' + guid;
}
}
if (toState.name.indexOf('pwaDraft') >= 0) {
finalUrl += '&context=' + getContext(toState, crossLaunchContext);
}
else if (toState.name.indexOf('edit') != -1 && toParams.context) {
finalUrl += '&context=' + toParams.context;
}
$rootScope.showFrame = true;
$scope.finalUrl = finalUrl + '&rand=' + Math.random();
}
else if (toState.name.indexOf("pwaAction") >= 0 && toParams.data && toParams.data.formName) {
$rootScope.showFrame = true;
$scope.finalUrl = getPwaBaseUrl(toParams, true);
}
else {
$rootScope.showFrame = false;
$scope.finalUrl = getPwaBaseUrl();
}
}
else {
$rootScope.showStudioFrame = false;
$scope.midTierUrlDeferred.promise.then(function () {
stateChangeSuccess(event, toState, toParams);
});
}
}
function getPwaBaseUrl(toState, excludeOrigin) {
var midtierUrl = localStorage.getItem('midtierUrl');
if (!midtierUrl) {
console.warn("Mid-tier URL is not available");
return "about:blank";
}
var homeServer = localStorage.getItem('homeServer');
//if (!homeServer) {
//$scope.$broadcast(AUTH_EVENTS.SESSION_EXPIRED);
//}
var origin = window.location.origin;
var path = 'goto', baseUrl = "";
if (homeServer) {
path = 'forms/' + homeServer;
}
var formName = toState && toState.data && toState.data.formName ? (path + '/' + toState.data.formName) : 'fake-route';
baseUrl = midtierUrl + '/pwa/#/' + formName;
if (!excludeOrigin) {
baseUrl += '?origin=' + origin;
}
return baseUrl;
}
$scope.$on('$stateChangeSuccess', function (event, toState, toParams) {
stateChangeSuccess(event, toState, toParams);
});
/**
* Public functions
*/
$scope.sendMessageToPwaDomain = function (data) {
if (localStorage.getItem('midtierUrl')) {
var domain = localStorage.getItem('pwaDomain');
if (domain) {
console.info('pwa iframe load status : ' + $scope.pwaFrameLoaded);
var elemFound = setInterval(function () {
console.info('sendMessageToPwaDomain - setInterval');
var iframeContent = document.getElementsByClassName('app__pwa-home-iframe') && document.getElementsByClassName('app__pwa-home-iframe').length ? document.getElementsByClassName('app__pwa-home-iframe')[0].contentWindow : null;
if (iframeContent != null && $scope.pwaFrameLoaded) {
console.info('message sent to pwa iframe ');
utilityFunctions.windowPostMessage(iframeContent, data, domain);
clearInterval(elemFound);
}
});
}
}
};
$scope.onLogoutClick = function () {
logoutPWA();
logoutLiveChat();
// timeout added so that the logout event can be passed to the iframes
$timeout(function () {
$scope.appState = APP_STATES.INDETERMINATE;
authModel.logout();
}, 1000);
};
$scope.onOptinConfigClick = function () {
gainsightModel.showOptinConfig();
};
$scope.onAboutClick = function () {
$modal.open({
templateUrl: 'views/about.html',
windowClass: 'bmc-system-about-modal',
size: 'lg'
});
};
$scope.toggleAccessibility = function () {
userModel.isAccessibleUser = !userModel.isAccessibleUser;
$scope.setAccessibility();
};
$scope.setAccessibility = function () {
var expDate = new Date();
expDate.setDate(expDate.getDate() + 365);
if ($location.protocol() === "https") {
$cookies.put('accessibility', userModel.isAccessibleUser, {
expires: expDate,
httpOnly: true,
secure: true
});
}
else {
$cookies.put('accessibility', userModel.isAccessibleUser, {
expires: expDate,
httpOnly: true
});
}
userModel.updateUserPreferences('interface', {
id: userModel.isAccessibleUserPreferenceId,
name: 'accessibility',
value: userModel.isAccessibleUser
});
};
$scope.setFocus = function (id) {
$('#' + id).focus();
};
$scope.$on(AUTH_EVENTS.LOGIN_SUCCESS, function (event, params) {
console.log('$scope.$on(AUTH_EVENTS.LOGIN_SUCCESS)');
var promises = [];
if (ANCHORS.DashBoardWithHash === window.location.hash) {
promises.push(ccsModel.getCCSParameters());
if (localStorage.midtierUrl && !params.isSsoEnabled && localStorage.getItem('overridePV') !== 'T') {
promises.push($scope.homeServerDefer.promise);
}
$q.all(promises).then(function (response) {
$scope.ccsProperties = response[0];
if ($scope.ccsProperties && $scope.ccsProperties.landingPage && ANCHORS[$scope.ccsProperties.landingPage]) {
if (ANCHORS[$scope.ccsProperties.landingPage] === 'calendar' && $scope.ccsProperties.calendarFeatureEnabled
&& $scope.ccsProperties.calendarFeatureEnabled.trim() === 'false') {
console.log('Landing page :: Dashboard. calendarFeatureEnabled :' + $scope.ccsProperties.calendarFeatureEnabled);
}
else {
console.log('Landing page :: Diverting to === ' + ANCHORS[$scope.ccsProperties.landingPage]);
if ($scope.isMobile) {
window.location.hash = ANCHORS['Ticket Console'];
}
else {
window.location.hash = ANCHORS[$scope.ccsProperties.landingPage];
}
}
}
if (!params.isSsoEnabled) {
window.location.reload(false);
}
else if (session.alive) {
console.info('location hash : session alive');
$scope.sendMessageToPwaDomain({ isSsoEnabled: params.isSsoEnabled });
sessionActiveCallback();
if ($scope.isMobile) {
window.location.hash = ANCHORS['Ticket Console'];
}
}
});
}
else {
if (!params.isSsoEnabled) {
localStorage.midtierUrl ? promises.push($scope.homeServerDefer.promise) : promises.push(Promise.resolve());
$q.all(promises).then(function () {
window.location.reload(false);
});
}
else if (session.alive) {
console.info('session alive');
$scope.sendMessageToPwaDomain({ isSsoEnabled: params.isSsoEnabled });
sessionActiveCallback();
}
}
});
$scope.$on(AUTH_EVENTS.LOGOUT_SUCCESS, function (event, eventData) {
console.log('$scope.$on(AUTH_EVENTS.LOGOUT_SUCCESS)');
localStorage.removeItem('tabCount');
window.localStorage.sessionActive = false;
localStorage.removeItem('smartITActivity');
$scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive });
if (authModel.isSSOEnabled()) {
if (eventData && eventData.postLogoutUrl) {
var url = eventData.postLogoutUrl;
if (url.indexOf('?') > -1) {
url += '&callback=JSON_CALLBACK';
}
else {
url += '?callback=JSON_CALLBACK';
}
$http.jsonp(url)
.finally(function () {
$window.location.href = './?' + moment().valueOf();
});
}
else if (eventData && eventData.redirectUrl) {
$window.location.href = eventData.redirectUrl;
}
else {
$window.location.href = './?' + moment().valueOf();
}
}
else {
$window.location.href = './';
}
});
function sessionActiveCallback() {
console.log('$scope.$on(AUTH_EVENTS.SESSION_ACTIVE)');
window.localStorage.sessionActive = true;
$scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive });
if (window.localStorage.tabCount == 1) {
authModel.deRegister();
}
//Below commented line causes page reload and since we are still in resolve in case of knowledge related screens, the current state is not KA but blank
//And this causes user to redirect to unauthorised page. Couldnt find any valid use case where below call is required.
//$rootScope.$emit('$stateChangeStart', $scope.state.current);
loadApplicationData();
}
$scope.$on(AUTH_EVENTS.SESSION_ACTIVE, sessionActiveCallback);
$scope.$on(AUTH_EVENTS.NOT_AUTHENTICATED, function () {
console.log('$scope.$on(AUTH_EVENTS.NOT_AUTHENTICATED)');
$scope.appState = APP_STATES.SHOW_LOGIN;
});
$scope.$on(AUTH_EVENTS.AR_CONNECTION_FAILED, function (event, response) {
console.log('$scope.$on(AUTH_EVENTS.AR_CONNECTION_FAILED)');
systemAlertService.error({
text: response.data.error
});
});
$scope.$on(AUTH_EVENTS.SESSION_EXPIRED, function () {
console.log('$scope.$on(AUTH_EVENTS.SESSION_EXPIRED)');
window.localStorage.sessionActive = false;
$scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive });
localStorage.removeItem('tabCount');
localStorage.removeItem('smartITActivity');
if (authModel.isSSOEnabled()) {
$scope.appState = APP_STATES.INDETERMINATE;
//For RSSO show session expired alert
var modalInstance = systemAlertService.modal({
title: $filter('i18n')('error.sessionExpired.title'),
text: $filter('i18n')('error.sessionExpired.message'),
backdrop: 'static',
buttons: [
{
text: i18nService.getLocalizedString('common.button.signInAgain'),
data: true
}
]
});
modalInstance.result.then(function (data) {
if (data) {
localStorage.removeItem('homeServer');
$window.location.reload();
}
});
}
else {
logoutPWA();
$scope.appState = APP_STATES.SHOW_LOGIN;
}
});
$scope.$on(AUTH_EVENTS.INITIALIZE_METADATA_ERROR, function () {
if (!$scope.showingErrorModal) {
$scope.appState = APP_STATES.INDETERMINATE;
$scope.showingErrorModal = true;
console.log('$scope.$on(AUTH_EVENTS.INITIALIZE_METADATA_ERROR)');
window.localStorage.sessionActive = false;
$scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive });
localStorage.removeItem('tabCount');
localStorage.removeItem('smartITActivity');
var modalInstance = systemAlertService.modal({
title: $filter('i18n')('error.invalidMetadata.title'),
text: $filter('i18n')('error.invalidMetadata.message'),
backdrop: 'static',
buttons: [
{
text: i18nService.getLocalizedString('common.button.signInAgain'),
data: true
}
]
});
modalInstance.result.then(function (data) {
$scope.showingErrorModal = false;
if (data && authModel.isSSOEnabled()) {
$window.location.reload();
}
else if (data) {
clearApplicationData();
}
});
}
});
function clearApplicationData() {
logoutPWA();
logoutLiveChat();
// timeout added so that the logout event can be passed to the iframes
$timeout(function () {
$scope.appState = APP_STATES.INDETERMINATE;
localStorageService.remove('user.userId');
// ITSM calendar related storage.
sessionStorage.removeItem('calendarFilterState');
sessionStorage.removeItem('calendarFilterView');
sessionStorage.removeItem('calendarFilterDate');
session.destroy();
localStorage.removeItem('tabCount');
localStorage.sessionActive = false;
localStorage.removeItem('smartITActivity');
$scope.sendMessageToPwaDomain({ smartITsessionActive: window.localStorage.sessionActive });
$window.location.href = './';
}, 1000);
}
/**
* Private functions
*/
/**
* Loads all data required for application
*/
function loadApplicationData() {
$scope.appState = APP_STATES.INDETERMINATE; // show loading spinner
userModel.getUserDataForCurrentSession();
l10nModel.loadSystemMessages();
init();
}
function logoutPWA() {
if (localStorage.homeServer) {
localStorage.removeItem('homeServer');
}
$scope.sendMessageToPwaDomain({ message: 'logout', logout: true });
}
function logoutLiveChat() {
var domain = localStorageService.get('eschatServerUrl');
if (domain) {
var targetFrame = window.frames.liveChatFrame;
if (targetFrame !== undefined && targetFrame !== null) {
var message = {
event: 'app_logout',
data: { logout: true, isRSSO: authModel.isSSOEnabled() }
};
targetFrame.postMessage(message, domain);
console.log("Message Sent To LiveChat Frame:" + JSON.stringify(message));
localStorageService.remove('eschatServerUrl');
}
return true;
}
return false;
}
/**
* Entry point
*/
function init() {
$scope.showMeridian = window.showMeridian;
studioModel.init().then(function (studioMetaVals) {
$scope.studioCCSDetailsDefer.resolve(studioMetaVals);
});
searchModel.init();
$scope.chatModel = chatModel;
$scope.userModel = userModel;
$scope.emailModel = { emailInstances: emailModel.emailInstances };
if ($scope.state.$current.data && $scope.state.$current.data.separateWindowMode) {
$scope.appState = APP_STATES.SHOW_WINDOW;
}
else {
var accessibilityCookie = $cookies.get('accessibility') ? JSON.parse($cookies.get('accessibility')) : false;
userModel.getUserPreferences('interface').then(function (accessibleConfig) {
if (_.isObject(accessibleConfig[0]) || accessibilityCookie) {
userModel.isAccessibleUser = _.isObject(accessibleConfig[0]) ? accessibleConfig[0].value : false;
userModel.isAccessibleUserPreferenceId = _.isObject(accessibleConfig[0]) ? accessibleConfig[0].id : null;
if (userModel.isAccessibleUser !== accessibilityCookie) {
$scope.setAccessibility();
}
}
}).finally(function () {
$scope.appState = APP_STATES.SHOW_MAIN;
});
}
$scope.$on('$viewContentLoaded', function () {
if (!chatModel.connected && !$scope.isMobile) {
chatModel.openChatConnection();
}
setPwaFrameUrl();
});
}
}]);
})();