From 5fda7a1d1551b4877dc2deeec02d598573d21e3f Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 21 Jul 2017 18:53:15 +0300 Subject: [PATCH] TB-72: Add ability to edit JSON additional info of relations. --- .../add-relation-dialog.controller.js | 54 -------- .../relation/relation-dialog.controller.js | 125 ++++++++++++++++++ .../app/entity/relation/relation-dialog.scss | 27 ++++ ...alog.tpl.html => relation-dialog.tpl.html} | 22 ++- .../relation/relation-table.directive.js | 55 ++++++-- .../entity/relation/relation-table.tpl.html | 6 + ui/src/app/locale/locale.constant.js | 5 +- 7 files changed, 224 insertions(+), 70 deletions(-) delete mode 100644 ui/src/app/entity/relation/add-relation-dialog.controller.js create mode 100644 ui/src/app/entity/relation/relation-dialog.controller.js create mode 100644 ui/src/app/entity/relation/relation-dialog.scss rename ui/src/app/entity/relation/{add-relation-dialog.tpl.html => relation-dialog.tpl.html} (66%) diff --git a/ui/src/app/entity/relation/add-relation-dialog.controller.js b/ui/src/app/entity/relation/add-relation-dialog.controller.js deleted file mode 100644 index e05be526c7..0000000000 --- a/ui/src/app/entity/relation/add-relation-dialog.controller.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright © 2016-2017 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. - */ -/*@ngInject*/ -export default function AddRelationDialogController($scope, $mdDialog, types, entityRelationService, direction, entityId) { - - var vm = this; - - vm.types = types; - vm.direction = direction; - vm.targetEntityId = {}; - - vm.relation = {}; - if (vm.direction == vm.types.entitySearchDirection.from) { - vm.relation.from = entityId; - } else { - vm.relation.to = entityId; - } - vm.relation.type = types.entityRelationType.contains; - - vm.add = add; - vm.cancel = cancel; - - function cancel() { - $mdDialog.cancel(); - } - - function add() { - if (vm.direction == vm.types.entitySearchDirection.from) { - vm.relation.to = vm.targetEntityId; - } else { - vm.relation.from = vm.targetEntityId; - } - $scope.theForm.$setPristine(); - entityRelationService.saveRelation(vm.relation).then( - function success() { - $mdDialog.hide(); - } - ); - } - -} diff --git a/ui/src/app/entity/relation/relation-dialog.controller.js b/ui/src/app/entity/relation/relation-dialog.controller.js new file mode 100644 index 0000000000..ae50e3033e --- /dev/null +++ b/ui/src/app/entity/relation/relation-dialog.controller.js @@ -0,0 +1,125 @@ +/* + * Copyright © 2016-2017 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 'brace/ext/language_tools'; +import 'brace/mode/json'; +import 'brace/theme/github'; +import beautify from 'js-beautify'; + +import './relation-dialog.scss'; + +const js_beautify = beautify.js; + +/*@ngInject*/ +export default function RelationDialogController($scope, $mdDialog, types, entityRelationService, isAdd, direction, relation, showingCallback) { + + var vm = this; + + vm.types = types; + vm.isAdd = isAdd; + vm.direction = direction; + + showingCallback.onShowing = function(scope, element) { + updateEditorSize(element); + } + + vm.relationAdditionalInfoOptions = { + useWrapMode: false, + mode: 'json', + showGutter: false, + showPrintMargin: false, + theme: 'github', + advanced: { + enableSnippets: false, + enableBasicAutocompletion: false, + enableLiveAutocompletion: false + }, + onLoad: function (_ace) { + vm.editor = _ace; + } + }; + + vm.relation = relation; + if (vm.isAdd) { + vm.relation.type = types.entityRelationType.contains; + vm.targetEntityId = {}; + } else { + if (vm.direction == vm.types.entitySearchDirection.from) { + vm.targetEntityId = vm.relation.to; + } else { + vm.targetEntityId = vm.relation.from; + } + } + + vm.save = save; + vm.cancel = cancel; + + vm.additionalInfo = ''; + + if (vm.relation.additionalInfo) { + vm.additionalInfo = angular.toJson(vm.relation.additionalInfo); + vm.additionalInfo = js_beautify(vm.additionalInfo, {indent_size: 4}); + } + + $scope.$watch('vm.additionalInfo', () => { + $scope.theForm.$setValidity("additionalInfo", true); + }); + + function updateEditorSize(element) { + var newWidth = 600; + var newHeight = 200; + angular.element('#tb-relation-additional-info', element).height(newHeight.toString() + "px") + .width(newWidth.toString() + "px"); + vm.editor.resize(); + } + + function cancel() { + $mdDialog.cancel(); + } + + function save() { + if (vm.isAdd) { + if (vm.direction == vm.types.entitySearchDirection.from) { + vm.relation.to = vm.targetEntityId; + } else { + vm.relation.from = vm.targetEntityId; + } + } + $scope.theForm.$setPristine(); + + var valid = true; + if (vm.additionalInfo && vm.additionalInfo.length) { + try { + vm.relation.additionalInfo = angular.fromJson(vm.additionalInfo); + } catch(e) { + valid = false; + } + } else { + vm.relation.additionalInfo = null; + } + + $scope.theForm.$setValidity("additionalInfo", valid); + + if (valid) { + entityRelationService.saveRelation(vm.relation).then( + function success() { + $mdDialog.hide(); + } + ); + } + } + +} diff --git a/ui/src/app/entity/relation/relation-dialog.scss b/ui/src/app/entity/relation/relation-dialog.scss new file mode 100644 index 0000000000..55064df8fa --- /dev/null +++ b/ui/src/app/entity/relation/relation-dialog.scss @@ -0,0 +1,27 @@ +/** + * Copyright © 2016-2017 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. + */ + +.tb-relation-additional-info-panel { + margin-left: 15px; + border: 1px solid #C0C0C0; + height: 100%; + #tb-relation-additional-info { + min-width: 600px; + min-height: 200px; + width: 100%; + height: 100%; + } +} diff --git a/ui/src/app/entity/relation/add-relation-dialog.tpl.html b/ui/src/app/entity/relation/relation-dialog.tpl.html similarity index 66% rename from ui/src/app/entity/relation/add-relation-dialog.tpl.html rename to ui/src/app/entity/relation/relation-dialog.tpl.html index b45013bded..15b0c7f47b 100644 --- a/ui/src/app/entity/relation/add-relation-dialog.tpl.html +++ b/ui/src/app/entity/relation/relation-dialog.tpl.html @@ -15,11 +15,11 @@ limitations under the License. --> - -
+ +
-

relation.add

+

{{ vm.isAdd ? 'relation.add' : 'relation.edit'}}

@@ -32,17 +32,29 @@
- {{(vm.direction == vm.types.entitySearchDirection.from ? 'relation.to-entity' : 'relation.from-entity') | translate}} +
relation.additional-info
+
+
+
+
+
@@ -51,7 +63,7 @@ - {{ 'action.add' | translate }} + {{ (vm.isAdd ? 'action.add' : 'action.save') | translate }} {{ 'action.cancel' | translate }} diff --git a/ui/src/app/entity/relation/relation-table.directive.js b/ui/src/app/entity/relation/relation-table.directive.js index f0c192b9d1..17436a6f74 100644 --- a/ui/src/app/entity/relation/relation-table.directive.js +++ b/ui/src/app/entity/relation/relation-table.directive.js @@ -19,11 +19,11 @@ import './relation-table.scss'; /* eslint-disable import/no-unresolved, import/default */ import relationTableTemplate from './relation-table.tpl.html'; -import addRelationTemplate from './add-relation-dialog.tpl.html'; +import relationTemplate from './relation-dialog.tpl.html'; /* eslint-enable import/no-unresolved, import/default */ -import AddRelationController from './add-relation-dialog.controller'; +import RelationController from './relation-dialog.controller'; /*@ngInject*/ export default function RelationTable() { @@ -66,6 +66,7 @@ function RelationTableController($scope, $q, $mdDialog, $document, $translate, $ vm.onReorder = onReorder; vm.onPaginate = onPaginate; vm.addRelation = addRelation; + vm.editRelation = editRelation; vm.deleteRelation = deleteRelation; vm.deleteRelations = deleteRelations; vm.reloadRelations = reloadRelations; @@ -110,18 +111,52 @@ function RelationTableController($scope, $q, $mdDialog, $document, $translate, $ if ($event) { $event.stopPropagation(); } - var entityId = { - id: vm.entityId, - entityType: vm.entityType - }; + openRelationDialog($event); + } + + function editRelation($event, relation) { + if ($event) { + $event.stopPropagation(); + } + openRelationDialog($event, relation); + } + + function openRelationDialog($event, relation) { + if ($event) { + $event.stopPropagation(); + } + var isAdd = false; + if (!relation) { + isAdd = true; + var entityId = { + id: vm.entityId, + entityType: vm.entityType + }; + relation = {}; + if (vm.direction == vm.types.entitySearchDirection.from) { + relation.from = entityId; + } else { + relation.to = entityId; + } + } + var onShowingCallback = { + onShowing: function(){} + } $mdDialog.show({ - controller: AddRelationController, + controller: RelationController, controllerAs: 'vm', - templateUrl: addRelationTemplate, + templateUrl: relationTemplate, parent: angular.element($document[0].body), - locals: { direction: vm.direction, entityId: entityId }, + locals: { isAdd: isAdd, + direction: vm.direction, + relation: relation, + showingCallback: onShowingCallback}, + targetEvent: $event, fullscreen: true, - targetEvent: $event + skipHide: true, + onShowing: function(scope, element) { + onShowingCallback.onShowing(scope, element); + } }).then(function () { reloadRelations(); }, function () { diff --git a/ui/src/app/entity/relation/relation-table.tpl.html b/ui/src/app/entity/relation/relation-table.tpl.html index 56970f9815..8599397bc5 100644 --- a/ui/src/app/entity/relation/relation-table.tpl.html +++ b/ui/src/app/entity/relation/relation-table.tpl.html @@ -112,6 +112,12 @@ {{ relation.toName }} {{ relation.fromName }} + + edit + + {{ 'relation.edit' | translate }} + + delete diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js index d5f8dd2ff5..6513ce8821 100644 --- a/ui/src/app/locale/locale.constant.js +++ b/ui/src/app/locale/locale.constant.js @@ -888,6 +888,7 @@ export default angular.module('thingsboard.locale', []) "relation-type-required": "Relation type is required.", "any-relation-type": "Any type", "add": "Add relation", + "edit": "Edit relation", "delete-to-relation-title": "Are you sure you want to delete relation to the entity '{{entityName}}'?", "delete-to-relation-text": "Be careful, after the confirmation the entity '{{entityName}}' will be unrelated from the current entity.", "delete-to-relations-title": "Are you sure you want to delete { count, select, 1 {1 relation} other {# relations} }?", @@ -899,7 +900,9 @@ export default angular.module('thingsboard.locale', []) "remove-relation-filter": "Remove relation filter", "add-relation-filter": "Add relation filter", "any-relation": "Any relation", - "relation-filters": "Relation filters" + "relation-filters": "Relation filters", + "additional-info": "Additional info (JSON)", + "invalid-additional-info": "Unable to parse additional info json." }, "rule": { "rule": "Rule",