thingsboard-memoizeit

Details

diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js
index cca2a11..a7b2b44 100644
--- a/ui/src/app/locale/locale.constant.js
+++ b/ui/src/app/locale/locale.constant.js
@@ -1177,6 +1177,7 @@ export default angular.module('thingsboard.locale', [])
                     "type": "Type",
                     "description": "Description",
                     "delete": "Delete rule node",
+                    "delete-selected-objects": "Delete selected nodes and connections",
                     "rulenode-details": "Rule node details",
                     "debug-mode": "Debug mode",
                     "configuration": "Configuration",
diff --git a/ui/src/app/rulechain/rulechain.controller.js b/ui/src/app/rulechain/rulechain.controller.js
index b792f13..565e72b 100644
--- a/ui/src/app/rulechain/rulechain.controller.js
+++ b/ui/src/app/rulechain/rulechain.controller.js
@@ -81,6 +81,9 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
     vm.saveRuleChain = saveRuleChain;
     vm.revertRuleChain = revertRuleChain;
 
+    vm.objectsSelected = objectsSelected;
+    vm.deleteSelected = deleteSelected;
+
     vm.keyDown = function (evt) {
         if (evt.keyCode === ctrlKeyCode) {
             vm.ctrlDown = true;
@@ -632,6 +635,14 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
         });
     }
 
+    function objectsSelected() {
+        return vm.modelservice.nodes.getSelectedNodes().length > 0 ||
+            vm.modelservice.edges.getSelectedEdges().length > 0
+    }
+
+    function deleteSelected() {
+        vm.modelservice.deleteSelected();
+    }
 }
 
 /*@ngInject*/
diff --git a/ui/src/app/rulechain/rulechain.scss b/ui/src/app/rulechain/rulechain.scss
index 26a5225..c1d1376 100644
--- a/ui/src/app/rulechain/rulechain.scss
+++ b/ui/src/app/rulechain/rulechain.scss
@@ -121,10 +121,6 @@
 .fc-node {
   z-index: 1;
   outline: none;
-  &.fc-hover, &.fc-selected {
-    -webkit-filter: brightness(70%);
-    filter: brightness(70%);
-  }
   &.fc-dragging {
     z-index: 10;
   }
@@ -132,6 +128,26 @@
     padding: 0 15px;
     text-align: center;
   }
+  .fc-node-overlay {
+    position: absolute;
+    pointer-events: none;
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    background-color: #000;
+    opacity: 0;
+  }
+  &.fc-hover {
+    .fc-node-overlay {
+      opacity: 0.25;
+    }
+  }
+  &.fc-selected {
+    .fc-node-overlay {
+      opacity: 0.25;
+    }
+  }
 }
 
 .fc-leftConnectors, .fc-rightConnectors {
@@ -181,6 +197,7 @@
   stroke: gray;
   stroke-width: 4;
   fill: transparent;
+  transition: stroke-width .2s;
   &.fc-selected {
     stroke: red;
     stroke-width: 4;
@@ -232,20 +249,29 @@
 .fc-edge-label {
   position: absolute;
   user-select: none;
-  pointer-events: none;
+  transition: transform .2s;
   opacity: 0.8;
+  &.fc-hover {
+    transform: scale(1.25);
+  }
+  &.fc-selected {
+    .fc-edge-label-text {
+      span {
+        border: solid red;
+        color: red;
+      }
+    }
+  }
 }
 
 .fc-edge-label-text {
   position: absolute;
-  left: 50%;
-  -webkit-transform: translateX(-50%);
-  transform: translateX(-50%);
+  -webkit-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
   white-space: nowrap;
   text-align: center;
   font-size: 14px;
   font-weight: 600;
-  top: 5px;
   span {
     border: solid 2px #003a79;
     border-radius: 10px;
@@ -255,6 +281,13 @@
   }
 }
 
+.fc-select-rectangle {
+  border: 2px dashed #5262ff;
+  position: absolute;
+  background: rgba(20,125,255,0.1);
+  z-index: 2;
+}
+
 @keyframes dash {
   from {
     stroke-dashoffset: 500;
diff --git a/ui/src/app/rulechain/rulechain.tpl.html b/ui/src/app/rulechain/rulechain.tpl.html
index 9f1141e..eec376e 100644
--- a/ui/src/app/rulechain/rulechain.tpl.html
+++ b/ui/src/app/rulechain/rulechain.tpl.html
@@ -112,6 +112,13 @@
         </tb-details-sidenav>
     </section>
     <section layout="row" layout-wrap class="tb-footer-buttons md-fab" layout-align="start end">
+        <md-button ng-disabled="$root.loading" ng-show="vm.objectsSelected()" class="tb-btn-footer md-accent md-hue-2 md-fab"
+                   ng-click="vm.deleteSelected()" aria-label="{{ 'action.delete' | translate }}">
+            <md-tooltip md-direction="top">
+                {{ 'rulenode.delete-selected-objects' | translate }}
+            </md-tooltip>
+            <ng-md-icon icon="delete"></ng-md-icon>
+        </md-button>
         <md-button ng-disabled="$root.loading || !vm.isDirty"
                    class="tb-btn-footer md-accent md-hue-2 md-fab"
                    aria-label="{{ 'action.apply' | translate }}"
diff --git a/ui/src/app/rulechain/rulenode.tpl.html b/ui/src/app/rulechain/rulenode.tpl.html
index ffc8a0f..55ee3d3 100644
--- a/ui/src/app/rulechain/rulenode.tpl.html
+++ b/ui/src/app/rulechain/rulenode.tpl.html
@@ -22,6 +22,7 @@
         ng-mousedown="callbacks.mouseDown($event, node)"
         ng-mouseenter="callbacks.mouseEnter($event, node)"
         ng-mouseleave="callbacks.mouseLeave($event, node)">
+    <div class="{{flowchartConstants.nodeOverlayClass}}"></div>
     <div class="tb-rule-node {{node.nodeClass}}">
         <md-icon aria-label="node-type-icon" flex="15"
                  class="material-icons">{{node.icon}}</md-icon>