2016-12-26 17:07:47 +02:00
|
|
|
/*
|
2018-03-05 17:34:13 +02:00
|
|
|
* Copyright © 2016-2018 The Thingsboard Authors
|
2016-12-26 17:07:47 +02:00
|
|
|
*
|
|
|
|
|
* 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 angularStorage from 'angular-storage';
|
|
|
|
|
|
|
|
|
|
export default angular.module('thingsboard.itembuffer', [angularStorage])
|
|
|
|
|
.factory('itembuffer', ItemBuffer)
|
|
|
|
|
.factory('bufferStore', function(store) {
|
|
|
|
|
var newStore = store.getNamespacedStore('tbBufferStore', null, null, false);
|
|
|
|
|
return newStore;
|
|
|
|
|
})
|
|
|
|
|
.name;
|
|
|
|
|
|
|
|
|
|
/*@ngInject*/
|
2017-05-24 10:39:33 +03:00
|
|
|
function ItemBuffer($q, bufferStore, types, utils, dashboardUtils) {
|
2016-12-26 17:07:47 +02:00
|
|
|
|
|
|
|
|
const WIDGET_ITEM = "widget_item";
|
2017-05-24 10:39:33 +03:00
|
|
|
const WIDGET_REFERENCE = "widget_reference";
|
2016-12-26 17:07:47 +02:00
|
|
|
|
|
|
|
|
var service = {
|
2017-01-06 19:49:00 +02:00
|
|
|
prepareWidgetItem: prepareWidgetItem,
|
2016-12-26 17:07:47 +02:00
|
|
|
copyWidget: copyWidget,
|
2017-05-24 10:39:33 +03:00
|
|
|
copyWidgetReference: copyWidgetReference,
|
2016-12-26 17:07:47 +02:00
|
|
|
hasWidget: hasWidget,
|
2017-05-24 10:39:33 +03:00
|
|
|
canPasteWidgetReference: canPasteWidgetReference,
|
2016-12-26 17:07:47 +02:00
|
|
|
pasteWidget: pasteWidget,
|
2017-05-24 10:39:33 +03:00
|
|
|
pasteWidgetReference: pasteWidgetReference,
|
2016-12-26 17:07:47 +02:00
|
|
|
addWidgetToDashboard: addWidgetToDashboard
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return service;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
aliasesInfo {
|
|
|
|
|
datasourceAliases: {
|
|
|
|
|
datasourceIndex: {
|
2017-06-08 09:24:11 +03:00
|
|
|
alias: "...",
|
|
|
|
|
filter: "..."
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
targetDeviceAliases: {
|
|
|
|
|
targetDeviceAliasIndex: {
|
2017-06-08 09:24:11 +03:00
|
|
|
alias: "...",
|
|
|
|
|
filter: "..."
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
....
|
|
|
|
|
}
|
|
|
|
|
**/
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function prepareAliasInfo(entityAlias) {
|
|
|
|
|
return {
|
2017-06-08 09:24:11 +03:00
|
|
|
alias: entityAlias.alias,
|
|
|
|
|
filter: entityAlias.filter
|
2017-05-24 10:39:33 +03:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getOriginalColumns(dashboard, sourceState, sourceLayout) {
|
|
|
|
|
var originalColumns = 24;
|
|
|
|
|
var gridSettings = null;
|
|
|
|
|
var state = dashboard.configuration.states[sourceState];
|
|
|
|
|
var layoutCount = Object.keys(state.layouts).length;
|
|
|
|
|
if (state) {
|
|
|
|
|
var layout = state.layouts[sourceLayout];
|
|
|
|
|
if (layout) {
|
|
|
|
|
gridSettings = layout.gridSettings;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (gridSettings &&
|
|
|
|
|
gridSettings.columns) {
|
|
|
|
|
originalColumns = gridSettings.columns;
|
2017-03-07 12:26:42 +02:00
|
|
|
}
|
2017-05-24 10:39:33 +03:00
|
|
|
originalColumns = originalColumns * layoutCount;
|
|
|
|
|
return originalColumns;
|
2017-03-07 12:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function getOriginalSize(dashboard, sourceState, sourceLayout, widget) {
|
|
|
|
|
var layout = dashboard.configuration.states[sourceState].layouts[sourceLayout];
|
|
|
|
|
var widgetLayout = layout.widgets[widget.id];
|
2017-03-07 12:26:42 +02:00
|
|
|
return {
|
2017-05-24 10:39:33 +03:00
|
|
|
sizeX: widgetLayout.sizeX,
|
|
|
|
|
sizeY: widgetLayout.sizeY
|
|
|
|
|
}
|
2017-03-07 12:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function prepareWidgetItem(dashboard, sourceState, sourceLayout, widget) {
|
2017-01-06 19:49:00 +02:00
|
|
|
var aliasesInfo = {
|
|
|
|
|
datasourceAliases: {},
|
|
|
|
|
targetDeviceAliases: {}
|
|
|
|
|
};
|
2017-05-24 10:39:33 +03:00
|
|
|
var originalColumns = getOriginalColumns(dashboard, sourceState, sourceLayout);
|
|
|
|
|
var originalSize = getOriginalSize(dashboard, sourceState, sourceLayout, widget);
|
2017-01-06 19:49:00 +02:00
|
|
|
if (widget.config && dashboard.configuration
|
2017-05-24 10:39:33 +03:00
|
|
|
&& dashboard.configuration.entityAliases) {
|
|
|
|
|
var entityAlias;
|
2017-01-06 19:49:00 +02:00
|
|
|
if (widget.config.datasources) {
|
|
|
|
|
for (var i=0;i<widget.config.datasources.length;i++) {
|
|
|
|
|
var datasource = widget.config.datasources[i];
|
2017-05-24 10:39:33 +03:00
|
|
|
if (datasource.type === types.datasourceType.entity && datasource.entityAliasId) {
|
|
|
|
|
entityAlias = dashboard.configuration.entityAliases[datasource.entityAliasId];
|
|
|
|
|
if (entityAlias) {
|
|
|
|
|
aliasesInfo.datasourceAliases[i] = prepareAliasInfo(entityAlias);
|
2017-01-06 19:49:00 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (widget.config.targetDeviceAliasIds) {
|
|
|
|
|
for (i=0;i<widget.config.targetDeviceAliasIds.length;i++) {
|
|
|
|
|
var targetDeviceAliasId = widget.config.targetDeviceAliasIds[i];
|
|
|
|
|
if (targetDeviceAliasId) {
|
2017-05-24 10:39:33 +03:00
|
|
|
entityAlias = dashboard.configuration.entityAliases[targetDeviceAliasId];
|
|
|
|
|
if (entityAlias) {
|
|
|
|
|
aliasesInfo.targetDeviceAliases[i] = prepareAliasInfo(entityAlias);
|
2017-01-06 19:49:00 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return {
|
2016-12-26 17:07:47 +02:00
|
|
|
widget: widget,
|
|
|
|
|
aliasesInfo: aliasesInfo,
|
2017-05-24 10:39:33 +03:00
|
|
|
originalSize: originalSize,
|
2016-12-26 17:07:47 +02:00
|
|
|
originalColumns: originalColumns
|
2017-05-24 10:39:33 +03:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function prepareWidgetReference(dashboard, sourceState, sourceLayout, widget) {
|
|
|
|
|
var originalColumns = getOriginalColumns(dashboard, sourceState, sourceLayout);
|
|
|
|
|
var originalSize = getOriginalSize(dashboard, sourceState, sourceLayout, widget);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
dashboardId: dashboard.id.id,
|
|
|
|
|
sourceState: sourceState,
|
|
|
|
|
sourceLayout: sourceLayout,
|
|
|
|
|
widgetId: widget.id,
|
|
|
|
|
originalSize: originalSize,
|
|
|
|
|
originalColumns: originalColumns
|
|
|
|
|
};
|
2017-01-06 19:49:00 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function copyWidget(dashboard, sourceState, sourceLayout, widget) {
|
|
|
|
|
var widgetItem = prepareWidgetItem(dashboard, sourceState, sourceLayout, widget);
|
2016-12-26 17:07:47 +02:00
|
|
|
bufferStore.set(WIDGET_ITEM, angular.toJson(widgetItem));
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function copyWidgetReference(dashboard, sourceState, sourceLayout, widget) {
|
|
|
|
|
var widgetReference = prepareWidgetReference(dashboard, sourceState, sourceLayout, widget);
|
|
|
|
|
bufferStore.set(WIDGET_REFERENCE, angular.toJson(widgetReference));
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-26 17:07:47 +02:00
|
|
|
function hasWidget() {
|
|
|
|
|
return bufferStore.get(WIDGET_ITEM);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function canPasteWidgetReference(dashboard, state, layout) {
|
|
|
|
|
var widgetReferenceJson = bufferStore.get(WIDGET_REFERENCE);
|
|
|
|
|
if (widgetReferenceJson) {
|
|
|
|
|
var widgetReference = angular.fromJson(widgetReferenceJson);
|
|
|
|
|
if (widgetReference.dashboardId === dashboard.id.id) {
|
|
|
|
|
if ((widgetReference.sourceState != state || widgetReference.sourceLayout != layout)
|
|
|
|
|
&& dashboard.configuration.widgets[widgetReference.widgetId]) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function pasteWidgetReference(targetDashboard, targetState, targetLayout, position) {
|
|
|
|
|
var deferred = $q.defer();
|
|
|
|
|
var widgetReferenceJson = bufferStore.get(WIDGET_REFERENCE);
|
|
|
|
|
if (widgetReferenceJson) {
|
|
|
|
|
var widgetReference = angular.fromJson(widgetReferenceJson);
|
|
|
|
|
var widget = targetDashboard.configuration.widgets[widgetReference.widgetId];
|
|
|
|
|
if (widget) {
|
|
|
|
|
var originalColumns = widgetReference.originalColumns;
|
|
|
|
|
var originalSize = widgetReference.originalSize;
|
|
|
|
|
var targetRow = -1;
|
|
|
|
|
var targetColumn = -1;
|
|
|
|
|
if (position) {
|
|
|
|
|
targetRow = position.row;
|
|
|
|
|
targetColumn = position.column;
|
|
|
|
|
}
|
|
|
|
|
addWidgetToDashboard(targetDashboard, targetState, targetLayout, widget, null,
|
|
|
|
|
null, originalColumns, originalSize, targetRow, targetColumn).then(
|
|
|
|
|
function () {
|
|
|
|
|
deferred.resolve(widget);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
deferred.reject();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
deferred.reject();
|
|
|
|
|
}
|
|
|
|
|
return deferred.promise;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function pasteWidget(targetDashboard, targetState, targetLayout, position, onAliasesUpdateFunction) {
|
|
|
|
|
var deferred = $q.defer();
|
2016-12-26 17:07:47 +02:00
|
|
|
var widgetItemJson = bufferStore.get(WIDGET_ITEM);
|
|
|
|
|
if (widgetItemJson) {
|
|
|
|
|
var widgetItem = angular.fromJson(widgetItemJson);
|
|
|
|
|
var widget = widgetItem.widget;
|
|
|
|
|
var aliasesInfo = widgetItem.aliasesInfo;
|
|
|
|
|
var originalColumns = widgetItem.originalColumns;
|
2017-05-24 10:39:33 +03:00
|
|
|
var originalSize = widgetItem.originalSize;
|
2016-12-26 17:07:47 +02:00
|
|
|
var targetRow = -1;
|
|
|
|
|
var targetColumn = -1;
|
|
|
|
|
if (position) {
|
|
|
|
|
targetRow = position.row;
|
|
|
|
|
targetColumn = position.column;
|
|
|
|
|
}
|
2017-05-24 10:39:33 +03:00
|
|
|
widget.id = utils.guid();
|
|
|
|
|
addWidgetToDashboard(targetDashboard, targetState, targetLayout, widget, aliasesInfo,
|
|
|
|
|
onAliasesUpdateFunction, originalColumns, originalSize, targetRow, targetColumn).then(
|
|
|
|
|
function () {
|
|
|
|
|
deferred.resolve(widget);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
deferred.reject();
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
2017-05-24 10:39:33 +03:00
|
|
|
return deferred.promise;
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function addWidgetToDashboard(dashboard, targetState, targetLayout, widget, aliasesInfo, onAliasesUpdateFunction, originalColumns, originalSize, row, column) {
|
|
|
|
|
var deferred = $q.defer();
|
2016-12-26 17:07:47 +02:00
|
|
|
var theDashboard;
|
|
|
|
|
if (dashboard) {
|
|
|
|
|
theDashboard = dashboard;
|
|
|
|
|
} else {
|
|
|
|
|
theDashboard = {};
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
theDashboard = dashboardUtils.validateAndUpdateDashboard(theDashboard);
|
|
|
|
|
|
|
|
|
|
var callAliasUpdateFunction = false;
|
|
|
|
|
if (aliasesInfo) {
|
|
|
|
|
var newEntityAliases = updateAliases(theDashboard, widget, aliasesInfo);
|
|
|
|
|
var aliasesUpdated = !angular.equals(newEntityAliases, theDashboard.configuration.entityAliases);
|
|
|
|
|
if (aliasesUpdated) {
|
|
|
|
|
theDashboard.configuration.entityAliases = newEntityAliases;
|
|
|
|
|
if (onAliasesUpdateFunction) {
|
|
|
|
|
callAliasUpdateFunction = true;
|
|
|
|
|
}
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-05-24 10:39:33 +03:00
|
|
|
dashboardUtils.addWidgetToLayout(theDashboard, targetState, targetLayout, widget, originalColumns, originalSize, row, column);
|
|
|
|
|
if (callAliasUpdateFunction) {
|
2017-06-07 17:09:04 +03:00
|
|
|
onAliasesUpdateFunction();
|
2017-03-07 12:26:42 +02:00
|
|
|
}
|
2017-06-07 17:09:04 +03:00
|
|
|
deferred.resolve(theDashboard);
|
2017-05-24 10:39:33 +03:00
|
|
|
return deferred.promise;
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updateAliases(dashboard, widget, aliasesInfo) {
|
2017-05-24 10:39:33 +03:00
|
|
|
var entityAliases = angular.copy(dashboard.configuration.entityAliases);
|
2016-12-26 17:07:47 +02:00
|
|
|
var aliasInfo;
|
|
|
|
|
var newAliasId;
|
|
|
|
|
for (var datasourceIndex in aliasesInfo.datasourceAliases) {
|
|
|
|
|
aliasInfo = aliasesInfo.datasourceAliases[datasourceIndex];
|
2017-05-24 10:39:33 +03:00
|
|
|
newAliasId = getEntityAliasId(entityAliases, aliasInfo);
|
|
|
|
|
widget.config.datasources[datasourceIndex].entityAliasId = newAliasId;
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
for (var targetDeviceAliasIndex in aliasesInfo.targetDeviceAliases) {
|
|
|
|
|
aliasInfo = aliasesInfo.targetDeviceAliases[targetDeviceAliasIndex];
|
2017-05-24 10:39:33 +03:00
|
|
|
newAliasId = getEntityAliasId(entityAliases, aliasInfo);
|
2016-12-26 17:07:47 +02:00
|
|
|
widget.config.targetDeviceAliasIds[targetDeviceAliasIndex] = newAliasId;
|
|
|
|
|
}
|
2017-05-24 10:39:33 +03:00
|
|
|
return entityAliases;
|
2017-03-07 12:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function isEntityAliasEqual(alias1, alias2) {
|
2017-06-08 09:24:11 +03:00
|
|
|
return angular.equals(alias1.filter, alias2.filter);
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function getEntityAliasId(entityAliases, aliasInfo) {
|
2016-12-26 17:07:47 +02:00
|
|
|
var newAliasId;
|
2017-05-24 10:39:33 +03:00
|
|
|
for (var aliasId in entityAliases) {
|
|
|
|
|
if (isEntityAliasEqual(entityAliases[aliasId], aliasInfo)) {
|
2016-12-26 17:07:47 +02:00
|
|
|
newAliasId = aliasId;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!newAliasId) {
|
2017-06-08 09:24:11 +03:00
|
|
|
var newAliasName = createEntityAliasName(entityAliases, aliasInfo.alias);
|
2017-06-08 21:15:47 +03:00
|
|
|
newAliasId = utils.guid();
|
2017-06-08 09:24:11 +03:00
|
|
|
entityAliases[newAliasId] = {id: newAliasId, alias: newAliasName, filter: aliasInfo.filter};
|
2016-12-26 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
return newAliasId;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-24 10:39:33 +03:00
|
|
|
function createEntityAliasName(entityAliases, alias) {
|
2016-12-26 17:07:47 +02:00
|
|
|
var c = 0;
|
|
|
|
|
var newAlias = angular.copy(alias);
|
|
|
|
|
var unique = false;
|
|
|
|
|
while (!unique) {
|
|
|
|
|
unique = true;
|
2017-05-24 10:39:33 +03:00
|
|
|
for (var entAliasId in entityAliases) {
|
|
|
|
|
var entAlias = entityAliases[entAliasId];
|
|
|
|
|
if (newAlias === entAlias.alias) {
|
2016-12-26 17:07:47 +02:00
|
|
|
c++;
|
|
|
|
|
newAlias = alias + c;
|
|
|
|
|
unique = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return newAlias;
|
|
|
|
|
}
|
|
|
|
|
}
|