RuleChain Import/Export
This commit is contained in:
		
							parent
							
								
									dc47727cf5
								
							
						
					
					
						commit
						9c0f6e9925
					
				@ -253,7 +253,7 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
 | 
			
		||||
        if (ruleChainConnections && ruleChainConnections.length) {
 | 
			
		||||
            var tasks = [];
 | 
			
		||||
            for (var i = 0; i < ruleChainConnections.length; i++) {
 | 
			
		||||
                tasks.push(getRuleChain(ruleChainConnections[i].targetRuleChainId.id));
 | 
			
		||||
                tasks.push(resolveRuleChain(ruleChainConnections[i].targetRuleChainId.id));
 | 
			
		||||
            }
 | 
			
		||||
            $q.all(tasks).then(
 | 
			
		||||
                (ruleChains) => {
 | 
			
		||||
@ -273,6 +273,21 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
 | 
			
		||||
        return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function resolveRuleChain(ruleChainId) {
 | 
			
		||||
        var deferred = $q.defer();
 | 
			
		||||
        getRuleChain(ruleChainId, {ignoreErrors: true}).then(
 | 
			
		||||
            (ruleChain) => {
 | 
			
		||||
                deferred.resolve(ruleChain);
 | 
			
		||||
            },
 | 
			
		||||
            () => {
 | 
			
		||||
                deferred.resolve({
 | 
			
		||||
                    id: {id: ruleChainId, entityType: types.entityType.rulechain}
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
        return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function loadRuleNodeComponents() {
 | 
			
		||||
        return componentDescriptorService.getComponentDescriptorsByTypes(types.ruleNodeTypeComponentTypes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -281,39 +281,63 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
 | 
			
		||||
 | 
			
		||||
    function exportRuleChain(ruleChainId) {
 | 
			
		||||
        ruleChainService.getRuleChain(ruleChainId).then(
 | 
			
		||||
            function success(ruleChain) {
 | 
			
		||||
                var name = ruleChain.name;
 | 
			
		||||
                name = name.toLowerCase().replace(/\W/g,"_");
 | 
			
		||||
                exportToPc(prepareExport(ruleChain), name + '.json');
 | 
			
		||||
                //TODO: metadata
 | 
			
		||||
            (ruleChain) => {
 | 
			
		||||
                ruleChainService.getRuleChainMetaData(ruleChainId).then(
 | 
			
		||||
                    (ruleChainMetaData) => {
 | 
			
		||||
                        var ruleChainExport = {
 | 
			
		||||
                            ruleChain: prepareRuleChain(ruleChain),
 | 
			
		||||
                            metadata: prepareRuleChainMetaData(ruleChainMetaData)
 | 
			
		||||
                        };
 | 
			
		||||
                        var name = ruleChain.name;
 | 
			
		||||
                        name = name.toLowerCase().replace(/\W/g,"_");
 | 
			
		||||
                        exportToPc(ruleChainExport, name + '.json');
 | 
			
		||||
                    },
 | 
			
		||||
                    (rejection) => {
 | 
			
		||||
                        processExportRuleChainRejection(rejection);
 | 
			
		||||
                    }
 | 
			
		||||
                );
 | 
			
		||||
            },
 | 
			
		||||
            function fail(rejection) {
 | 
			
		||||
                var message = rejection;
 | 
			
		||||
                if (!message) {
 | 
			
		||||
                    message = $translate.instant('error.unknown-error');
 | 
			
		||||
                }
 | 
			
		||||
                toast.showError($translate.instant('rulechain.export-failed-error', {error: message}));
 | 
			
		||||
            (rejection) => {
 | 
			
		||||
                processExportRuleChainRejection(rejection);
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function prepareRuleChain(ruleChain) {
 | 
			
		||||
        ruleChain = prepareExport(ruleChain);
 | 
			
		||||
        if (ruleChain.firstRuleNodeId) {
 | 
			
		||||
            ruleChain.firstRuleNodeId = null;
 | 
			
		||||
        }
 | 
			
		||||
        ruleChain.root = false;
 | 
			
		||||
        return ruleChain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function prepareRuleChainMetaData(ruleChainMetaData) {
 | 
			
		||||
        delete ruleChainMetaData.ruleChainId;
 | 
			
		||||
        for (var i=0;i<ruleChainMetaData.nodes.length;i++) {
 | 
			
		||||
            var node = ruleChainMetaData.nodes[i];
 | 
			
		||||
            ruleChainMetaData.nodes[i] = prepareExport(node);
 | 
			
		||||
        }
 | 
			
		||||
        return ruleChainMetaData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function processExportRuleChainRejection(rejection) {
 | 
			
		||||
        var message = rejection;
 | 
			
		||||
        if (!message) {
 | 
			
		||||
            message = $translate.instant('error.unknown-error');
 | 
			
		||||
        }
 | 
			
		||||
        toast.showError($translate.instant('rulechain.export-failed-error', {error: message}));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function importRuleChain($event) {
 | 
			
		||||
        var deferred = $q.defer();
 | 
			
		||||
        openImportDialog($event, 'rulechain.import', 'rulechain.rulechain-file').then(
 | 
			
		||||
            function success(ruleChain) {
 | 
			
		||||
                if (!validateImportedRuleChain(ruleChain)) {
 | 
			
		||||
            function success(ruleChainImport) {
 | 
			
		||||
                if (!validateImportedRuleChain(ruleChainImport)) {
 | 
			
		||||
                    toast.showError($translate.instant('rulechain.invalid-rulechain-file-error'));
 | 
			
		||||
                    deferred.reject();
 | 
			
		||||
                } else {
 | 
			
		||||
                    //TODO: rulechain metadata
 | 
			
		||||
                    ruleChainService.saveRuleChain(ruleChain).then(
 | 
			
		||||
                        function success() {
 | 
			
		||||
                            deferred.resolve();
 | 
			
		||||
                        },
 | 
			
		||||
                        function fail() {
 | 
			
		||||
                            deferred.reject();
 | 
			
		||||
                        }
 | 
			
		||||
                    );
 | 
			
		||||
                    deferred.resolve(ruleChainImport);
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            function fail() {
 | 
			
		||||
@ -323,10 +347,14 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document,
 | 
			
		||||
        return deferred.promise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function validateImportedRuleChain(ruleChain) {
 | 
			
		||||
        //TODO: rulechain metadata
 | 
			
		||||
        if (angular.isUndefined(ruleChain.name))
 | 
			
		||||
        {
 | 
			
		||||
    function validateImportedRuleChain(ruleChainImport) {
 | 
			
		||||
        if (angular.isUndefined(ruleChainImport.ruleChain)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (angular.isUndefined(ruleChainImport.metadata)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (angular.isUndefined(ruleChainImport.ruleChain.name)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
 | 
			
		||||
@ -1175,7 +1175,7 @@ export default angular.module('thingsboard.locale', [])
 | 
			
		||||
                    "export": "Export rule chain",
 | 
			
		||||
                    "export-failed-error": "Unable to export rule chain: {{error}}",
 | 
			
		||||
                    "create-new-rulechain": "Create new rule chain",
 | 
			
		||||
                    "rule-file": "Rule chain file",
 | 
			
		||||
                    "rulechain-file": "Rule chain file",
 | 
			
		||||
                    "invalid-rulechain-file-error": "Unable to import rule chain: Invalid rule chain data structure.",
 | 
			
		||||
                    "copyId": "Copy rule chain Id",
 | 
			
		||||
                    "idCopiedMessage": "Rule chain Id has been copied to clipboard",
 | 
			
		||||
@ -1219,7 +1219,8 @@ export default angular.module('thingsboard.locale', [])
 | 
			
		||||
                    "type-rule-chain": "Rule Chain",
 | 
			
		||||
                    "type-rule-chain-details": "Forwards incoming messages to specified Rule Chain",
 | 
			
		||||
                    "directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.",
 | 
			
		||||
                    "ui-resources-load-error": "Failed to load configuration ui resources."
 | 
			
		||||
                    "ui-resources-load-error": "Failed to load configuration ui resources.",
 | 
			
		||||
                    "invalid-target-rulechain": "Unable to resolve target rule chain!"
 | 
			
		||||
                },
 | 
			
		||||
                "rule-plugin": {
 | 
			
		||||
                    "management": "Rules and plugins management"
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ import addRuleNodeLinkTemplate from './add-link.tpl.html';
 | 
			
		||||
/* eslint-enable import/no-unresolved, import/default */
 | 
			
		||||
 | 
			
		||||
/*@ngInject*/
 | 
			
		||||
export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil, $timeout, $mdExpansionPanel, $window, $document, $mdDialog,
 | 
			
		||||
export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $timeout, $mdExpansionPanel, $window, $document, $mdDialog,
 | 
			
		||||
                                    $filter, $translate, hotkeys, types, ruleChainService, Modelfactory, flowchartConstants,
 | 
			
		||||
                                    ruleChain, ruleChainMetaData, ruleNodeComponents) {
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,22 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
    vm.$mdExpansionPanel = $mdExpansionPanel;
 | 
			
		||||
    vm.types = types;
 | 
			
		||||
 | 
			
		||||
    if ($state.current.data.import && !ruleChain) {
 | 
			
		||||
        $state.go('home.ruleChains');
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vm.isImport = $state.current.data.import;
 | 
			
		||||
    vm.isConfirmOnExit = false;
 | 
			
		||||
 | 
			
		||||
    $scope.$watch(function() {
 | 
			
		||||
        return vm.isDirty || vm.isImport;
 | 
			
		||||
    }, (val) => {
 | 
			
		||||
        vm.isConfirmOnExit = val;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    vm.errorTooltips = {};
 | 
			
		||||
 | 
			
		||||
    vm.isFullscreen = false;
 | 
			
		||||
 | 
			
		||||
    vm.editingRuleNode = null;
 | 
			
		||||
@ -151,6 +167,9 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
        $scope.$broadcast('form-submit');
 | 
			
		||||
        if (theForm.$valid) {
 | 
			
		||||
            theForm.$setPristine();
 | 
			
		||||
            if (vm.editingRuleNode.error) {
 | 
			
		||||
                delete vm.editingRuleNode.error;
 | 
			
		||||
            }
 | 
			
		||||
            vm.ruleChainModel.nodes[vm.editingRuleNodeIndex] = vm.editingRuleNode;
 | 
			
		||||
            vm.editingRuleNode = angular.copy(vm.editingRuleNode);
 | 
			
		||||
            updateRuleNodesHighlight();
 | 
			
		||||
@ -210,7 +229,9 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
        }
 | 
			
		||||
        var instances = angular.element.tooltipster.instances();
 | 
			
		||||
        instances.forEach((instance) => {
 | 
			
		||||
            instance.destroy();
 | 
			
		||||
            if (!instance.isErrorTooltip) {
 | 
			
		||||
                instance.destroy();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -256,6 +277,71 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
        }, 500);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function updateNodeErrorTooltip(node) {
 | 
			
		||||
        if (node.error) {
 | 
			
		||||
            var element = angular.element('#' + node.id);
 | 
			
		||||
            var tooltip = vm.errorTooltips[node.id];
 | 
			
		||||
            if (!tooltip || !element.hasClass("tooltipstered")) {
 | 
			
		||||
                element.tooltipster(
 | 
			
		||||
                    {
 | 
			
		||||
                        theme: 'tooltipster-shadow',
 | 
			
		||||
                        delay: 0,
 | 
			
		||||
                        animationDuration: 0,
 | 
			
		||||
                        trigger: 'custom',
 | 
			
		||||
                        triggerOpen: {
 | 
			
		||||
                            click: false,
 | 
			
		||||
                            tap: false
 | 
			
		||||
                        },
 | 
			
		||||
                        triggerClose: {
 | 
			
		||||
                            click: false,
 | 
			
		||||
                            tap: false,
 | 
			
		||||
                            scroll: false
 | 
			
		||||
                        },
 | 
			
		||||
                        side: 'top',
 | 
			
		||||
                        trackOrigin: true
 | 
			
		||||
                    }
 | 
			
		||||
                );
 | 
			
		||||
                var content = '<div class="tb-rule-node-error-tooltip">' +
 | 
			
		||||
                    '<div id="tooltip-content" layout="column">' +
 | 
			
		||||
                    '<div class="tb-node-details">' + node.error + '</div>' +
 | 
			
		||||
                    '</div>' +
 | 
			
		||||
                    '</div>';
 | 
			
		||||
                var contentElement = angular.element(content);
 | 
			
		||||
                $compile(contentElement)($scope);
 | 
			
		||||
                tooltip = element.tooltipster('instance');
 | 
			
		||||
                tooltip.isErrorTooltip = true;
 | 
			
		||||
                tooltip.content(contentElement);
 | 
			
		||||
                vm.errorTooltips[node.id] = tooltip;
 | 
			
		||||
            }
 | 
			
		||||
            $mdUtil.nextTick(() => {
 | 
			
		||||
                tooltip.open();
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            if (vm.errorTooltips[node.id]) {
 | 
			
		||||
                tooltip = vm.errorTooltips[node.id];
 | 
			
		||||
                tooltip.destroy();
 | 
			
		||||
                delete vm.errorTooltips[node.id];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function updateErrorTooltips(hide) {
 | 
			
		||||
        for (var nodeId in vm.errorTooltips) {
 | 
			
		||||
            var tooltip = vm.errorTooltips[nodeId];
 | 
			
		||||
            if (hide) {
 | 
			
		||||
                tooltip.close();
 | 
			
		||||
            } else {
 | 
			
		||||
                tooltip.open();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $scope.$watch(function() {
 | 
			
		||||
        return vm.isEditingRuleNode || vm.isEditingRuleNodeLink;
 | 
			
		||||
    }, (val) => {
 | 
			
		||||
        updateErrorTooltips(val);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    vm.editCallbacks = {
 | 
			
		||||
        edgeDoubleClick: function (event, edge) {
 | 
			
		||||
            var sourceNode = vm.modelservice.nodes.getNodeByConnectorId(edge.source);
 | 
			
		||||
@ -381,6 +467,16 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
                    vm.ruleNodeTypesCanvasControl[componentType].adjustCanvasSize(true);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (componentType in vm.ruleNodeTypesModel) {
 | 
			
		||||
                var panel = vm.$mdExpansionPanel(componentType);
 | 
			
		||||
                if (panel) {
 | 
			
		||||
                    if (!vm.ruleNodeTypesModel[componentType].model.nodes.length) {
 | 
			
		||||
                        panel.collapse();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        panel.expand();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -512,11 +608,9 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
                        ruleChainNode = {
 | 
			
		||||
                            id: 'rule-chain-node-' + vm.nextNodeID++,
 | 
			
		||||
                            additionalInfo: ruleChainConnection.additionalInfo,
 | 
			
		||||
                            targetRuleChainId: ruleChainConnection.targetRuleChainId.id,
 | 
			
		||||
                            x: ruleChainConnection.additionalInfo.layoutX,
 | 
			
		||||
                            y: ruleChainConnection.additionalInfo.layoutY,
 | 
			
		||||
                            component: types.ruleChainNodeComponent,
 | 
			
		||||
                            name: ruleChain.name,
 | 
			
		||||
                            nodeClass: vm.types.ruleNodeType.RULE_CHAIN.nodeClass,
 | 
			
		||||
                            icon: vm.types.ruleNodeType.RULE_CHAIN.icon,
 | 
			
		||||
                            connectors: [
 | 
			
		||||
@ -526,6 +620,14 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
                                }
 | 
			
		||||
                            ]
 | 
			
		||||
                        };
 | 
			
		||||
                        if (ruleChain.name) {
 | 
			
		||||
                            ruleChainNode.name = ruleChain.name;
 | 
			
		||||
                            ruleChainNode.targetRuleChainId = ruleChainConnection.targetRuleChainId.id;
 | 
			
		||||
                        } else {
 | 
			
		||||
                            ruleChainNode.name = "Unresolved";
 | 
			
		||||
                            ruleChainNode.targetRuleChainId = null;
 | 
			
		||||
                            ruleChainNode.error = $translate.instant('rulenode.invalid-target-rulechain');
 | 
			
		||||
                        }
 | 
			
		||||
                        ruleChainNodesMap[ruleChainConnection.additionalInfo.ruleChainNodeId] = ruleChainNode;
 | 
			
		||||
                        vm.ruleChainModel.nodes.push(ruleChainNode);
 | 
			
		||||
                    }
 | 
			
		||||
@ -553,11 +655,16 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
 | 
			
		||||
        updateRuleNodesHighlight();
 | 
			
		||||
 | 
			
		||||
        validate();
 | 
			
		||||
 | 
			
		||||
        $mdUtil.nextTick(() => {
 | 
			
		||||
            vm.ruleChainWatch = $scope.$watch('vm.ruleChainModel',
 | 
			
		||||
                function (newVal, oldVal) {
 | 
			
		||||
                    if (!vm.isDirty && !angular.equals(newVal, oldVal)) {
 | 
			
		||||
                        vm.isDirty = true;
 | 
			
		||||
                    if (!angular.equals(newVal, oldVal)) {
 | 
			
		||||
                        validate();
 | 
			
		||||
                        if (!vm.isDirty) {
 | 
			
		||||
                            vm.isDirty = true;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }, true
 | 
			
		||||
            );
 | 
			
		||||
@ -565,91 +672,122 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function updateRuleNodesHighlight() {
 | 
			
		||||
        for (var i=0;i<vm.ruleChainModel.nodes.length;i++) {
 | 
			
		||||
        for (var i = 0; i < vm.ruleChainModel.nodes.length; i++) {
 | 
			
		||||
            vm.ruleChainModel.nodes[i].highlighted = false;
 | 
			
		||||
        }
 | 
			
		||||
        if ($scope.searchConfig.searchText) {
 | 
			
		||||
            var res = $filter('filter')(vm.ruleChainModel.nodes, {name: $scope.searchConfig.searchText});
 | 
			
		||||
            if (res) {
 | 
			
		||||
                for (i=0;i<res.length;i++) {
 | 
			
		||||
                for (i = 0; i < res.length; i++) {
 | 
			
		||||
                    res[i].highlighted = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function validate() {
 | 
			
		||||
        $mdUtil.nextTick(() => {
 | 
			
		||||
            vm.isInvalid = false;
 | 
			
		||||
            for (var i = 0; i < vm.ruleChainModel.nodes.length; i++) {
 | 
			
		||||
                if (vm.ruleChainModel.nodes[i].error) {
 | 
			
		||||
                    vm.isInvalid = true;
 | 
			
		||||
                }
 | 
			
		||||
                updateNodeErrorTooltip(vm.ruleChainModel.nodes[i]);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function saveRuleChain() {
 | 
			
		||||
        var ruleChainMetaData = {
 | 
			
		||||
            ruleChainId: vm.ruleChain.id,
 | 
			
		||||
            nodes: [],
 | 
			
		||||
            connections: [],
 | 
			
		||||
            ruleChainConnections: []
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var nodes = [];
 | 
			
		||||
 | 
			
		||||
        for (var i=0;i<vm.ruleChainModel.nodes.length;i++) {
 | 
			
		||||
            var node = vm.ruleChainModel.nodes[i];
 | 
			
		||||
            if (node.component.type != types.ruleNodeType.INPUT.value && node.component.type != types.ruleNodeType.RULE_CHAIN.value) {
 | 
			
		||||
                var ruleNode = {};
 | 
			
		||||
                if (node.ruleNodeId) {
 | 
			
		||||
                    ruleNode.id = node.ruleNodeId;
 | 
			
		||||
                }
 | 
			
		||||
                ruleNode.type = node.component.clazz;
 | 
			
		||||
                ruleNode.name = node.name;
 | 
			
		||||
                ruleNode.configuration = node.configuration;
 | 
			
		||||
                ruleNode.additionalInfo = node.additionalInfo;
 | 
			
		||||
                ruleNode.debugMode = node.debugMode;
 | 
			
		||||
                if (!ruleNode.additionalInfo) {
 | 
			
		||||
                    ruleNode.additionalInfo = {};
 | 
			
		||||
                }
 | 
			
		||||
                ruleNode.additionalInfo.layoutX = node.x;
 | 
			
		||||
                ruleNode.additionalInfo.layoutY = node.y;
 | 
			
		||||
                ruleChainMetaData.nodes.push(ruleNode);
 | 
			
		||||
                nodes.push(node);
 | 
			
		||||
            }
 | 
			
		||||
        var saveRuleChainPromise;
 | 
			
		||||
        if (vm.isImport) {
 | 
			
		||||
            saveRuleChainPromise = ruleChainService.saveRuleChain(vm.ruleChain);
 | 
			
		||||
        } else {
 | 
			
		||||
            saveRuleChainPromise = $q.when(vm.ruleChain);
 | 
			
		||||
        }
 | 
			
		||||
        var res = $filter('filter')(vm.ruleChainModel.edges, {source: vm.inputConnectorId});
 | 
			
		||||
        if (res && res.length) {
 | 
			
		||||
            var firstNodeEdge = res[0];
 | 
			
		||||
            var firstNode = vm.modelservice.nodes.getNodeByConnectorId(firstNodeEdge.destination);
 | 
			
		||||
            ruleChainMetaData.firstNodeIndex = nodes.indexOf(firstNode);
 | 
			
		||||
        }
 | 
			
		||||
        for (i=0;i<vm.ruleChainModel.edges.length;i++) {
 | 
			
		||||
            var edge = vm.ruleChainModel.edges[i];
 | 
			
		||||
            var sourceNode = vm.modelservice.nodes.getNodeByConnectorId(edge.source);
 | 
			
		||||
            var destNode = vm.modelservice.nodes.getNodeByConnectorId(edge.destination);
 | 
			
		||||
            if (sourceNode.component.type != types.ruleNodeType.INPUT.value) {
 | 
			
		||||
                var fromIndex = nodes.indexOf(sourceNode);
 | 
			
		||||
                if (destNode.component.type == types.ruleNodeType.RULE_CHAIN.value) {
 | 
			
		||||
                    var ruleChainConnection = {
 | 
			
		||||
                        fromIndex: fromIndex,
 | 
			
		||||
                        targetRuleChainId: {entityType: vm.types.entityType.rulechain, id: destNode.targetRuleChainId},
 | 
			
		||||
                        additionalInfo: destNode.additionalInfo,
 | 
			
		||||
                        type: edge.label
 | 
			
		||||
                    };
 | 
			
		||||
                    if (!ruleChainConnection.additionalInfo) {
 | 
			
		||||
                        ruleChainConnection.additionalInfo = {};
 | 
			
		||||
        saveRuleChainPromise.then(
 | 
			
		||||
            (ruleChain) => {
 | 
			
		||||
                vm.ruleChain = ruleChain;
 | 
			
		||||
                var ruleChainMetaData = {
 | 
			
		||||
                    ruleChainId: vm.ruleChain.id,
 | 
			
		||||
                    nodes: [],
 | 
			
		||||
                    connections: [],
 | 
			
		||||
                    ruleChainConnections: []
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                var nodes = [];
 | 
			
		||||
 | 
			
		||||
                for (var i=0;i<vm.ruleChainModel.nodes.length;i++) {
 | 
			
		||||
                    var node = vm.ruleChainModel.nodes[i];
 | 
			
		||||
                    if (node.component.type != types.ruleNodeType.INPUT.value && node.component.type != types.ruleNodeType.RULE_CHAIN.value) {
 | 
			
		||||
                        var ruleNode = {};
 | 
			
		||||
                        if (node.ruleNodeId) {
 | 
			
		||||
                            ruleNode.id = node.ruleNodeId;
 | 
			
		||||
                        }
 | 
			
		||||
                        ruleNode.type = node.component.clazz;
 | 
			
		||||
                        ruleNode.name = node.name;
 | 
			
		||||
                        ruleNode.configuration = node.configuration;
 | 
			
		||||
                        ruleNode.additionalInfo = node.additionalInfo;
 | 
			
		||||
                        ruleNode.debugMode = node.debugMode;
 | 
			
		||||
                        if (!ruleNode.additionalInfo) {
 | 
			
		||||
                            ruleNode.additionalInfo = {};
 | 
			
		||||
                        }
 | 
			
		||||
                        ruleNode.additionalInfo.layoutX = node.x;
 | 
			
		||||
                        ruleNode.additionalInfo.layoutY = node.y;
 | 
			
		||||
                        ruleChainMetaData.nodes.push(ruleNode);
 | 
			
		||||
                        nodes.push(node);
 | 
			
		||||
                    }
 | 
			
		||||
                    ruleChainConnection.additionalInfo.layoutX = destNode.x;
 | 
			
		||||
                    ruleChainConnection.additionalInfo.layoutY = destNode.y;
 | 
			
		||||
                    ruleChainConnection.additionalInfo.ruleChainNodeId = destNode.id;
 | 
			
		||||
                    ruleChainMetaData.ruleChainConnections.push(ruleChainConnection);
 | 
			
		||||
                } else {
 | 
			
		||||
                    var toIndex = nodes.indexOf(destNode);
 | 
			
		||||
                    var nodeConnection = {
 | 
			
		||||
                        fromIndex: fromIndex,
 | 
			
		||||
                        toIndex: toIndex,
 | 
			
		||||
                        type: edge.label
 | 
			
		||||
                    };
 | 
			
		||||
                    ruleChainMetaData.connections.push(nodeConnection);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        ruleChainService.saveRuleChainMetaData(ruleChainMetaData).then(
 | 
			
		||||
            (ruleChainMetaData) => {
 | 
			
		||||
                vm.ruleChainMetaData = ruleChainMetaData;
 | 
			
		||||
                prepareRuleChain();
 | 
			
		||||
                var res = $filter('filter')(vm.ruleChainModel.edges, {source: vm.inputConnectorId});
 | 
			
		||||
                if (res && res.length) {
 | 
			
		||||
                    var firstNodeEdge = res[0];
 | 
			
		||||
                    var firstNode = vm.modelservice.nodes.getNodeByConnectorId(firstNodeEdge.destination);
 | 
			
		||||
                    ruleChainMetaData.firstNodeIndex = nodes.indexOf(firstNode);
 | 
			
		||||
                }
 | 
			
		||||
                for (i=0;i<vm.ruleChainModel.edges.length;i++) {
 | 
			
		||||
                    var edge = vm.ruleChainModel.edges[i];
 | 
			
		||||
                    var sourceNode = vm.modelservice.nodes.getNodeByConnectorId(edge.source);
 | 
			
		||||
                    var destNode = vm.modelservice.nodes.getNodeByConnectorId(edge.destination);
 | 
			
		||||
                    if (sourceNode.component.type != types.ruleNodeType.INPUT.value) {
 | 
			
		||||
                        var fromIndex = nodes.indexOf(sourceNode);
 | 
			
		||||
                        if (destNode.component.type == types.ruleNodeType.RULE_CHAIN.value) {
 | 
			
		||||
                            var ruleChainConnection = {
 | 
			
		||||
                                fromIndex: fromIndex,
 | 
			
		||||
                                targetRuleChainId: {entityType: vm.types.entityType.rulechain, id: destNode.targetRuleChainId},
 | 
			
		||||
                                additionalInfo: destNode.additionalInfo,
 | 
			
		||||
                                type: edge.label
 | 
			
		||||
                            };
 | 
			
		||||
                            if (!ruleChainConnection.additionalInfo) {
 | 
			
		||||
                                ruleChainConnection.additionalInfo = {};
 | 
			
		||||
                            }
 | 
			
		||||
                            ruleChainConnection.additionalInfo.layoutX = destNode.x;
 | 
			
		||||
                            ruleChainConnection.additionalInfo.layoutY = destNode.y;
 | 
			
		||||
                            ruleChainConnection.additionalInfo.ruleChainNodeId = destNode.id;
 | 
			
		||||
                            ruleChainMetaData.ruleChainConnections.push(ruleChainConnection);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            var toIndex = nodes.indexOf(destNode);
 | 
			
		||||
                            var nodeConnection = {
 | 
			
		||||
                                fromIndex: fromIndex,
 | 
			
		||||
                                toIndex: toIndex,
 | 
			
		||||
                                type: edge.label
 | 
			
		||||
                            };
 | 
			
		||||
                            ruleChainMetaData.connections.push(nodeConnection);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                ruleChainService.saveRuleChainMetaData(ruleChainMetaData).then(
 | 
			
		||||
                    (ruleChainMetaData) => {
 | 
			
		||||
                        vm.ruleChainMetaData = ruleChainMetaData;
 | 
			
		||||
                        if (vm.isImport) {
 | 
			
		||||
                            vm.isDirty = false;
 | 
			
		||||
                            vm.isImport = false;
 | 
			
		||||
                            $mdUtil.nextTick(() => {
 | 
			
		||||
                                $state.go('home.ruleChains.ruleChain', {ruleChainId: vm.ruleChain.id.id});
 | 
			
		||||
                            });
 | 
			
		||||
                        } else {
 | 
			
		||||
                            prepareRuleChain();
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
@ -662,12 +800,14 @@ export function RuleChainController($stateParams, $scope, $compile, $q, $mdUtil,
 | 
			
		||||
 | 
			
		||||
        ruleNode.configuration = angular.copy(ruleNode.component.configurationDescriptor.nodeDefinition.defaultConfiguration);
 | 
			
		||||
 | 
			
		||||
        var ruleChainId = vm.ruleChain.id ? vm.ruleChain.id.id : null;
 | 
			
		||||
 | 
			
		||||
        $mdDialog.show({
 | 
			
		||||
            controller: 'AddRuleNodeController',
 | 
			
		||||
            controllerAs: 'vm',
 | 
			
		||||
            templateUrl: addRuleNodeTemplate,
 | 
			
		||||
            parent: angular.element($document[0].body),
 | 
			
		||||
            locals: {ruleNode: ruleNode, ruleChainId: vm.ruleChain.id.id},
 | 
			
		||||
            locals: {ruleNode: ruleNode, ruleChainId: ruleChainId},
 | 
			
		||||
            fullscreen: true,
 | 
			
		||||
            targetEvent: $event
 | 
			
		||||
        }).then(function (ruleNode) {
 | 
			
		||||
 | 
			
		||||
@ -76,11 +76,52 @@ export default function RuleChainRoutes($stateProvider, NodeTemplatePathProvider
 | 
			
		||||
                    }
 | 
			
		||||
            },
 | 
			
		||||
            data: {
 | 
			
		||||
                import: false,
 | 
			
		||||
                searchEnabled: true,
 | 
			
		||||
                pageTitle: 'rulechain.rulechain'
 | 
			
		||||
            },
 | 
			
		||||
            ncyBreadcrumb: {
 | 
			
		||||
                label: '{"icon": "settings_ethernet", "label": "{{ vm.ruleChain.name }}", "translate": "false"}'
 | 
			
		||||
            }
 | 
			
		||||
    }).state('home.ruleChains.importRuleChain', {
 | 
			
		||||
        url: '/ruleChain/import',
 | 
			
		||||
        reloadOnSearch: false,
 | 
			
		||||
        module: 'private',
 | 
			
		||||
        auth: ['SYS_ADMIN', 'TENANT_ADMIN'],
 | 
			
		||||
        views: {
 | 
			
		||||
            "content@home": {
 | 
			
		||||
                templateUrl: ruleChainTemplate,
 | 
			
		||||
                controller: 'RuleChainController',
 | 
			
		||||
                controllerAs: 'vm'
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        params: {
 | 
			
		||||
            ruleChainImport: {}
 | 
			
		||||
        },
 | 
			
		||||
        resolve: {
 | 
			
		||||
            ruleChain:
 | 
			
		||||
            /*@ngInject*/
 | 
			
		||||
                function($stateParams) {
 | 
			
		||||
                    return $stateParams.ruleChainImport.ruleChain;
 | 
			
		||||
                },
 | 
			
		||||
            ruleChainMetaData:
 | 
			
		||||
            /*@ngInject*/
 | 
			
		||||
                function($stateParams) {
 | 
			
		||||
                    return $stateParams.ruleChainImport.metadata;
 | 
			
		||||
                },
 | 
			
		||||
            ruleNodeComponents:
 | 
			
		||||
            /*@ngInject*/
 | 
			
		||||
                function($stateParams, ruleChainService) {
 | 
			
		||||
                    return ruleChainService.getRuleNodeComponents();
 | 
			
		||||
                }
 | 
			
		||||
        },
 | 
			
		||||
        data: {
 | 
			
		||||
            import: true,
 | 
			
		||||
            searchEnabled: true,
 | 
			
		||||
            pageTitle: 'rulechain.rulechain'
 | 
			
		||||
        },
 | 
			
		||||
        ncyBreadcrumb: {
 | 
			
		||||
            label: '{"icon": "settings_ethernet", "label": "{{ (\'rulechain.import\' | translate) + \': \'+ vm.ruleChain.name }}", "translate": "false"}'
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -125,13 +125,16 @@
 | 
			
		||||
  color: #333;
 | 
			
		||||
  border: solid 1px #777;
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  &.tb-rule-node-highlighted {
 | 
			
		||||
  &.tb-rule-node-highlighted:not(.tb-rule-node-invalid) {
 | 
			
		||||
    box-shadow: 0 0 10px 6px #51cbee;
 | 
			
		||||
    .tb-node-title {
 | 
			
		||||
      text-decoration: underline;
 | 
			
		||||
      font-weight: bold;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  &.tb-rule-node-invalid {
 | 
			
		||||
    box-shadow: 0 0 10px 6px #ff5c50;
 | 
			
		||||
  }
 | 
			
		||||
  &.tb-input-type {
 | 
			
		||||
    background-color: #a3eaa9;
 | 
			
		||||
    user-select: none;
 | 
			
		||||
@ -191,10 +194,6 @@
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    background-color: #000;
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
/*    &.tb-rule-node-highlighted {
 | 
			
		||||
      background-color: green;
 | 
			
		||||
      opacity: 0.15;
 | 
			
		||||
    }*/
 | 
			
		||||
  }
 | 
			
		||||
  &.fc-hover {
 | 
			
		||||
    .fc-node-overlay {
 | 
			
		||||
@ -391,6 +390,14 @@
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
  width: 300px;
 | 
			
		||||
  color: #333;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tb-rule-node-error-tooltip {
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
  color: #ea0d0d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tb-rule-node-tooltip, .tb-rule-node-error-tooltip {
 | 
			
		||||
  #tooltip-content {
 | 
			
		||||
    .tb-node-title {
 | 
			
		||||
      font-weight: 600;
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
<md-content flex tb-expand-fullscreen tb-confirm-on-exit is-dirty="vm.isDirty"
 | 
			
		||||
<md-content flex tb-expand-fullscreen tb-confirm-on-exit is-dirty="vm.isConfirmOnExit"
 | 
			
		||||
            expand-tooltip-direction="bottom" layout="column" class="tb-rulechain"
 | 
			
		||||
            ng-keydown="vm.keyDown($event)"
 | 
			
		||||
            ng-keyup="vm.keyUp($event)" on-fullscreen-changed="vm.isFullscreen = expanded">
 | 
			
		||||
@ -185,7 +185,7 @@
 | 
			
		||||
            </md-tooltip>
 | 
			
		||||
            <ng-md-icon icon="delete"></ng-md-icon>
 | 
			
		||||
        </md-button>
 | 
			
		||||
        <md-button ng-disabled="$root.loading || !vm.isDirty"
 | 
			
		||||
        <md-button ng-disabled="$root.loading  || vm.isInvalid || (!vm.isDirty && !vm.isImport)"
 | 
			
		||||
                   class="tb-btn-footer md-accent md-hue-2 md-fab"
 | 
			
		||||
                   aria-label="{{ 'action.apply' | translate }}"
 | 
			
		||||
                   ng-click="vm.saveRuleChain()">
 | 
			
		||||
 | 
			
		||||
@ -63,8 +63,8 @@ export default function RuleChainsController(ruleChainService, userService, impo
 | 
			
		||||
        {
 | 
			
		||||
            onAction: function ($event) {
 | 
			
		||||
                importExport.importRuleChain($event).then(
 | 
			
		||||
                    function() {
 | 
			
		||||
                        vm.grid.refreshList();
 | 
			
		||||
                    function(ruleChainImport) {
 | 
			
		||||
                        $state.go('home.ruleChains.importRuleChain', {ruleChainImport:ruleChainImport});
 | 
			
		||||
                    }
 | 
			
		||||
                );
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
@ -22,8 +22,8 @@
 | 
			
		||||
        ng-mousedown="callbacks.mouseDown($event, node)"
 | 
			
		||||
        ng-mouseenter="callbacks.mouseEnter($event, node)"
 | 
			
		||||
        ng-mouseleave="callbacks.mouseLeave($event, node)">
 | 
			
		||||
    <div class="{{flowchartConstants.nodeOverlayClass}}" ng-class="{'tb-rule-node-highlighted' : node.highlighted}"></div>
 | 
			
		||||
    <div class="tb-rule-node {{node.nodeClass}}" ng-class="{'tb-rule-node-highlighted' : node.highlighted}">
 | 
			
		||||
    <div class="{{flowchartConstants.nodeOverlayClass}}"></div>
 | 
			
		||||
    <div class="tb-rule-node {{node.nodeClass}}" ng-class="{'tb-rule-node-highlighted' : node.highlighted, 'tb-rule-node-invalid': node.error }">
 | 
			
		||||
        <md-icon aria-label="node-type-icon" flex="15"
 | 
			
		||||
                 class="material-icons">{{node.icon}}</md-icon>
 | 
			
		||||
        <div layout="column" flex="85" layout-align="center">
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user