Multiple labels support.
This commit is contained in:
parent
1f58c1b0d6
commit
f081b656d0
@ -32,6 +32,7 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
|
|||||||
getRuleNodeComponents: getRuleNodeComponents,
|
getRuleNodeComponents: getRuleNodeComponents,
|
||||||
getRuleNodeComponentByClazz: getRuleNodeComponentByClazz,
|
getRuleNodeComponentByClazz: getRuleNodeComponentByClazz,
|
||||||
getRuleNodeSupportedLinks: getRuleNodeSupportedLinks,
|
getRuleNodeSupportedLinks: getRuleNodeSupportedLinks,
|
||||||
|
ruleNodeAllowCustomLinks: ruleNodeAllowCustomLinks,
|
||||||
resolveTargetRuleChains: resolveTargetRuleChains,
|
resolveTargetRuleChains: resolveTargetRuleChains,
|
||||||
testScript: testScript,
|
testScript: testScript,
|
||||||
getLatestRuleNodeDebugInput: getLatestRuleNodeDebugInput
|
getLatestRuleNodeDebugInput: getLatestRuleNodeDebugInput
|
||||||
@ -127,21 +128,21 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
|
|||||||
|
|
||||||
function getRuleNodeSupportedLinks(component) {
|
function getRuleNodeSupportedLinks(component) {
|
||||||
var relationTypes = component.configurationDescriptor.nodeDefinition.relationTypes;
|
var relationTypes = component.configurationDescriptor.nodeDefinition.relationTypes;
|
||||||
var customRelations = component.configurationDescriptor.nodeDefinition.customRelations;
|
var linkLabels = {};
|
||||||
var linkLabels = [];
|
|
||||||
for (var i=0;i<relationTypes.length;i++) {
|
for (var i=0;i<relationTypes.length;i++) {
|
||||||
linkLabels.push({
|
var label = relationTypes[i];
|
||||||
name: relationTypes[i], custom: false
|
linkLabels[label] = {
|
||||||
});
|
name: label,
|
||||||
}
|
value: label
|
||||||
if (customRelations) {
|
};
|
||||||
linkLabels.push(
|
|
||||||
{ name: 'Custom', custom: true }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return linkLabels;
|
return linkLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ruleNodeAllowCustomLinks(component) {
|
||||||
|
return component.configurationDescriptor.nodeDefinition.customRelations;
|
||||||
|
}
|
||||||
|
|
||||||
function getRuleNodeComponents() {
|
function getRuleNodeComponents() {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
if (ruleNodeComponents) {
|
if (ruleNodeComponents) {
|
||||||
@ -226,7 +227,10 @@ function RuleChainService($http, $q, $filter, $ocLazyLoad, $translate, types, co
|
|||||||
if (res && res.length) {
|
if (res && res.length) {
|
||||||
return res[0];
|
return res[0];
|
||||||
}
|
}
|
||||||
return null;
|
var unknownComponent = angular.copy(types.unknownNodeComponent);
|
||||||
|
unknownComponent.clazz = clazz;
|
||||||
|
unknownComponent.configurationDescriptor.nodeDefinition.details = "Unknown Rule Node class: " + clazz;
|
||||||
|
return unknownComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveTargetRuleChains(ruleChainConnections) {
|
function resolveTargetRuleChains(ruleChainConnections) {
|
||||||
|
|||||||
@ -510,6 +510,22 @@ export default angular.module('thingsboard.types', [])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
unknownNodeComponent: {
|
||||||
|
type: 'UNKNOWN',
|
||||||
|
name: 'unknown',
|
||||||
|
clazz: 'tb.internal.Unknown',
|
||||||
|
configurationDescriptor: {
|
||||||
|
nodeDefinition: {
|
||||||
|
description: "",
|
||||||
|
details: "",
|
||||||
|
inEnabled: true,
|
||||||
|
outEnabled: true,
|
||||||
|
relationTypes: [],
|
||||||
|
customRelations: false,
|
||||||
|
defaultConfiguration: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
inputNodeComponent: {
|
inputNodeComponent: {
|
||||||
type: 'INPUT',
|
type: 'INPUT',
|
||||||
name: 'Input',
|
name: 'Input',
|
||||||
@ -565,6 +581,13 @@ export default angular.module('thingsboard.types', [])
|
|||||||
nodeClass: "tb-input-type",
|
nodeClass: "tb-input-type",
|
||||||
icon: "input",
|
icon: "input",
|
||||||
special: true
|
special: true
|
||||||
|
},
|
||||||
|
UNKNOWN: {
|
||||||
|
value: "UNKNOWN",
|
||||||
|
name: "rulenode.type-unknown",
|
||||||
|
details: "rulenode.type-unknown-details",
|
||||||
|
nodeClass: "tb-unknown-type",
|
||||||
|
icon: "help_outline"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
valueType: {
|
valueType: {
|
||||||
|
|||||||
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<div flex layout="column" style="margin-top: -10px;">
|
<div flex layout="column" style="margin-top: -10px;">
|
||||||
<div flex>{{vm.item.additionalInfo.description}}</div>
|
<div style="text-transform: uppercase; padding-bottom: 5px;">{{vm.item.type}}</div>
|
||||||
<div flex style="text-transform: uppercase; padding-bottom: 10px;">{{vm.item.type}}</div>
|
<div class="tb-card-description">{{vm.item.additionalInfo.description}}</div>
|
||||||
<div class="tb-small" ng-show="vm.isAssignedToCustomer()">{{'device.assignedToCustomer' | translate}} '{{vm.item.assignedCustomer.title}}'</div>
|
<div style="padding-top: 5px;" class="tb-small" ng-show="vm.isAssignedToCustomer()">{{'device.assignedToCustomer' | translate}} '{{vm.item.assignedCustomer.title}}'</div>
|
||||||
<div class="tb-small" ng-show="vm.isPublic()">{{'device.public' | translate}}</div>
|
<div style="padding-top: 5px;" class="tb-small" ng-show="vm.isPublic()">{{'device.public' | translate}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1157,6 +1157,11 @@ export default angular.module('thingsboard.locale', [])
|
|||||||
"link-label-required": "Link label is required.",
|
"link-label-required": "Link label is required.",
|
||||||
"custom-link-label": "Custom link label",
|
"custom-link-label": "Custom link label",
|
||||||
"custom-link-label-required": "Custom link label is required.",
|
"custom-link-label-required": "Custom link label is required.",
|
||||||
|
"link-labels": "Link labels",
|
||||||
|
"link-labels-required": "Link labels is required.",
|
||||||
|
"no-link-labels-found": "No link labels found",
|
||||||
|
"no-link-label-matching": "'{{label}}' not found.",
|
||||||
|
"create-new-link-label": "Create a new one!",
|
||||||
"type-filter": "Filter",
|
"type-filter": "Filter",
|
||||||
"type-filter-details": "Filter incoming messages with configured conditions",
|
"type-filter-details": "Filter incoming messages with configured conditions",
|
||||||
"type-enrichment": "Enrichment",
|
"type-enrichment": "Enrichment",
|
||||||
@ -1171,6 +1176,8 @@ export default angular.module('thingsboard.locale', [])
|
|||||||
"type-rule-chain-details": "Forwards incoming messages to specified Rule Chain",
|
"type-rule-chain-details": "Forwards incoming messages to specified Rule Chain",
|
||||||
"type-input": "Input",
|
"type-input": "Input",
|
||||||
"type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node",
|
"type-input-details": "Logical input of Rule Chain, forwards incoming messages to next related Rule Node",
|
||||||
|
"type-unknown": "Unknown",
|
||||||
|
"type-unknown-details": "Unresolved Rule Node",
|
||||||
"directive-is-not-loaded": "Defined configuration directive '{{directiveName}}' is not available.",
|
"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!",
|
"invalid-target-rulechain": "Unable to resolve target rule chain!",
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
<span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span>
|
<span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span>
|
||||||
<md-dialog-content>
|
<md-dialog-content>
|
||||||
<div class="md-dialog-content">
|
<div class="md-dialog-content">
|
||||||
<tb-rule-node-link link="vm.link" labels="vm.labels" is-edit="true" the-form="theForm"></tb-rule-node-link>
|
<tb-rule-node-link ng-model="vm.link" allowed-labels="vm.labels" is-edit="true" allow-custom="vm.allowCustomLabels"></tb-rule-node-link>
|
||||||
</div>
|
</div>
|
||||||
</md-dialog-content>
|
</md-dialog-content>
|
||||||
<md-dialog-actions layout="row">
|
<md-dialog-actions layout="row">
|
||||||
|
|||||||
@ -17,7 +17,46 @@
|
|||||||
-->
|
-->
|
||||||
<md-content class="md-padding tb-link" layout="column">
|
<md-content class="md-padding tb-link" layout="column">
|
||||||
<fieldset ng-disabled="$root.loading || !isEdit || isReadOnly">
|
<fieldset ng-disabled="$root.loading || !isEdit || isReadOnly">
|
||||||
<md-input-container class="md-block">
|
<label translate class="tb-title no-padding" ng-class="{'tb-required': required}">rulenode.link-labels</label>
|
||||||
|
<md-chips id="link_label_chips"
|
||||||
|
ng-required="true"
|
||||||
|
readonly="$root.loading || !isEdit || isReadOnly"
|
||||||
|
ng-model="labels" md-autocomplete-snap
|
||||||
|
md-transform-chip="transformLinkLabelChip($chip)"
|
||||||
|
md-require-match="!allowCustom">
|
||||||
|
<md-autocomplete
|
||||||
|
id="link_label"
|
||||||
|
md-no-cache="true"
|
||||||
|
md-selected-item="selectedLabel"
|
||||||
|
md-search-text="labelSearchText"
|
||||||
|
md-items="item in labelsSearch(labelSearchText)"
|
||||||
|
md-item-text="item.name"
|
||||||
|
md-min-length="0"
|
||||||
|
placeholder="{{'rulenode.link-label' | translate }}"
|
||||||
|
md-menu-class="tb-link-label-autocomplete">
|
||||||
|
<span md-highlight-text="labelSearchText" md-highlight-flags="^i">{{item}}</span>
|
||||||
|
<md-not-found>
|
||||||
|
<div class="tb-not-found">
|
||||||
|
<div class="tb-no-entries" ng-if="!labelSearchText || !labelSearchText.length">
|
||||||
|
<span translate>rulenode.no-link-labels-found</span>
|
||||||
|
</div>
|
||||||
|
<div ng-if="labelSearchText && labelSearchText.length">
|
||||||
|
<span translate translate-values='{ label: "{{labelSearchText | truncate:true:6:'...'}}" }'>rulenode.no-link-label-matching</span>
|
||||||
|
<span ng-if="allowCustom">
|
||||||
|
<a translate ng-click="createLinkLabel($event, '#link_label_chips')">rulenode.create-new-link-label</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</md-not-found>
|
||||||
|
</md-autocomplete>
|
||||||
|
<md-chip-template>
|
||||||
|
<span>{{$chip.name}}</span>
|
||||||
|
</md-chip-template>
|
||||||
|
</md-chips>
|
||||||
|
<div class="tb-error-messages" ng-messages="ngModelCtrl.$error" role="alert">
|
||||||
|
<div translate ng-message="linkLabels" class="tb-error-message">rulenode.link-labels-required</div>
|
||||||
|
</div>
|
||||||
|
<!--md-input-container class="md-block">
|
||||||
<label translate>rulenode.link-label</label>
|
<label translate>rulenode.link-label</label>
|
||||||
<md-select ng-model="selectedLabel" ng-change="selectedLabelChanged()">
|
<md-select ng-model="selectedLabel" ng-change="selectedLabelChanged()">
|
||||||
<md-option ng-repeat="label in labels" ng-value="label">
|
<md-option ng-repeat="label in labels" ng-value="label">
|
||||||
@ -34,6 +73,6 @@
|
|||||||
<div ng-messages="theForm.customLinkLabel.$error">
|
<div ng-messages="theForm.customLinkLabel.$error">
|
||||||
<div translate ng-message="required">rulenode.custom-link-label-required</div>
|
<div translate ng-message="required">rulenode.custom-link-label-required</div>
|
||||||
</div>
|
</div>
|
||||||
</md-input-container>
|
</md-input-container-->
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</md-content>
|
</md-content>
|
||||||
|
|||||||
@ -14,6 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import './link.scss';
|
||||||
|
|
||||||
/* eslint-disable import/no-unresolved, import/default */
|
/* eslint-disable import/no-unresolved, import/default */
|
||||||
|
|
||||||
import linkFieldsetTemplate from './link-fieldset.tpl.html';
|
import linkFieldsetTemplate from './link-fieldset.tpl.html';
|
||||||
@ -22,13 +24,18 @@ import linkFieldsetTemplate from './link-fieldset.tpl.html';
|
|||||||
|
|
||||||
/*@ngInject*/
|
/*@ngInject*/
|
||||||
export default function LinkDirective($compile, $templateCache, $filter) {
|
export default function LinkDirective($compile, $templateCache, $filter) {
|
||||||
var linker = function (scope, element) {
|
var linker = function (scope, element, attrs, ngModelCtrl) {
|
||||||
var template = $templateCache.get(linkFieldsetTemplate);
|
var template = $templateCache.get(linkFieldsetTemplate);
|
||||||
element.html(template);
|
element.html(template);
|
||||||
|
|
||||||
scope.selectedLabel = null;
|
scope.selectedLabel = null;
|
||||||
|
scope.labelSearchText = null;
|
||||||
|
|
||||||
scope.$watch('link', function() {
|
scope.ngModelCtrl = ngModelCtrl;
|
||||||
|
|
||||||
|
var labelsList = [];
|
||||||
|
|
||||||
|
/*scope.$watch('link', function() {
|
||||||
scope.selectedLabel = null;
|
scope.selectedLabel = null;
|
||||||
if (scope.link && scope.labels) {
|
if (scope.link && scope.labels) {
|
||||||
if (scope.link.label) {
|
if (scope.link.label) {
|
||||||
@ -53,19 +60,100 @@ export default function LinkDirective($compile, $templateCache, $filter) {
|
|||||||
scope.link.label = "";
|
scope.link.label = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};*/
|
||||||
|
|
||||||
|
scope.transformLinkLabelChip = function (chip) {
|
||||||
|
var res = $filter('filter')(labelsList, {name: chip}, true);
|
||||||
|
var result;
|
||||||
|
if (res && res.length) {
|
||||||
|
result = angular.copy(res[0]);
|
||||||
|
} else {
|
||||||
|
result = {
|
||||||
|
name: chip,
|
||||||
|
value: chip
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.labelsSearch = function (searchText) {
|
||||||
|
var labels = searchText ? $filter('filter')(labelsList, {name: searchText}) : labelsList;
|
||||||
|
return labels.map((label) => label.name);
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.createLinkLabel = function (event, chipsId) {
|
||||||
|
var chipsChild = angular.element(chipsId, element)[0].firstElementChild;
|
||||||
|
var el = angular.element(chipsChild);
|
||||||
|
var chipBuffer = el.scope().$mdChipsCtrl.getChipBuffer();
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
el.scope().$mdChipsCtrl.appendChip(chipBuffer.trim());
|
||||||
|
el.scope().$mdChipsCtrl.resetChipBuffer();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ngModelCtrl.$render = function () {
|
||||||
|
labelsList.length = 0;
|
||||||
|
for (var label in scope.allowedLabels) {
|
||||||
|
var linkLabel = {
|
||||||
|
name: scope.allowedLabels[label].name,
|
||||||
|
value: scope.allowedLabels[label].value
|
||||||
|
};
|
||||||
|
labelsList.push(linkLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
var link = ngModelCtrl.$viewValue;
|
||||||
|
var labels = [];
|
||||||
|
if (link && link.labels) {
|
||||||
|
for (var i = 0; i < link.labels.length; i++) {
|
||||||
|
label = link.labels[i];
|
||||||
|
if (scope.allowedLabels[label]) {
|
||||||
|
labels.push(angular.copy(scope.allowedLabels[label]));
|
||||||
|
} else {
|
||||||
|
labels.push({
|
||||||
|
name: label,
|
||||||
|
value: label
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scope.labels = labels;
|
||||||
|
scope.$watch('labels', function (newVal, prevVal) {
|
||||||
|
if (!angular.equals(newVal, prevVal)) {
|
||||||
|
updateLabels();
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateLabels() {
|
||||||
|
if (ngModelCtrl.$viewValue) {
|
||||||
|
var labels = [];
|
||||||
|
for (var i = 0; i < scope.labels.length; i++) {
|
||||||
|
labels.push(scope.labels[i].value);
|
||||||
|
}
|
||||||
|
ngModelCtrl.$viewValue.labels = labels;
|
||||||
|
ngModelCtrl.$viewValue.label = labels.join(' / ');
|
||||||
|
updateValidity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateValidity() {
|
||||||
|
var valid = ngModelCtrl.$viewValue.labels &&
|
||||||
|
ngModelCtrl.$viewValue.labels.length ? true : false;
|
||||||
|
ngModelCtrl.$setValidity('linkLabels', valid);
|
||||||
|
}
|
||||||
|
|
||||||
$compile(element.contents())(scope);
|
$compile(element.contents())(scope);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
restrict: "E",
|
restrict: "E",
|
||||||
|
require: "^ngModel",
|
||||||
link: linker,
|
link: linker,
|
||||||
scope: {
|
scope: {
|
||||||
link: '=',
|
allowedLabels: '=',
|
||||||
labels: '=',
|
allowCustom: '=',
|
||||||
isEdit: '=',
|
isEdit: '=',
|
||||||
isReadOnly: '=',
|
isReadOnly: '='
|
||||||
theForm: '='
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
30
ui/src/app/rulechain/link.scss
Normal file
30
ui/src/app/rulechain/link.scss
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2018 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.tb-link-label-autocomplete {
|
||||||
|
.tb-not-found {
|
||||||
|
display: block;
|
||||||
|
line-height: 1.5;
|
||||||
|
height: 48px;
|
||||||
|
.tb-no-entries {
|
||||||
|
line-height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
height: auto !important;
|
||||||
|
white-space: normal !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -669,11 +669,15 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (edge.label) {
|
if (edge.label) {
|
||||||
|
if (!edge.labels) {
|
||||||
|
edge.labels = edge.label.split(' / ');
|
||||||
|
}
|
||||||
deferred.resolve(edge);
|
deferred.resolve(edge);
|
||||||
} else {
|
} else {
|
||||||
var labels = ruleChainService.getRuleNodeSupportedLinks(sourceNode.component);
|
var labels = ruleChainService.getRuleNodeSupportedLinks(sourceNode.component);
|
||||||
|
var allowCustomLabels = ruleChainService.ruleNodeAllowCustomLinks(sourceNode.component);
|
||||||
vm.enableHotKeys = false;
|
vm.enableHotKeys = false;
|
||||||
addRuleNodeLink(event, edge, labels).then(
|
addRuleNodeLink(event, edge, labels, allowCustomLabels).then(
|
||||||
(link) => {
|
(link) => {
|
||||||
deferred.resolve(link);
|
deferred.resolve(link);
|
||||||
vm.enableHotKeys = true;
|
vm.enableHotKeys = true;
|
||||||
@ -713,6 +717,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
vm.isEditingRuleNode = false;
|
vm.isEditingRuleNode = false;
|
||||||
vm.editingRuleNode = null;
|
vm.editingRuleNode = null;
|
||||||
vm.editingRuleNodeLinkLabels = ruleChainService.getRuleNodeSupportedLinks(sourceNode.component);
|
vm.editingRuleNodeLinkLabels = ruleChainService.getRuleNodeSupportedLinks(sourceNode.component);
|
||||||
|
vm.editingRuleNodeAllowCustomLabels = ruleChainService.ruleNodeAllowCustomLinks(sourceNode.component);
|
||||||
vm.isEditingRuleNodeLink = true;
|
vm.isEditingRuleNodeLink = true;
|
||||||
vm.editingRuleNodeLinkIndex = vm.ruleChainModel.edges.indexOf(edge);
|
vm.editingRuleNodeLinkIndex = vm.ruleChainModel.edges.indexOf(edge);
|
||||||
vm.editingRuleNodeLink = angular.copy(edge);
|
vm.editingRuleNodeLink = angular.copy(edge);
|
||||||
@ -744,7 +749,8 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
isInputSource: isInputSource,
|
isInputSource: isInputSource,
|
||||||
fromIndex: fromIndex,
|
fromIndex: fromIndex,
|
||||||
toIndex: toIndex,
|
toIndex: toIndex,
|
||||||
label: edge.label
|
label: edge.label,
|
||||||
|
labels: edge.labels
|
||||||
};
|
};
|
||||||
connections.push(connection);
|
connections.push(connection);
|
||||||
}
|
}
|
||||||
@ -816,7 +822,8 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
var edge = {
|
var edge = {
|
||||||
source: source,
|
source: source,
|
||||||
destination: destination,
|
destination: destination,
|
||||||
label: connection.label
|
label: connection.label,
|
||||||
|
labels: connection.labels
|
||||||
};
|
};
|
||||||
vm.ruleChainModel.edges.push(edge);
|
vm.ruleChainModel.edges.push(edge);
|
||||||
vm.modelservice.edges.select(edge);
|
vm.modelservice.edges.select(edge);
|
||||||
@ -1024,6 +1031,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vm.ruleChainMetaData.connections) {
|
if (vm.ruleChainMetaData.connections) {
|
||||||
|
var edgeMap = {};
|
||||||
for (i = 0; i < vm.ruleChainMetaData.connections.length; i++) {
|
for (i = 0; i < vm.ruleChainMetaData.connections.length; i++) {
|
||||||
var connection = vm.ruleChainMetaData.connections[i];
|
var connection = vm.ruleChainMetaData.connections[i];
|
||||||
var sourceNode = nodes[connection.fromIndex];
|
var sourceNode = nodes[connection.fromIndex];
|
||||||
@ -1032,12 +1040,23 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
var sourceConnectors = vm.modelservice.nodes.getConnectorsByType(sourceNode, flowchartConstants.rightConnectorType);
|
var sourceConnectors = vm.modelservice.nodes.getConnectorsByType(sourceNode, flowchartConstants.rightConnectorType);
|
||||||
var destConnectors = vm.modelservice.nodes.getConnectorsByType(destNode, flowchartConstants.leftConnectorType);
|
var destConnectors = vm.modelservice.nodes.getConnectorsByType(destNode, flowchartConstants.leftConnectorType);
|
||||||
if (sourceConnectors && sourceConnectors.length && destConnectors && destConnectors.length) {
|
if (sourceConnectors && sourceConnectors.length && destConnectors && destConnectors.length) {
|
||||||
|
var sourceId = sourceConnectors[0].id;
|
||||||
|
var destId = destConnectors[0].id;
|
||||||
|
var edgeKey = sourceId + '_' + destId;
|
||||||
|
edge = edgeMap[edgeKey];
|
||||||
|
if (!edge) {
|
||||||
edge = {
|
edge = {
|
||||||
source: sourceConnectors[0].id,
|
source: sourceId,
|
||||||
destination: destConnectors[0].id,
|
destination: destId,
|
||||||
label: connection.type
|
label: connection.type,
|
||||||
|
labels: [connection.type]
|
||||||
};
|
};
|
||||||
|
edgeMap[edgeKey] = edge;
|
||||||
vm.ruleChainModel.edges.push(edge);
|
vm.ruleChainModel.edges.push(edge);
|
||||||
|
} else {
|
||||||
|
edge.label += ' / ' +connection.type;
|
||||||
|
edge.labels.push(connection.type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1045,6 +1064,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
|
|
||||||
if (vm.ruleChainMetaData.ruleChainConnections) {
|
if (vm.ruleChainMetaData.ruleChainConnections) {
|
||||||
var ruleChainNodesMap = {};
|
var ruleChainNodesMap = {};
|
||||||
|
var ruleChainEdgeMap = {};
|
||||||
for (i = 0; i < vm.ruleChainMetaData.ruleChainConnections.length; i++) {
|
for (i = 0; i < vm.ruleChainMetaData.ruleChainConnections.length; i++) {
|
||||||
var ruleChainConnection = vm.ruleChainMetaData.ruleChainConnections[i];
|
var ruleChainConnection = vm.ruleChainMetaData.ruleChainConnections[i];
|
||||||
var ruleChain = ruleChainsMap[ruleChainConnection.targetRuleChainId.id];
|
var ruleChain = ruleChainsMap[ruleChainConnection.targetRuleChainId.id];
|
||||||
@ -1081,12 +1101,23 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
if (sourceNode) {
|
if (sourceNode) {
|
||||||
connectors = vm.modelservice.nodes.getConnectorsByType(sourceNode, flowchartConstants.rightConnectorType);
|
connectors = vm.modelservice.nodes.getConnectorsByType(sourceNode, flowchartConstants.rightConnectorType);
|
||||||
if (connectors && connectors.length) {
|
if (connectors && connectors.length) {
|
||||||
var ruleChainEdge = {
|
sourceId = connectors[0].id;
|
||||||
source: connectors[0].id,
|
destId = ruleChainNode.connectors[0].id;
|
||||||
destination: ruleChainNode.connectors[0].id,
|
edgeKey = sourceId + '_' + destId;
|
||||||
label: ruleChainConnection.type
|
var ruleChainEdge = ruleChainEdgeMap[edgeKey];
|
||||||
|
if (!ruleChainEdge) {
|
||||||
|
ruleChainEdge = {
|
||||||
|
source: sourceId,
|
||||||
|
destination: destId,
|
||||||
|
label: ruleChainConnection.type,
|
||||||
|
labels: [ruleChainConnection.type]
|
||||||
};
|
};
|
||||||
|
ruleChainEdgeMap[edgeKey] = ruleChainEdge;
|
||||||
vm.ruleChainModel.edges.push(ruleChainEdge);
|
vm.ruleChainModel.edges.push(ruleChainEdge);
|
||||||
|
} else {
|
||||||
|
ruleChainEdge.label += ' / ' +ruleChainConnection.type;
|
||||||
|
ruleChainEdge.labels.push(ruleChainConnection.type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1199,8 +1230,7 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
var ruleChainConnection = {
|
var ruleChainConnection = {
|
||||||
fromIndex: fromIndex,
|
fromIndex: fromIndex,
|
||||||
targetRuleChainId: {entityType: vm.types.entityType.rulechain, id: destNode.targetRuleChainId},
|
targetRuleChainId: {entityType: vm.types.entityType.rulechain, id: destNode.targetRuleChainId},
|
||||||
additionalInfo: destNode.additionalInfo,
|
additionalInfo: destNode.additionalInfo
|
||||||
type: edge.label
|
|
||||||
};
|
};
|
||||||
if (!ruleChainConnection.additionalInfo) {
|
if (!ruleChainConnection.additionalInfo) {
|
||||||
ruleChainConnection.additionalInfo = {};
|
ruleChainConnection.additionalInfo = {};
|
||||||
@ -1208,15 +1238,22 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
ruleChainConnection.additionalInfo.layoutX = Math.round(destNode.x);
|
ruleChainConnection.additionalInfo.layoutX = Math.round(destNode.x);
|
||||||
ruleChainConnection.additionalInfo.layoutY = Math.round(destNode.y);
|
ruleChainConnection.additionalInfo.layoutY = Math.round(destNode.y);
|
||||||
ruleChainConnection.additionalInfo.ruleChainNodeId = destNode.id;
|
ruleChainConnection.additionalInfo.ruleChainNodeId = destNode.id;
|
||||||
ruleChainMetaData.ruleChainConnections.push(ruleChainConnection);
|
for (var rcIndex=0;rcIndex<edge.labels.length;rcIndex++) {
|
||||||
|
var newRuleChainConnection = angular.copy(ruleChainConnection);
|
||||||
|
newRuleChainConnection.type = edge.labels[rcIndex];
|
||||||
|
ruleChainMetaData.ruleChainConnections.push(newRuleChainConnection);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
var toIndex = nodes.indexOf(destNode);
|
var toIndex = nodes.indexOf(destNode);
|
||||||
var nodeConnection = {
|
var nodeConnection = {
|
||||||
fromIndex: fromIndex,
|
fromIndex: fromIndex,
|
||||||
toIndex: toIndex,
|
toIndex: toIndex
|
||||||
type: edge.label
|
|
||||||
};
|
};
|
||||||
ruleChainMetaData.connections.push(nodeConnection);
|
for (var cIndex=0;cIndex<edge.labels.length;cIndex++) {
|
||||||
|
var newNodeConnection = angular.copy(nodeConnection);
|
||||||
|
newNodeConnection.type = edge.labels[cIndex];
|
||||||
|
ruleChainMetaData.connections.push(newNodeConnection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1285,13 +1322,13 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addRuleNodeLink($event, link, labels) {
|
function addRuleNodeLink($event, link, labels, allowCustomLabels) {
|
||||||
return $mdDialog.show({
|
return $mdDialog.show({
|
||||||
controller: 'AddRuleNodeLinkController',
|
controller: 'AddRuleNodeLinkController',
|
||||||
controllerAs: 'vm',
|
controllerAs: 'vm',
|
||||||
templateUrl: addRuleNodeLinkTemplate,
|
templateUrl: addRuleNodeLinkTemplate,
|
||||||
parent: angular.element($document[0].body),
|
parent: angular.element($document[0].body),
|
||||||
locals: {link: link, labels: labels},
|
locals: {link: link, labels: labels, allowCustomLabels: allowCustomLabels},
|
||||||
fullscreen: true,
|
fullscreen: true,
|
||||||
targetEvent: $event
|
targetEvent: $event
|
||||||
});
|
});
|
||||||
@ -1335,13 +1372,14 @@ export function AddRuleNodeController($scope, $mdDialog, ruleNode, ruleChainId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*@ngInject*/
|
/*@ngInject*/
|
||||||
export function AddRuleNodeLinkController($scope, $mdDialog, link, labels, helpLinks) {
|
export function AddRuleNodeLinkController($scope, $mdDialog, link, labels, allowCustomLabels, helpLinks) {
|
||||||
|
|
||||||
var vm = this;
|
var vm = this;
|
||||||
|
|
||||||
vm.helpLinks = helpLinks;
|
vm.helpLinks = helpLinks;
|
||||||
vm.link = link;
|
vm.link = link;
|
||||||
vm.labels = labels;
|
vm.labels = labels;
|
||||||
|
vm.allowCustomLabels = allowCustomLabels;
|
||||||
|
|
||||||
vm.add = add;
|
vm.add = add;
|
||||||
vm.cancel = cancel;
|
vm.cancel = cancel;
|
||||||
|
|||||||
@ -170,6 +170,9 @@
|
|||||||
&.tb-rule-chain-type {
|
&.tb-rule-chain-type {
|
||||||
background-color: #d6c4f1;
|
background-color: #d6c4f1;
|
||||||
}
|
}
|
||||||
|
&.tb-unknown-type {
|
||||||
|
background-color: #f16c29;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tb-rule-node {
|
.tb-rule-node {
|
||||||
@ -202,6 +205,7 @@
|
|||||||
background-color: #a3eaa9;
|
background-color: #a3eaa9;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
md-icon {
|
md-icon {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
|||||||
@ -207,11 +207,11 @@
|
|||||||
</details-buttons>
|
</details-buttons>
|
||||||
<form name="vm.ruleNodeLinkForm" ng-if="vm.isEditingRuleNodeLink">
|
<form name="vm.ruleNodeLinkForm" ng-if="vm.isEditingRuleNodeLink">
|
||||||
<tb-rule-node-link
|
<tb-rule-node-link
|
||||||
link="vm.editingRuleNodeLink"
|
ng-model="vm.editingRuleNodeLink"
|
||||||
labels="vm.editingRuleNodeLinkLabels"
|
allowed-labels="vm.editingRuleNodeLinkLabels"
|
||||||
|
allow-custom="vm.editingRuleNodeAllowCustomLabels"
|
||||||
is-edit="true"
|
is-edit="true"
|
||||||
is-read-only="false"
|
is-read-only="false">
|
||||||
the-form="vm.ruleNodeLinkForm">
|
|
||||||
</tb-rule-node-link>
|
</tb-rule-node-link>
|
||||||
</form>
|
</form>
|
||||||
</tb-details-sidenav>
|
</tb-details-sidenav>
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
@import "~compass-sass-mixins/lib/compass";
|
@import "~compass-sass-mixins/lib/compass";
|
||||||
@import "constants";
|
@import "constants";
|
||||||
@import "animations";
|
@import "animations";
|
||||||
|
@import "mixins";
|
||||||
@import "fonts";
|
@import "fonts";
|
||||||
|
|
||||||
/***************
|
/***************
|
||||||
@ -437,6 +438,12 @@ pre.tb-highlight {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tb-card-description {
|
||||||
|
color: rgba(0,0,0,0.54);
|
||||||
|
font-size: 13px;
|
||||||
|
@include line-clamp(2, 1.1);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************
|
/***********************
|
||||||
* Flow
|
* Flow
|
||||||
***********************/
|
***********************/
|
||||||
|
|||||||
@ -32,3 +32,28 @@
|
|||||||
@content;
|
@content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin line-clamp($numLines: 1, $lineHeight: 1.412) {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
line-height: $lineHeight;
|
||||||
|
text-align: justify;
|
||||||
|
margin-right: -1em;
|
||||||
|
padding-right: 2em;
|
||||||
|
max-height: ($numLines*$lineHeight)+em;
|
||||||
|
&:before {
|
||||||
|
content: '...';
|
||||||
|
position: absolute;
|
||||||
|
right: 1em;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
right: 1em;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
margin-top: 0.2em;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user