committed by
GitHub
28 changed files with 928 additions and 134 deletions
@ -0,0 +1,71 @@ |
|||||
|
/* |
||||
|
* Copyright © 2016 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 './import-dialog.scss'; |
||||
|
|
||||
|
/*@ngInject*/ |
||||
|
export default function ImportDialogController($scope, $mdDialog, toast, importTitle, importFileLabel) { |
||||
|
|
||||
|
var vm = this; |
||||
|
|
||||
|
vm.cancel = cancel; |
||||
|
vm.importFromJson = importFromJson; |
||||
|
vm.fileAdded = fileAdded; |
||||
|
vm.clearFile = clearFile; |
||||
|
|
||||
|
vm.importTitle = importTitle; |
||||
|
vm.importFileLabel = importFileLabel; |
||||
|
|
||||
|
|
||||
|
function cancel() { |
||||
|
$mdDialog.cancel(); |
||||
|
} |
||||
|
|
||||
|
function fileAdded($file) { |
||||
|
if ($file.getExtension() === 'json') { |
||||
|
var reader = new FileReader(); |
||||
|
reader.onload = function(event) { |
||||
|
$scope.$apply(function() { |
||||
|
if (event.target.result) { |
||||
|
$scope.theForm.$setDirty(); |
||||
|
var importJson = event.target.result; |
||||
|
if (importJson && importJson.length > 0) { |
||||
|
try { |
||||
|
vm.importData = angular.fromJson(importJson); |
||||
|
vm.fileName = $file.name; |
||||
|
} catch (err) { |
||||
|
vm.fileName = null; |
||||
|
toast.showError(err.message); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
reader.readAsText($file.file); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function clearFile() { |
||||
|
$scope.theForm.$setDirty(); |
||||
|
vm.fileName = null; |
||||
|
vm.importData = null; |
||||
|
} |
||||
|
|
||||
|
function importFromJson() { |
||||
|
$scope.theForm.$setPristine(); |
||||
|
$mdDialog.hide(vm.importData); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016 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. |
||||
|
*/ |
||||
|
$previewSize: 100px; |
||||
|
|
||||
|
.file-input { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.tb-container { |
||||
|
position: relative; |
||||
|
margin-top: 32px; |
||||
|
padding: 10px 0; |
||||
|
} |
||||
|
|
||||
|
.tb-file-select-container { |
||||
|
position: relative; |
||||
|
height: $previewSize; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.tb-file-preview { |
||||
|
max-width: $previewSize; |
||||
|
max-height: $previewSize; |
||||
|
width: auto; |
||||
|
height: auto; |
||||
|
} |
||||
|
|
||||
|
.tb-flow-drop { |
||||
|
position: relative; |
||||
|
border: dashed 2px; |
||||
|
height: $previewSize; |
||||
|
vertical-align: top; |
||||
|
padding: 0 8px; |
||||
|
overflow: hidden; |
||||
|
min-width: 300px; |
||||
|
label { |
||||
|
width: 100%; |
||||
|
font-size: 24px; |
||||
|
text-align: center; |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
left: 50%; |
||||
|
transform: translate(-50%,-50%); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tb-file-clear-container { |
||||
|
width: 48px; |
||||
|
height: $previewSize; |
||||
|
position: relative; |
||||
|
float: right; |
||||
|
} |
||||
|
.tb-file-clear-btn { |
||||
|
position: absolute !important; |
||||
|
top: 50%; |
||||
|
transform: translate(0%,-50%) !important; |
||||
|
} |
||||
@ -0,0 +1,72 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016 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. |
||||
|
|
||||
|
--> |
||||
|
<md-dialog aria-label="{{ vm.importTitle | translate }}"> |
||||
|
<form name="theForm" ng-submit="vm.importFromJson()"> |
||||
|
<md-toolbar> |
||||
|
<div class="md-toolbar-tools"> |
||||
|
<h2 translate>{{ vm.importTitle }}</h2> |
||||
|
<span flex></span> |
||||
|
<md-button class="md-icon-button" ng-click="vm.cancel()"> |
||||
|
<ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> |
||||
|
</md-button> |
||||
|
</div> |
||||
|
</md-toolbar> |
||||
|
<md-progress-linear class="md-warn" md-mode="indeterminate" ng-show="loading"></md-progress-linear> |
||||
|
<span style="min-height: 5px;" flex="" ng-show="!loading"></span> |
||||
|
<md-dialog-content> |
||||
|
<div class="md-dialog-content"> |
||||
|
<fieldset ng-disabled="loading"> |
||||
|
<div layout="column" layout-padding> |
||||
|
<div class="tb-container"> |
||||
|
<label class="tb-label" translate>{{ vm.importFileLabel }}</label> |
||||
|
<div flow-init="{singleFile:true}" |
||||
|
flow-file-added="vm.fileAdded( $file )" class="tb-file-select-container"> |
||||
|
<div class="tb-file-clear-container"> |
||||
|
<md-button ng-click="vm.clearFile()" |
||||
|
class="tb-file-clear-btn md-icon-button md-primary" aria-label="{{ 'action.remove' | translate }}"> |
||||
|
<md-tooltip md-direction="top"> |
||||
|
{{ 'action.remove' | translate }} |
||||
|
</md-tooltip> |
||||
|
<md-icon aria-label="{{ 'action.remove' | translate }}" class="material-icons"> |
||||
|
close |
||||
|
</md-icon> |
||||
|
</md-button> |
||||
|
</div> |
||||
|
<div class="alert tb-flow-drop" flow-drop> |
||||
|
<label for="select" translate>import.drop-file</label> |
||||
|
<input class="file-input" flow-btn flow-attrs="{accept:'.json,application/json'}" id="select"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div> |
||||
|
<div ng-show="!vm.fileName" translate>import.no-file</div> |
||||
|
<div ng-show="vm.fileName">{{ vm.fileName }}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</fieldset> |
||||
|
</div> |
||||
|
</md-dialog-content> |
||||
|
<md-dialog-actions layout="row"> |
||||
|
<span flex></span> |
||||
|
<md-button ng-disabled="loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit" class="md-raised md-primary"> |
||||
|
{{ 'action.import' | translate }} |
||||
|
</md-button> |
||||
|
<md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> |
||||
|
</md-dialog-actions> |
||||
|
</form> |
||||
|
</md-dialog> |
||||
@ -0,0 +1,373 @@ |
|||||
|
/* |
||||
|
* Copyright © 2016 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. |
||||
|
*/ |
||||
|
|
||||
|
/* eslint-disable import/no-unresolved, import/default */ |
||||
|
|
||||
|
import importDialogTemplate from './import-dialog.tpl.html'; |
||||
|
import deviceAliasesTemplate from '../dashboard/device-aliases.tpl.html'; |
||||
|
|
||||
|
/* eslint-enable import/no-unresolved, import/default */ |
||||
|
|
||||
|
|
||||
|
/* eslint-disable no-undef, angular/window-service, angular/document-service */ |
||||
|
|
||||
|
/*@ngInject*/ |
||||
|
export default function ImportExport($log, $translate, $q, $mdDialog, $document, itembuffer, deviceService, dashboardService, toast) { |
||||
|
|
||||
|
|
||||
|
var service = { |
||||
|
exportDashboard: exportDashboard, |
||||
|
importDashboard: importDashboard, |
||||
|
exportWidget: exportWidget, |
||||
|
importWidget: importWidget |
||||
|
} |
||||
|
|
||||
|
return service; |
||||
|
|
||||
|
// Widget functions
|
||||
|
|
||||
|
function exportWidget(dashboard, widget) { |
||||
|
var widgetItem = itembuffer.prepareWidgetItem(dashboard, widget); |
||||
|
var name = widgetItem.widget.config.title; |
||||
|
name = name.toLowerCase().replace(/\W/g,"_"); |
||||
|
exportToPc(prepareExport(widgetItem), name + '.json'); |
||||
|
} |
||||
|
|
||||
|
function importWidget($event, dashboard) { |
||||
|
openImportDialog($event, 'dashboard.import-widget', 'dashboard.widget-file').then( |
||||
|
function success(widgetItem) { |
||||
|
if (!validateImportedWidget(widgetItem)) { |
||||
|
toast.showError($translate.instant('dashboard.invalid-widget-file-error')); |
||||
|
} else { |
||||
|
var widget = widgetItem.widget; |
||||
|
var aliasesInfo = widgetItem.aliasesInfo; |
||||
|
var originalColumns = widgetItem.originalColumns; |
||||
|
|
||||
|
var datasourceAliases = aliasesInfo.datasourceAliases; |
||||
|
var targetDeviceAliases = aliasesInfo.targetDeviceAliases; |
||||
|
if (datasourceAliases || targetDeviceAliases) { |
||||
|
var deviceAliases = {}; |
||||
|
var datasourceAliasesMap = {}; |
||||
|
var targetDeviceAliasesMap = {}; |
||||
|
var aliasId = 1; |
||||
|
var datasourceIndex; |
||||
|
if (datasourceAliases) { |
||||
|
for (datasourceIndex in datasourceAliases) { |
||||
|
datasourceAliasesMap[aliasId] = datasourceIndex; |
||||
|
deviceAliases[aliasId] = { |
||||
|
alias: datasourceAliases[datasourceIndex].aliasName, |
||||
|
deviceId: datasourceAliases[datasourceIndex].deviceId |
||||
|
}; |
||||
|
aliasId++; |
||||
|
} |
||||
|
} |
||||
|
if (targetDeviceAliases) { |
||||
|
for (datasourceIndex in targetDeviceAliases) { |
||||
|
targetDeviceAliasesMap[aliasId] = datasourceIndex; |
||||
|
deviceAliases[aliasId] = { |
||||
|
alias: targetDeviceAliases[datasourceIndex].aliasName, |
||||
|
deviceId: targetDeviceAliases[datasourceIndex].deviceId |
||||
|
}; |
||||
|
aliasId++; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var aliasIds = Object.keys(deviceAliases); |
||||
|
if (aliasIds.length > 0) { |
||||
|
processDeviceAliases(deviceAliases, aliasIds).then( |
||||
|
function(missingDeviceAliases) { |
||||
|
if (Object.keys(missingDeviceAliases).length > 0) { |
||||
|
editMissingAliases($event, [ widget ], |
||||
|
true, 'dashboard.widget-import-missing-aliases-title', missingDeviceAliases).then( |
||||
|
function success(updatedDeviceAliases) { |
||||
|
for (var aliasId in updatedDeviceAliases) { |
||||
|
var deviceAlias = updatedDeviceAliases[aliasId]; |
||||
|
var datasourceIndex; |
||||
|
if (datasourceAliasesMap[aliasId]) { |
||||
|
datasourceIndex = datasourceAliasesMap[aliasId]; |
||||
|
datasourceAliases[datasourceIndex].deviceId = deviceAlias.deviceId; |
||||
|
} else if (targetDeviceAliasesMap[aliasId]) { |
||||
|
datasourceIndex = targetDeviceAliasesMap[aliasId]; |
||||
|
targetDeviceAliases[datasourceIndex].deviceId = deviceAlias.deviceId; |
||||
|
} |
||||
|
} |
||||
|
addImportedWidget(dashboard, widget, aliasesInfo, originalColumns); |
||||
|
}, |
||||
|
function fail() {} |
||||
|
); |
||||
|
} else { |
||||
|
addImportedWidget(dashboard, widget, aliasesInfo, originalColumns); |
||||
|
} |
||||
|
} |
||||
|
); |
||||
|
} else { |
||||
|
addImportedWidget(dashboard, widget, aliasesInfo, originalColumns); |
||||
|
} |
||||
|
} else { |
||||
|
addImportedWidget(dashboard, widget, aliasesInfo, originalColumns); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
function fail() {} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
function validateImportedWidget(widgetItem) { |
||||
|
if (angular.isUndefined(widgetItem.widget) |
||||
|
|| angular.isUndefined(widgetItem.aliasesInfo) |
||||
|
|| angular.isUndefined(widgetItem.originalColumns)) { |
||||
|
return false; |
||||
|
} |
||||
|
var widget = widgetItem.widget; |
||||
|
if (angular.isUndefined(widget.isSystemType) || |
||||
|
angular.isUndefined(widget.bundleAlias) || |
||||
|
angular.isUndefined(widget.typeAlias) || |
||||
|
angular.isUndefined(widget.type)) { |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
function addImportedWidget(dashboard, widget, aliasesInfo, originalColumns) { |
||||
|
itembuffer.addWidgetToDashboard(dashboard, widget, aliasesInfo, originalColumns, -1, -1); |
||||
|
} |
||||
|
|
||||
|
// Dashboard functions
|
||||
|
|
||||
|
function exportDashboard(dashboardId) { |
||||
|
dashboardService.getDashboard(dashboardId).then( |
||||
|
function success(dashboard) { |
||||
|
var name = dashboard.title; |
||||
|
name = name.toLowerCase().replace(/\W/g,"_"); |
||||
|
exportToPc(prepareExport(dashboard), name + '.json'); |
||||
|
}, |
||||
|
function fail(rejection) { |
||||
|
var message = rejection; |
||||
|
if (!message) { |
||||
|
message = $translate.instant('error.unknown-error'); |
||||
|
} |
||||
|
toast.showError($translate.instant('dashboard.export-failed-error', {error: message})); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
function importDashboard($event) { |
||||
|
var deferred = $q.defer(); |
||||
|
openImportDialog($event, 'dashboard.import', 'dashboard.dashboard-file').then( |
||||
|
function success(dashboard) { |
||||
|
if (!validateImportedDashboard(dashboard)) { |
||||
|
toast.showError($translate.instant('dashboard.invalid-dashboard-file-error')); |
||||
|
deferred.reject(); |
||||
|
} else { |
||||
|
var deviceAliases = dashboard.configuration.deviceAliases; |
||||
|
if (deviceAliases) { |
||||
|
var aliasIds = Object.keys( deviceAliases ); |
||||
|
if (aliasIds.length > 0) { |
||||
|
processDeviceAliases(deviceAliases, aliasIds).then( |
||||
|
function(missingDeviceAliases) { |
||||
|
if (Object.keys( missingDeviceAliases ).length > 0) { |
||||
|
editMissingAliases($event, dashboard.configuration.widgets, |
||||
|
false, 'dashboard.dashboard-import-missing-aliases-title', missingDeviceAliases).then( |
||||
|
function success(updatedDeviceAliases) { |
||||
|
for (var aliasId in updatedDeviceAliases) { |
||||
|
deviceAliases[aliasId] = updatedDeviceAliases[aliasId]; |
||||
|
} |
||||
|
saveImportedDashboard(dashboard, deferred); |
||||
|
}, |
||||
|
function fail() { |
||||
|
deferred.reject(); |
||||
|
} |
||||
|
); |
||||
|
} else { |
||||
|
saveImportedDashboard(dashboard, deferred); |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
} else { |
||||
|
saveImportedDashboard(dashboard, deferred); |
||||
|
} |
||||
|
} else { |
||||
|
saveImportedDashboard(dashboard, deferred); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
function fail() { |
||||
|
deferred.reject(); |
||||
|
} |
||||
|
); |
||||
|
return deferred.promise; |
||||
|
} |
||||
|
|
||||
|
function saveImportedDashboard(dashboard, deferred) { |
||||
|
dashboardService.saveDashboard(dashboard).then( |
||||
|
function success() { |
||||
|
deferred.resolve(); |
||||
|
}, |
||||
|
function fail() { |
||||
|
deferred.reject(); |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function validateImportedDashboard(dashboard) { |
||||
|
if (angular.isUndefined(dashboard.title) || angular.isUndefined(dashboard.configuration)) { |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
function processDeviceAliases(deviceAliases, aliasIds) { |
||||
|
var deferred = $q.defer(); |
||||
|
var missingDeviceAliases = {}; |
||||
|
var index = -1; |
||||
|
checkNextDeviceAliasOrComplete(index, aliasIds, deviceAliases, missingDeviceAliases, deferred); |
||||
|
return deferred.promise; |
||||
|
} |
||||
|
|
||||
|
function checkNextDeviceAliasOrComplete(index, aliasIds, deviceAliases, missingDeviceAliases, deferred) { |
||||
|
index++; |
||||
|
if (index == aliasIds.length) { |
||||
|
deferred.resolve(missingDeviceAliases); |
||||
|
} else { |
||||
|
checkDeviceAlias(index, aliasIds, deviceAliases, missingDeviceAliases, deferred); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function checkDeviceAlias(index, aliasIds, deviceAliases, missingDeviceAliases, deferred) { |
||||
|
var aliasId = aliasIds[index]; |
||||
|
var deviceAlias = deviceAliases[aliasId]; |
||||
|
if (deviceAlias.deviceId) { |
||||
|
deviceService.getDevice(deviceAlias.deviceId, true).then( |
||||
|
function success() { |
||||
|
checkNextDeviceAliasOrComplete(index, aliasIds, deviceAliases, missingDeviceAliases, deferred); |
||||
|
}, |
||||
|
function fail() { |
||||
|
var missingDeviceAlias = angular.copy(deviceAlias); |
||||
|
missingDeviceAlias.deviceId = null; |
||||
|
missingDeviceAliases[aliasId] = missingDeviceAlias; |
||||
|
checkNextDeviceAliasOrComplete(index, aliasIds, deviceAliases, missingDeviceAliases, deferred); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function editMissingAliases($event, widgets, isSingleWidget, customTitle, missingDeviceAliases) { |
||||
|
var deferred = $q.defer(); |
||||
|
$mdDialog.show({ |
||||
|
controller: 'DeviceAliasesController', |
||||
|
controllerAs: 'vm', |
||||
|
templateUrl: deviceAliasesTemplate, |
||||
|
locals: { |
||||
|
config: { |
||||
|
deviceAliases: missingDeviceAliases, |
||||
|
widgets: widgets, |
||||
|
isSingleWidget: isSingleWidget, |
||||
|
isSingleDevice: false, |
||||
|
singleDeviceAlias: null, |
||||
|
customTitle: customTitle, |
||||
|
disableAdd: true |
||||
|
} |
||||
|
}, |
||||
|
parent: angular.element($document[0].body), |
||||
|
skipHide: true, |
||||
|
fullscreen: true, |
||||
|
targetEvent: $event |
||||
|
}).then(function (updatedDeviceAliases) { |
||||
|
deferred.resolve(updatedDeviceAliases); |
||||
|
}, function () { |
||||
|
deferred.reject(); |
||||
|
}); |
||||
|
return deferred.promise; |
||||
|
} |
||||
|
|
||||
|
// Common functions
|
||||
|
|
||||
|
function prepareExport(data) { |
||||
|
var exportedData = angular.copy(data); |
||||
|
if (angular.isDefined(exportedData.id)) { |
||||
|
delete exportedData.id; |
||||
|
} |
||||
|
if (angular.isDefined(exportedData.createdTime)) { |
||||
|
delete exportedData.createdTime; |
||||
|
} |
||||
|
if (angular.isDefined(exportedData.tenantId)) { |
||||
|
delete exportedData.tenantId; |
||||
|
} |
||||
|
if (angular.isDefined(exportedData.customerId)) { |
||||
|
delete exportedData.customerId; |
||||
|
} |
||||
|
return exportedData; |
||||
|
} |
||||
|
|
||||
|
function exportToPc(data, filename) { |
||||
|
if (!data) { |
||||
|
$log.error('No data'); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!filename) { |
||||
|
filename = 'download.json'; |
||||
|
} |
||||
|
|
||||
|
if (angular.isObject(data)) { |
||||
|
data = angular.toJson(data, 2); |
||||
|
} |
||||
|
|
||||
|
var blob = new Blob([data], {type: 'text/json'}); |
||||
|
|
||||
|
// FOR IE:
|
||||
|
|
||||
|
if (window.navigator && window.navigator.msSaveOrOpenBlob) { |
||||
|
window.navigator.msSaveOrOpenBlob(blob, filename); |
||||
|
} |
||||
|
else{ |
||||
|
var e = document.createEvent('MouseEvents'), |
||||
|
a = document.createElement('a'); |
||||
|
|
||||
|
a.download = filename; |
||||
|
a.href = window.URL.createObjectURL(blob); |
||||
|
a.dataset.downloadurl = ['text/json', a.download, a.href].join(':'); |
||||
|
e.initEvent('click', true, false, window, |
||||
|
0, 0, 0, 0, 0, false, false, false, false, 0, null); |
||||
|
a.dispatchEvent(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function openImportDialog($event, importTitle, importFileLabel) { |
||||
|
var deferred = $q.defer(); |
||||
|
$mdDialog.show({ |
||||
|
controller: 'ImportDialogController', |
||||
|
controllerAs: 'vm', |
||||
|
templateUrl: importDialogTemplate, |
||||
|
locals: { |
||||
|
importTitle: importTitle, |
||||
|
importFileLabel: importFileLabel |
||||
|
}, |
||||
|
parent: angular.element($document[0].body), |
||||
|
skipHide: true, |
||||
|
fullscreen: true, |
||||
|
targetEvent: $event |
||||
|
}).then(function (importData) { |
||||
|
deferred.resolve(importData); |
||||
|
}, function () { |
||||
|
deferred.reject(); |
||||
|
}); |
||||
|
return deferred.promise; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/* eslint-enable no-undef, angular/window-service, angular/document-service */ |
||||
@ -0,0 +1,24 @@ |
|||||
|
/* |
||||
|
* Copyright © 2016 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 ImportExport from './import-export.service'; |
||||
|
import ImportDialogController from './import-dialog.controller'; |
||||
|
|
||||
|
|
||||
|
export default angular.module('thingsboard.importexport', []) |
||||
|
.factory('importExport', ImportExport) |
||||
|
.controller('ImportDialogController', ImportDialogController) |
||||
|
.name; |
||||
Loading…
Reference in new issue