Import export extension configuration
This commit is contained in:
parent
32ece471e9
commit
5795e7f259
@ -70,6 +70,7 @@
|
|||||||
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.grid.operatingItem().additionalInfo.gateway" md-on-select="vm.grid.triggerResize()" label="{{ 'extension.extensions' | translate }}">
|
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.grid.operatingItem().additionalInfo.gateway" md-on-select="vm.grid.triggerResize()" label="{{ 'extension.extensions' | translate }}">
|
||||||
<tb-extension-table flex
|
<tb-extension-table flex
|
||||||
entity-id="vm.grid.operatingItem().id.id"
|
entity-id="vm.grid.operatingItem().id.id"
|
||||||
|
entity-name="vm.grid.operatingItem().name"
|
||||||
entity-type="{{vm.types.entityType.device}}">
|
entity-type="{{vm.types.entityType.device}}">
|
||||||
</tb-extension-table>
|
</tb-extension-table>
|
||||||
</md-tab>
|
</md-tab>
|
||||||
|
|||||||
@ -34,7 +34,8 @@ export default function ExtensionTableDirective() {
|
|||||||
scope: true,
|
scope: true,
|
||||||
bindToController: {
|
bindToController: {
|
||||||
entityId: '=',
|
entityId: '=',
|
||||||
entityType: '@'
|
entityType: '@',
|
||||||
|
entityName: '='
|
||||||
},
|
},
|
||||||
controller: ExtensionTableController,
|
controller: ExtensionTableController,
|
||||||
controllerAs: 'vm',
|
controllerAs: 'vm',
|
||||||
@ -43,7 +44,7 @@ export default function ExtensionTableDirective() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*@ngInject*/
|
/*@ngInject*/
|
||||||
function ExtensionTableController($scope, $filter, $document, $translate, types, $mdDialog, attributeService, telemetryWebsocketService) {
|
function ExtensionTableController($scope, $filter, $document, $translate, types, $mdDialog, attributeService, telemetryWebsocketService, importExport) {
|
||||||
|
|
||||||
let vm = this;
|
let vm = this;
|
||||||
|
|
||||||
@ -328,4 +329,21 @@ function ExtensionTableController($scope, $filter, $document, $translate, types,
|
|||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm.importExtensions = function () {
|
||||||
|
importExport.importExtension({"entityType":vm.entityType, "entityId":vm.entityId, "successFunc":reloadExtensions});
|
||||||
|
};
|
||||||
|
vm.exportExtensions = function () {
|
||||||
|
importExport.exportToPc(vm.extensionsJSON, vm.entityName + '_configuration.json');
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.exportExtension = function ($event, extension) {
|
||||||
|
if ($event) {
|
||||||
|
$event.stopPropagation();
|
||||||
|
}
|
||||||
|
importExport.exportToPc(extension, vm.entityName +'_'+ extension.id +'_configuration.json');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -16,10 +16,19 @@
|
|||||||
@import '../../scss/constants';
|
@import '../../scss/constants';
|
||||||
|
|
||||||
|
|
||||||
.extension-table md-input-container .md-errors-spacer {
|
.extension-table {
|
||||||
|
|
||||||
|
md-input-container .md-errors-spacer {
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.tb-data-table table.md-table tbody tr td.tb-action-cell,
|
||||||
|
&.tb-data-table table.md-table.md-row-select tbody tr td.tb-action-cell {
|
||||||
|
width: 114px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.extension__syncStatus--black {
|
.extension__syncStatus--black {
|
||||||
color: #000000!important;
|
color: #000000!important;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,19 @@
|
|||||||
<div class="md-toolbar-tools">
|
<div class="md-toolbar-tools">
|
||||||
<span translate>{{ 'extension.extensions' }}</span>
|
<span translate>{{ 'extension.extensions' }}</span>
|
||||||
<span flex></span>
|
<span flex></span>
|
||||||
|
|
||||||
|
<md-button class="md-icon-button" ng-click="vm.importExtensions($event)">
|
||||||
|
<md-icon>file_upload</md-icon>
|
||||||
|
<md-tooltip md-direction="top">
|
||||||
|
{{ 'extension.sync.import-extensions-configuration' | translate }}
|
||||||
|
</md-tooltip>
|
||||||
|
</md-button>
|
||||||
|
<md-button class="md-icon-button" ng-click="vm.exportExtensions()">
|
||||||
|
<md-icon>file_download</md-icon>
|
||||||
|
<md-tooltip md-direction="top">
|
||||||
|
{{ 'extension.sync.export-extensions-configuration' | translate }}
|
||||||
|
</md-tooltip>
|
||||||
|
</md-button>
|
||||||
<md-button class="md-icon-button" ng-click="vm.addExtension($event)">
|
<md-button class="md-icon-button" ng-click="vm.addExtension($event)">
|
||||||
<md-icon>add</md-icon>
|
<md-icon>add</md-icon>
|
||||||
<md-tooltip md-direction="top">
|
<md-tooltip md-direction="top">
|
||||||
@ -44,7 +57,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</md-toolbar>
|
</md-toolbar>
|
||||||
<md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedExtensions.length
|
<md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedExtensions.length
|
||||||
&& vm.query.search != null"">
|
&& vm.query.search != null">
|
||||||
<div class="md-toolbar-tools">
|
<div class="md-toolbar-tools">
|
||||||
<md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}">
|
<md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}">
|
||||||
<md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon>
|
<md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon>
|
||||||
@ -111,6 +124,12 @@
|
|||||||
<td md-cell>{{ extension.id }}</td>
|
<td md-cell>{{ extension.id }}</td>
|
||||||
<td md-cell>{{ extension.type }}</td>
|
<td md-cell>{{ extension.type }}</td>
|
||||||
<td md-cell class="tb-action-cell">
|
<td md-cell class="tb-action-cell">
|
||||||
|
<md-button class="md-icon-button" aria-label="{{ 'action.edit' | translate }}" ng-click="vm.exportExtension($event, extension)">
|
||||||
|
<md-icon aria-label="{{ 'action.edit' | translate }}" class="material-icons">file_download</md-icon>
|
||||||
|
<md-tooltip md-direction="top">
|
||||||
|
{{ 'extension.export-extension' | translate }}
|
||||||
|
</md-tooltip>
|
||||||
|
</md-button>
|
||||||
<md-button class="md-icon-button" aria-label="{{ 'action.edit' | translate }}" ng-click="vm.editExtension($event, extension)">
|
<md-button class="md-icon-button" aria-label="{{ 'action.edit' | translate }}" ng-click="vm.editExtension($event, extension)">
|
||||||
<md-icon aria-label="{{ 'action.edit' | translate }}" class="material-icons">edit</md-icon>
|
<md-icon aria-label="{{ 'action.edit' | translate }}" class="material-icons">edit</md-icon>
|
||||||
<md-tooltip md-direction="top">
|
<md-tooltip md-direction="top">
|
||||||
|
|||||||
@ -24,8 +24,9 @@ import entityAliasesTemplate from '../entity/alias/entity-aliases.tpl.html';
|
|||||||
/* eslint-disable no-undef, angular/window-service, angular/document-service */
|
/* eslint-disable no-undef, angular/window-service, angular/document-service */
|
||||||
|
|
||||||
/*@ngInject*/
|
/*@ngInject*/
|
||||||
export default function ImportExport($log, $translate, $q, $mdDialog, $document, itembuffer, utils, types, dashboardUtils,
|
export default function ImportExport($log, $translate, $q, $mdDialog, $document, $http, itembuffer, utils, types,
|
||||||
entityService, dashboardService, pluginService, ruleService, widgetService, toast) {
|
dashboardUtils, entityService, dashboardService, pluginService, ruleService,
|
||||||
|
widgetService, toast, attributeService) {
|
||||||
|
|
||||||
|
|
||||||
var service = {
|
var service = {
|
||||||
@ -40,8 +41,11 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
|
|||||||
exportWidgetType: exportWidgetType,
|
exportWidgetType: exportWidgetType,
|
||||||
importWidgetType: importWidgetType,
|
importWidgetType: importWidgetType,
|
||||||
exportWidgetsBundle: exportWidgetsBundle,
|
exportWidgetsBundle: exportWidgetsBundle,
|
||||||
importWidgetsBundle: importWidgetsBundle
|
importWidgetsBundle: importWidgetsBundle,
|
||||||
}
|
exportExtension: exportExtension,
|
||||||
|
importExtension: importExtension,
|
||||||
|
exportToPc: exportToPc
|
||||||
|
};
|
||||||
|
|
||||||
return service;
|
return service;
|
||||||
|
|
||||||
@ -614,6 +618,89 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function exportExtension(extensionId) {
|
||||||
|
|
||||||
|
getExtension(extensionId)
|
||||||
|
.then(
|
||||||
|
function success(extension) {
|
||||||
|
var name = extension.title;
|
||||||
|
name = name.toLowerCase().replace(/\W/g,"_");
|
||||||
|
exportToPc(prepareExport(extension), name + '.json');
|
||||||
|
},
|
||||||
|
function fail(rejection) {
|
||||||
|
var message = rejection;
|
||||||
|
if (!message) {
|
||||||
|
message = $translate.instant('error.unknown-error');
|
||||||
|
}
|
||||||
|
toast.showError($translate.instant('extension.export-failed-error', {error: message}));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
function getExtension(extensionId) {
|
||||||
|
var deferred = $q.defer();
|
||||||
|
var url = '/api/plugins/telemetry/DEVICE/' + extensionId;
|
||||||
|
$http.get(url, null)
|
||||||
|
.then(function success(response) {
|
||||||
|
deferred.resolve(response.data);
|
||||||
|
}, function fail() {
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function importExtension(options) {
|
||||||
|
var deferred = $q.defer();
|
||||||
|
openImportDialog(options, 'extension.import-extensions', 'extension.file')
|
||||||
|
.then(
|
||||||
|
function success(extension) {
|
||||||
|
if (!validateImportedExtension(extension)) {
|
||||||
|
toast.showError($translate.instant('extension.invalid-file-error'));
|
||||||
|
deferred.reject();
|
||||||
|
} else {
|
||||||
|
attributeService
|
||||||
|
.saveEntityAttributes(
|
||||||
|
options.entityType,
|
||||||
|
options.entityId,
|
||||||
|
types.attributesScope.shared.value,
|
||||||
|
[{
|
||||||
|
key: "configuration",
|
||||||
|
value: angular.toJson(extension)
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
.then(function success() {
|
||||||
|
options.successFunc();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function fail() {
|
||||||
|
deferred.reject();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function validateImportedExtension(configuration) {
|
||||||
|
if (configuration.length) {
|
||||||
|
for (let i = 0; i < configuration.length; i++) {
|
||||||
|
if (angular.isUndefined(configuration[i].configuration) || angular.isUndefined(configuration[i].id )|| angular.isUndefined(configuration[i].type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function processEntityAliases(entityAliases, aliasIds) {
|
function processEntityAliases(entityAliases, aliasIds) {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
var missingEntityAliases = {};
|
var missingEntityAliases = {};
|
||||||
|
|||||||
@ -845,8 +845,16 @@ export default angular.module('thingsboard.locale', [])
|
|||||||
"sync": "Sync",
|
"sync": "Sync",
|
||||||
"not-sync": "Not sync",
|
"not-sync": "Not sync",
|
||||||
"last-sync-time": "Last sync time",
|
"last-sync-time": "Last sync time",
|
||||||
"not-available": "Not available"
|
"not-available": "Not available",
|
||||||
|
"export-extensions-configuration":"Export extensions configuration",
|
||||||
|
"import-extensions-configuration":"Import extensions configuration"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"import-extensions": "Import extensions",
|
||||||
|
"import-extension": "Import extension",
|
||||||
|
"export-extension": "Export extension",
|
||||||
|
"file": "Extensions file",
|
||||||
|
"invalid-file-error": "Invalid extension file"
|
||||||
},
|
},
|
||||||
"fullscreen": {
|
"fullscreen": {
|
||||||
"expand": "Expand to fullscreen",
|
"expand": "Expand to fullscreen",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user