Commit 7b1a39fb68f153daf2f48c7aa7198d4deaab95d3
1 parent
68a943e2
Rule Chain hover and select improvements.
Showing
5 changed files
with
62 additions
and
9 deletions
@@ -1177,6 +1177,7 @@ export default angular.module('thingsboard.locale', []) | @@ -1177,6 +1177,7 @@ export default angular.module('thingsboard.locale', []) | ||
1177 | "type": "Type", | 1177 | "type": "Type", |
1178 | "description": "Description", | 1178 | "description": "Description", |
1179 | "delete": "Delete rule node", | 1179 | "delete": "Delete rule node", |
1180 | + "delete-selected-objects": "Delete selected nodes and connections", | ||
1180 | "rulenode-details": "Rule node details", | 1181 | "rulenode-details": "Rule node details", |
1181 | "debug-mode": "Debug mode", | 1182 | "debug-mode": "Debug mode", |
1182 | "configuration": "Configuration", | 1183 | "configuration": "Configuration", |
@@ -81,6 +81,9 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil, | @@ -81,6 +81,9 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil, | ||
81 | vm.saveRuleChain = saveRuleChain; | 81 | vm.saveRuleChain = saveRuleChain; |
82 | vm.revertRuleChain = revertRuleChain; | 82 | vm.revertRuleChain = revertRuleChain; |
83 | 83 | ||
84 | + vm.objectsSelected = objectsSelected; | ||
85 | + vm.deleteSelected = deleteSelected; | ||
86 | + | ||
84 | vm.keyDown = function (evt) { | 87 | vm.keyDown = function (evt) { |
85 | if (evt.keyCode === ctrlKeyCode) { | 88 | if (evt.keyCode === ctrlKeyCode) { |
86 | vm.ctrlDown = true; | 89 | vm.ctrlDown = true; |
@@ -632,6 +635,14 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil, | @@ -632,6 +635,14 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil, | ||
632 | }); | 635 | }); |
633 | } | 636 | } |
634 | 637 | ||
638 | + function objectsSelected() { | ||
639 | + return vm.modelservice.nodes.getSelectedNodes().length > 0 || | ||
640 | + vm.modelservice.edges.getSelectedEdges().length > 0 | ||
641 | + } | ||
642 | + | ||
643 | + function deleteSelected() { | ||
644 | + vm.modelservice.deleteSelected(); | ||
645 | + } | ||
635 | } | 646 | } |
636 | 647 | ||
637 | /*@ngInject*/ | 648 | /*@ngInject*/ |
@@ -121,10 +121,6 @@ | @@ -121,10 +121,6 @@ | ||
121 | .fc-node { | 121 | .fc-node { |
122 | z-index: 1; | 122 | z-index: 1; |
123 | outline: none; | 123 | outline: none; |
124 | - &.fc-hover, &.fc-selected { | ||
125 | - -webkit-filter: brightness(70%); | ||
126 | - filter: brightness(70%); | ||
127 | - } | ||
128 | &.fc-dragging { | 124 | &.fc-dragging { |
129 | z-index: 10; | 125 | z-index: 10; |
130 | } | 126 | } |
@@ -132,6 +128,26 @@ | @@ -132,6 +128,26 @@ | ||
132 | padding: 0 15px; | 128 | padding: 0 15px; |
133 | text-align: center; | 129 | text-align: center; |
134 | } | 130 | } |
131 | + .fc-node-overlay { | ||
132 | + position: absolute; | ||
133 | + pointer-events: none; | ||
134 | + left: 0; | ||
135 | + top: 0; | ||
136 | + right: 0; | ||
137 | + bottom: 0; | ||
138 | + background-color: #000; | ||
139 | + opacity: 0; | ||
140 | + } | ||
141 | + &.fc-hover { | ||
142 | + .fc-node-overlay { | ||
143 | + opacity: 0.25; | ||
144 | + } | ||
145 | + } | ||
146 | + &.fc-selected { | ||
147 | + .fc-node-overlay { | ||
148 | + opacity: 0.25; | ||
149 | + } | ||
150 | + } | ||
135 | } | 151 | } |
136 | 152 | ||
137 | .fc-leftConnectors, .fc-rightConnectors { | 153 | .fc-leftConnectors, .fc-rightConnectors { |
@@ -181,6 +197,7 @@ | @@ -181,6 +197,7 @@ | ||
181 | stroke: gray; | 197 | stroke: gray; |
182 | stroke-width: 4; | 198 | stroke-width: 4; |
183 | fill: transparent; | 199 | fill: transparent; |
200 | + transition: stroke-width .2s; | ||
184 | &.fc-selected { | 201 | &.fc-selected { |
185 | stroke: red; | 202 | stroke: red; |
186 | stroke-width: 4; | 203 | stroke-width: 4; |
@@ -232,20 +249,29 @@ | @@ -232,20 +249,29 @@ | ||
232 | .fc-edge-label { | 249 | .fc-edge-label { |
233 | position: absolute; | 250 | position: absolute; |
234 | user-select: none; | 251 | user-select: none; |
235 | - pointer-events: none; | 252 | + transition: transform .2s; |
236 | opacity: 0.8; | 253 | opacity: 0.8; |
254 | + &.fc-hover { | ||
255 | + transform: scale(1.25); | ||
256 | + } | ||
257 | + &.fc-selected { | ||
258 | + .fc-edge-label-text { | ||
259 | + span { | ||
260 | + border: solid red; | ||
261 | + color: red; | ||
262 | + } | ||
263 | + } | ||
264 | + } | ||
237 | } | 265 | } |
238 | 266 | ||
239 | .fc-edge-label-text { | 267 | .fc-edge-label-text { |
240 | position: absolute; | 268 | position: absolute; |
241 | - left: 50%; | ||
242 | - -webkit-transform: translateX(-50%); | ||
243 | - transform: translateX(-50%); | 269 | + -webkit-transform: translate(-50%, -50%); |
270 | + transform: translate(-50%, -50%); | ||
244 | white-space: nowrap; | 271 | white-space: nowrap; |
245 | text-align: center; | 272 | text-align: center; |
246 | font-size: 14px; | 273 | font-size: 14px; |
247 | font-weight: 600; | 274 | font-weight: 600; |
248 | - top: 5px; | ||
249 | span { | 275 | span { |
250 | border: solid 2px #003a79; | 276 | border: solid 2px #003a79; |
251 | border-radius: 10px; | 277 | border-radius: 10px; |
@@ -255,6 +281,13 @@ | @@ -255,6 +281,13 @@ | ||
255 | } | 281 | } |
256 | } | 282 | } |
257 | 283 | ||
284 | +.fc-select-rectangle { | ||
285 | + border: 2px dashed #5262ff; | ||
286 | + position: absolute; | ||
287 | + background: rgba(20,125,255,0.1); | ||
288 | + z-index: 2; | ||
289 | +} | ||
290 | + | ||
258 | @keyframes dash { | 291 | @keyframes dash { |
259 | from { | 292 | from { |
260 | stroke-dashoffset: 500; | 293 | stroke-dashoffset: 500; |
@@ -112,6 +112,13 @@ | @@ -112,6 +112,13 @@ | ||
112 | </tb-details-sidenav> | 112 | </tb-details-sidenav> |
113 | </section> | 113 | </section> |
114 | <section layout="row" layout-wrap class="tb-footer-buttons md-fab" layout-align="start end"> | 114 | <section layout="row" layout-wrap class="tb-footer-buttons md-fab" layout-align="start end"> |
115 | + <md-button ng-disabled="$root.loading" ng-show="vm.objectsSelected()" class="tb-btn-footer md-accent md-hue-2 md-fab" | ||
116 | + ng-click="vm.deleteSelected()" aria-label="{{ 'action.delete' | translate }}"> | ||
117 | + <md-tooltip md-direction="top"> | ||
118 | + {{ 'rulenode.delete-selected-objects' | translate }} | ||
119 | + </md-tooltip> | ||
120 | + <ng-md-icon icon="delete"></ng-md-icon> | ||
121 | + </md-button> | ||
115 | <md-button ng-disabled="$root.loading || !vm.isDirty" | 122 | <md-button ng-disabled="$root.loading || !vm.isDirty" |
116 | class="tb-btn-footer md-accent md-hue-2 md-fab" | 123 | class="tb-btn-footer md-accent md-hue-2 md-fab" |
117 | aria-label="{{ 'action.apply' | translate }}" | 124 | aria-label="{{ 'action.apply' | translate }}" |
@@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||
22 | ng-mousedown="callbacks.mouseDown($event, node)" | 22 | ng-mousedown="callbacks.mouseDown($event, node)" |
23 | ng-mouseenter="callbacks.mouseEnter($event, node)" | 23 | ng-mouseenter="callbacks.mouseEnter($event, node)" |
24 | ng-mouseleave="callbacks.mouseLeave($event, node)"> | 24 | ng-mouseleave="callbacks.mouseLeave($event, node)"> |
25 | + <div class="{{flowchartConstants.nodeOverlayClass}}"></div> | ||
25 | <div class="tb-rule-node {{node.nodeClass}}"> | 26 | <div class="tb-rule-node {{node.nodeClass}}"> |
26 | <md-icon aria-label="node-type-icon" flex="15" | 27 | <md-icon aria-label="node-type-icon" flex="15" |
27 | class="material-icons">{{node.icon}}</md-icon> | 28 | class="material-icons">{{node.icon}}</md-icon> |