thingsboard-memoizeit
Changes
ui/src/app/locale/locale.constant.js 1(+1 -0)
ui/src/app/rulechain/rulechain.controller.js 83(+82 -1)
ui/src/app/rulechain/rulechain.scss 56(+41 -15)
ui/src/app/rulechain/rulechain.tpl.html 43(+31 -12)
Details
ui/src/app/locale/locale.constant.js 1(+1 -0)
diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js
index 9d35cd1..e7c0f58 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",
ui/src/app/rulechain/rulechain.controller.js 83(+82 -1)
diff --git a/ui/src/app/rulechain/rulechain.controller.js b/ui/src/app/rulechain/rulechain.controller.js
index 9bd7960..eaa14fb 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;
ui/src/app/rulechain/rulechain.scss 56(+41 -15)
diff --git a/ui/src/app/rulechain/rulechain.scss b/ui/src/app/rulechain/rulechain.scss
index 187a722..68f0423 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;
ui/src/app/rulechain/rulechain.tpl.html 43(+31 -12)
diff --git a/ui/src/app/rulechain/rulechain.tpl.html b/ui/src/app/rulechain/rulechain.tpl.html
index 37fcd9b..8a8dcc5 100644
--- a/ui/src/app/rulechain/rulechain.tpl.html
+++ b/ui/src/app/rulechain/rulechain.tpl.html
@@ -99,18 +99,37 @@
</md-expansion-panel>
</md-expansion-panel-group>
</md-sidenav>
- <div flex class="tb-rulechain-graph">
- <fc-canvas id="tb-rulchain-canvas"
- model="vm.ruleChainModel"
- selected-objects="vm.selectedObjects"
- edge-style="curved"
- node-width="170"
- node-height="50"
- automatic-resize="true"
- control="vm.canvasControl"
- callbacks="vm.editCallbacks">
- </fc-canvas>
- </div>
+ <md-menu flex style="position: relative;" md-position-mode="target target" tb-mousepoint-menu>
+ <div class="tb-absolute-fill tb-rulechain-graph" ng-click="" tb-contextmenu="vm.openRuleChainContextMenu($event, $mdOpenMousepointMenu)">
+ <fc-canvas id="tb-rulchain-canvas"
+ model="vm.ruleChainModel"
+ selected-objects="vm.selectedObjects"
+ edge-style="curved"
+ node-width="170"
+ node-height="50"
+ automatic-resize="true"
+ control="vm.canvasControl"
+ callbacks="vm.editCallbacks">
+ </fc-canvas>
+ </div>
+ <md-menu-content id="tb-rule-chain-context-menu" width="4" ng-mouseleave="$mdCloseMousepointMenu()">
+ <div class="tb-context-menu-header {{vm.contextInfo.headerClass}}">
+ <md-icon aria-label="node-type-icon"
+ class="material-icons">{{vm.contextInfo.icon}}</md-icon>
+ <div flex>
+ <div class="tb-context-menu-title">{{vm.contextInfo.title}}</div>
+ <div class="tb-context-menu-subtitle">{{vm.contextInfo.subtitle}}</div>
+ </div>
+ </div>
+ <md-menu-item ng-repeat="item in vm.contextInfo.items">
+ <md-button ng-disabled="!item.enabled" ng-click="item.action(vm.contextMenuEvent)">
+ <md-icon ng-if="item.icon" md-menu-align-target aria-label="{{ item.value | translate }}" class="material-icons">{{item.icon}}</md-icon>
+ <span translate>{{item.value}}</span>
+ <span ng-if="item.shortcut" class="tb-alt-text"> {{ item.shortcut | keyboardShortcut }}</span>
+ </md-button>
+ </md-menu-item>
+ </md-menu-content>
+ </md-menu>
</div>
<tb-details-sidenav class="tb-rulenode-details-sidenav"
header-title="{{vm.editingRuleNode.name}}"