diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js index 9d35cd137e..e7c0f586b3 100644 --- a/ui/src/app/locale/locale.constant.js +++ b/ui/src/app/locale/locale.constant.js @@ -1209,6 +1209,7 @@ export default angular.module('thingsboard.locale', []) "rulenode-details": "Rule node details", "debug-mode": "Debug mode", "configuration": "Configuration", + "link": "Link", "link-details": "Rule node link details", "add-link": "Add link", "link-label": "Link label", diff --git a/ui/src/app/rulechain/rulechain.controller.js b/ui/src/app/rulechain/rulechain.controller.js index 9bd7960d0c..eaa14fbf48 100644 --- a/ui/src/app/rulechain/rulechain.controller.js +++ b/ui/src/app/rulechain/rulechain.controller.js @@ -104,8 +104,89 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time vm.triggerResize = triggerResize; + vm.openRuleChainContextMenu = openRuleChainContextMenu; + initHotKeys(); + function openRuleChainContextMenu($event, $mdOpenMousepointMenu) { + if (vm.canvasControl.modelservice && !$event.ctrlKey && !$event.metaKey) { + var x = $event.clientX; + var y = $event.clientY; + var item = vm.canvasControl.modelservice.getItemInfoAtPoint(x, y); + vm.contextInfo = prepareContextMenu(item); + if (vm.contextInfo.items && vm.contextInfo.items.length > 0) { + vm.contextMenuEvent = $event; + $mdOpenMousepointMenu($event); + return false; + } + } + } + + function prepareContextMenu(item) { + if (objectsSelected() || (!item.node && !item.edge)) { + return prepareRuleChainContextMenu(); + } else if (item.node) { + return prepareRuleNodeContextMenu(item.node); + } else if (item.edge) { + return prepareEdgeContextMenu(item.edge); + } + } + + function prepareRuleChainContextMenu() { + var contextInfo = { + title: vm.ruleChain.name, + subtitle: $translate.instant('rulechain.rulechain') + }; + contextInfo.items = []; + return contextInfo; + } + + function prepareRuleNodeContextMenu(node) { + var contextInfo = { + headerClass: node.nodeClass, + icon: node.icon, + title: node.name, + subtitle: node.component.name + }; + contextInfo.items = []; + if (!node.readonly) { + contextInfo.items.push( + { + action: function () { + vm.canvasControl.modelservice.nodes.delete(node); + }, + enabled: true, + value: "action.delete", + icon: "clear", + shortcut: "M-X" + } + ); + } + return contextInfo; + } + + function prepareEdgeContextMenu(edge) { + var contextInfo = { + headerClass: 'tb-link', + icon: 'trending_flat', + title: edge.label, + subtitle: $translate.instant('rulenode.link') + }; + contextInfo.items = []; + contextInfo.items.push( + { + action: function () { + vm.canvasControl.modelservice.edges.delete(edge); + }, + enabled: true, + value: "action.delete", + icon: "clear", + shortcut: "M-X" + } + ); + return contextInfo; + } + function initHotKeys() { hotkeys.bindTo($scope) .add({ @@ -652,7 +733,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time } if (vm.canvasControl.adjustCanvasSize) { - vm.canvasControl.adjustCanvasSize(); + vm.canvasControl.adjustCanvasSize(true); } vm.isDirty = false; diff --git a/ui/src/app/rulechain/rulechain.scss b/ui/src/app/rulechain/rulechain.scss index 187a722e0f..68f042352a 100644 --- a/ui/src/app/rulechain/rulechain.scss +++ b/ui/src/app/rulechain/rulechain.scss @@ -105,12 +105,53 @@ } } +#tb-rule-chain-context-menu { + padding-top: 0px; + border-radius: 8px; + .tb-context-menu-header { + padding: 8px 5px 5px; + font-size: 14px; + display: flex; + flex-direction: row; + &.tb-link { + background-color: #aac7e4; + } + md-icon { + padding-left: 2px; + padding-right: 10px; + } + .tb-context-menu-title { + font-weight: 500; + } + .tb-context-menu-subtitle { + } + } +} + .fc-canvas { min-width: 100%; min-height: 100%; outline: none; } +.tb-rule-node, #tb-rule-chain-context-menu .tb-context-menu-header { + &.tb-filter-type { + background-color: #f1e861; + } + &.tb-enrichment-type { + background-color: #cdf14e; + } + &.tb-transformation-type { + background-color: #79cef1; + } + &.tb-action-type { + background-color: #f1928f; + } + &.tb-rule-chain-type { + background-color: #d6c4f1; + } +} + .tb-rule-node { display: flex; flex-direction: row; @@ -139,21 +180,6 @@ background-color: #a3eaa9; user-select: none; } - &.tb-filter-type { - background-color: #f1e861; - } - &.tb-enrichment-type { - background-color: #cdf14e; - } - &.tb-transformation-type { - background-color: #79cef1; - } - &.tb-action-type { - background-color: #f1928f; - } - &.tb-rule-chain-type { - background-color: #d6c4f1; - } md-icon { font-size: 20px; width: 20px; diff --git a/ui/src/app/rulechain/rulechain.tpl.html b/ui/src/app/rulechain/rulechain.tpl.html index 37fcd9bfb3..8a8dcc54ea 100644 --- a/ui/src/app/rulechain/rulechain.tpl.html +++ b/ui/src/app/rulechain/rulechain.tpl.html @@ -99,18 +99,37 @@ -
- - -
+ +
+ + +
+ +
+ {{vm.contextInfo.icon}} +
+
{{vm.contextInfo.title}}
+
{{vm.contextInfo.subtitle}}
+
+
+ + + {{item.icon}} + {{item.value}} + {{ item.shortcut | keyboardShortcut }} + + +
+