/*
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import './entity-state-controller.scss';
/*@ngInject*/
export default function EntityStateController($scope, $timeout, $location, $state, $stateParams,
$q, $translate, utils, types, dashboardUtils, entityService, preservedState) {
var vm = this;
vm.inited = false;
vm.skipStateChange = false;
vm.openState = openState;
vm.updateState = updateState;
vm.resetState = resetState;
vm.getStateObject = getStateObject;
vm.navigatePrevState = navigatePrevState;
vm.getStateId = getStateId;
vm.getStateIndex = getStateIndex;
vm.getStateIdAtIndex = getStateIdAtIndex;
vm.getStateParams = getStateParams;
vm.getStateParamsByStateId = getStateParamsByStateId;
vm.getEntityId = getEntityId;
vm.getStateName = getStateName;
vm.selectedStateIndex = -1;
function openState(id, params, openRightLayout) {
if (vm.states && vm.states[id]) {
resolveEntity(params).then(
function success(entityName) {
params.entityName = entityName;
var newState = {
id: id,
params: params
}
//append new state
vm.stateObject.push(newState);
vm.selectedStateIndex = vm.stateObject.length-1;
gotoState(vm.stateObject[vm.stateObject.length-1].id, true, openRightLayout);
vm.skipStateChange = true;
}
);
}
}
function updateState(id, params, openRightLayout) {
if (!id) {
id = getStateId();
}
if (vm.states && vm.states[id]) {
resolveEntity(params).then(
function success(entityName) {
params.entityName = entityName;
var newState = {
id: id,
params: params
}
//replace with new state
vm.stateObject[vm.stateObject.length - 1] = newState;
gotoState(vm.stateObject[vm.stateObject.length - 1].id, true, openRightLayout);
vm.skipStateChange = true;
}
);
}
}
function resetState() {
var rootStateId = dashboardUtils.getRootStateId(vm.states);
vm.stateObject = [ { id: rootStateId, params: {} } ];
gotoState(rootStateId, true);
}
function getStateObject() {
return vm.stateObject;
}
function navigatePrevState(index) {
if (index < vm.stateObject.length-1) {
vm.stateObject.splice(index+1, vm.stateObject.length-index-1);
vm.selectedStateIndex = vm.stateObject.length-1;
gotoState(vm.stateObject[vm.stateObject.length-1].id, true);
vm.skipStateChange = true;
}
}
function getStateId() {
if (vm.stateObject && vm.stateObject.length) {
return vm.stateObject[vm.stateObject.length-1].id;
} else {
return '';
}
}
function getStateIndex() {
if (vm.stateObject && vm.stateObject.length) {
return vm.stateObject.length-1;
} else {
return -1;
}
}
function getStateIdAtIndex(index) {
if (vm.stateObject && vm.stateObject[index]) {
return vm.stateObject[index].id;
} else {
return '';
}
}
function getStateParams() {
if (vm.stateObject && vm.stateObject.length) {
return vm.stateObject[vm.stateObject.length - 1].params;
} else {
return {};
}
}
function getStateParamsByStateId(stateId) {
var stateObj = getStateObjById(stateId);
if (stateObj) {
return stateObj.params;
} else {
return null;
}
}
function getEntityId(entityParamName) {
var stateParams = getStateParams();
if (!entityParamName || !entityParamName.length) {
return stateParams.entityId;
} else if (stateParams[entityParamName]) {
return stateParams[entityParamName].entityId;
}
return null;
}
function getStateObjById(id) {
for (var i=0; i < vm.stateObject.length; i++) {
if (vm.stateObject[i].id === id) {
return vm.stateObject[i];
}
}
return null;
}
function getStateName(index) {
var result = '';
if (vm.stateObject[index]) {
var stateName = vm.states[vm.stateObject[index].id].name;
stateName = utils.customTranslation(stateName, stateName);
var params = vm.stateObject[index].params;
var entityName = params && params.entityName ? params.entityName : '';
result = utils.insertVariable(stateName, 'entityName', entityName);
for (var prop in params) {
if (params[prop] && params[prop].entityName) {
result = utils.insertVariable(result, prop + ':entityName', params[prop].entityName);
}
}
}
return result;
}
function resolveEntity(params) {
var deferred = $q.defer();
if (params && params.entityId && params.entityId.id && params.entityId.entityType) {
if (params.entityName && params.entityName.length) {
deferred.resolve(params.entityName);
} else {
entityService.getEntity(params.entityId.entityType, params.entityId.id, {
ignoreLoading: true,
ignoreErrors: true
}).then(
function success(entity) {
var entityName = entity.name;
deferred.resolve(entityName);
},
function fail() {
deferred.reject();
}
);
}
} else {
deferred.resolve('');
}
return deferred.promise;
}
function parseState(stateBase64) {
var result;
if (stateBase64) {
try {
result = utils.base64toObj(stateBase64);
} catch (e) {
result = [ { id: null, params: {} } ];
}
}
if (!result) {
result = [];
}
if (!result.length) {
result[0] = { id: null, params: {} }
}
var rootStateId = dashboardUtils.getRootStateId(vm.states);
if (!result[0].id) {
result[0].id = rootStateId;
}
if (!vm.states[result[0].id]) {
result[0].id = rootStateId;
}
var i = result.length;
while (i--) {
if (!result[i].id || !vm.states[result[i].id]) {
result.splice(i, 1);
}
}
return result;
}
$scope.$watch('vm.states', function() {
if (vm.states) {
if (!vm.inited) {
vm.inited = true;
init();
}
}
});
function init() {
if (preservedState) {
vm.stateObject = preservedState;
vm.selectedStateIndex = vm.stateObject.length-1;
gotoState(vm.stateObject[vm.stateObject.length-1].id, true);
} else {
var initialState = $stateParams.state;
vm.stateObject = parseState(initialState);
vm.selectedStateIndex = vm.stateObject.length-1;
gotoState(vm.stateObject[vm.stateObject.length-1].id, false);
}
$timeout(() => {
$scope.$watchCollection(function () {
return $state.params;
}, function () {
var currentState = $state.params.state;
vm.stateObject = parseState(currentState);
});
$scope.$watch('vm.dashboardCtrl.dashboardCtx.state', function () {
if (vm.stateObject[vm.stateObject.length - 1].id !== vm.dashboardCtrl.dashboardCtx.state) {
vm.stateObject[vm.stateObject.length - 1].id = vm.dashboardCtrl.dashboardCtx.state;
updateLocation();
vm.skipStateChange = true;
}
});
$scope.$watch('vm.stateObject', function(newVal, prevVal) {
if (!angular.equals(newVal, prevVal) && newVal) {
if (vm.skipStateChange) {
vm.skipStateChange = false;
} else {
vm.selectedStateIndex = vm.stateObject.length - 1;
gotoState(vm.stateObject[vm.stateObject.length - 1].id, true);
}
}
}, true);
if (vm.dashboardCtrl.isMobile) {
watchSelectedStateIndex();
}
$scope.$watch('vm.dashboardCtrl.isMobile', function (newVal, prevVal) {
if (!angular.equals(newVal, prevVal)) {
if (vm.dashboardCtrl.isMobile) {
watchSelectedStateIndex();
} else {
stopWatchSelectedStateIndex();
}
}
});
});
}
function stopWatchSelectedStateIndex() {
if (vm.selectedStateIndexWatcher) {
vm.selectedStateIndexWatcher();
vm.selectedStateIndexWatcher = null;
}
}
function watchSelectedStateIndex() {
vm.selectedStateIndexWatcher = $scope.$watch('vm.selectedStateIndex', function(newVal, prevVal) {
if (!angular.equals(newVal, prevVal)) {
navigatePrevState(vm.selectedStateIndex);
}
});
}
function gotoState(stateId, update, openRightLayout) {
vm.dashboardCtrl.openDashboardState(stateId, openRightLayout);
if (update) {
updateLocation();
}
}
function updateLocation() {
if (vm.stateObject[vm.stateObject.length-1].id) {
if (isDefaultState()) {
$location.search('state', null);
} else {
$location.search('state', utils.objToBase64(vm.stateObject));
}
}
}
function isDefaultState() {
if (vm.stateObject.length == 1) {
var state = vm.stateObject[0];
var rootStateId = dashboardUtils.getRootStateId(vm.states);
if (state.id == rootStateId && (!state.params || isEmpty(state.params))) {
return true;
}
}
return false;
}
function isEmpty(map) {
for(var key in map) {
return !map.hasOwnProperty(key);
}
return true;
}
}