ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nc...@apache.org
Subject [24/28] ambari git commit: AMBARI-20296. Workflow Manger support for pointing to kill node in decision editor.(Padma Priya N via gauravn7)
Date Fri, 03 Mar 2017 18:04:11 GMT
AMBARI-20296. Workflow Manger support for pointing to kill node in decision editor.(Padma Priya
N via gauravn7)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f7472a09
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f7472a09
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f7472a09

Branch: refs/heads/branch-feature-AMBARI-12556
Commit: f7472a09a650c76ea84c4e98492e7aa081887443
Parents: 1766ebf
Author: Gaurav Nagar <grvngr@gmail.com>
Authored: Fri Mar 3 21:02:56 2017 +0530
Committer: Gaurav Nagar <grvngr@gmail.com>
Committed: Fri Mar 3 21:02:56 2017 +0530

----------------------------------------------------------------------
 .../ui/app/components/decision-add-branch.js    |  5 ++-
 .../ui/app/components/decision-config.js        | 10 ++++-
 .../ui/app/components/flow-designer.js          | 33 +++++++++------
 .../ui/app/components/transition-config.js      |  3 ++
 .../ui/app/components/workflow-action-editor.js | 35 +++++++++-------
 .../ui/app/domain/cytoscape-flow-renderer.js    |  7 +++-
 .../src/main/resources/ui/app/domain/node.js    |  7 +++-
 .../main/resources/ui/app/domain/workflow.js    |  2 +-
 .../templates/components/decision-config.hbs    |  8 +++-
 .../app/templates/components/flow-designer.hbs  |  4 +-
 .../templates/components/transition-config.hbs  |  5 +++
 .../components/workflow-action-editor.hbs       |  2 +-
 .../resources/ui/app/validators/workflow-dag.js | 43 ++++++++++++++++++++
 13 files changed, 126 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-add-branch.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-add-branch.js
b/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-add-branch.js
index 41bb1e5..4066c79 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-add-branch.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-add-branch.js
@@ -55,7 +55,8 @@ export default Ember.Component.extend(Validations, FindNodeMixin,{
         self.set("isInsertAction",false);
         this.set("newNodeType",null);
         this.get('flowRenderer').populateOkToandErrorTONodes(node);
-        var descendantNodes= this.get('node.validOkToNodes');
+        var descendantNodes= Ember.A([]);
+        descendantNodes.pushObjects(this.get('node.validOkToNodes'));
         this.set('descendantNodes',descendantNodes);
         self.$("#selector-content").show();
       }
@@ -69,7 +70,7 @@ export default Ember.Component.extend(Validations, FindNodeMixin,{
       this.set("newNodeType",type);
     },
     onTargetNodeChange(value){
-      var node = this.get('descendantNodes').findBy('id',value);
+      var node = this.get('descendantNodes').findBy('id',value) || this.get('killNodes').findBy('id',value);
       this.set('targetNode', node);
     },
     save(){

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-config.js
b/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-config.js
index 419be37..0df3f96 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-config.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/decision-config.js
@@ -32,6 +32,14 @@ export default Ember.Component.extend(Validations,{
   initialize : function(){
     this.sendAction('register','decision',this);
     this.set('targetNodes', Ember.A([]));
+    this.get('targetNodes').pushObjects(this.get('currentNode.validOkToNodes'));
     this.get('targetNodes').pushObjects(this.get('killNodes'));
-  }.on('init')
+  }.on('init'),
+  actions : {
+    onTargetNodeChange(index){
+      var node = this.get('targetNodes').findBy('id', this.$(`#target-node-select-${index}`).find(":selected").val());
+      var config = this.get('actionModel').objectAt(index);
+      Ember.set(config, 'node', node);
+    }
+  }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
b/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
index 2f8455f..6af82ba 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/flow-designer.js
@@ -35,6 +35,9 @@ const Validations = buildValidations({
     validators: [
       validator('duplicate-data-node-name', {
         dependentKeys: ['dataNodes.@each.dataNodeName']
+      }),
+      validator('workflow-dag', {
+        dependentKeys: ['dataNodes.@each.source', 'dataNodes.@each.target']
       })
     ]
   },
@@ -79,8 +82,6 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
   globalConfig : {},
   assetConfig : {},
   parameters : {},
-  clonedDomain : {},
-  clonedErrorNode : {},
   validationErrors : Ember.computed('validations.attrs.dataNodes.message', 'validations.attrs.workflow.killNodes.message',
{
     get(key){
       var errors = [];
@@ -650,9 +651,7 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
     this.set('showActionEditor', true);
     this.set('currentAction', node.actionType);
     var domain = node.getNodeDetail();
-    this.set('clonedDomain', JSOG.stringify(domain));
-    this.set('clonedErrorNode', node.errorNode);
-    this.set('clonedKillMessage',node.get('killMessage'));
+    this.set('flowGraph', this.flowRenderer.getGraph());
     node.set("domain", domain);
     this.set('currentNode', node);
   },
@@ -924,7 +923,6 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
         if(transition.okToNode && trans.condition !== 'error'){
           if(trans.targetNode.id !== transition.okToNode.id){
             trans.targetNode = transition.okToNode;
-            this.showUndo('transition');
           }
         }
       }, this);
@@ -1098,20 +1096,31 @@ export default Ember.Component.extend(FindNodeMixin, Validations,
{
     resetLayout() {
       this.flowRenderer.resetLayout();
     },
+    validateWorkflow(promise){
+      this.currentNode.onSave();
+      this.rerender();
+      if(this.get('flowRenderer').isWorkflowValid()){
+        promise.resolve();
+      }else{
+        promise.reject();
+        this.send('undo');
+        this.rerender();
+      }
+    },
     closeActionEditor (isSaved){
       this.send("hideNotification");
       if(isSaved){
         this.currentNode.onSave();
         this.doValidation();
+        this.rerender();
       }	else {
-        this.set('currentNode.domain',JSOG.parse(this.get('clonedDomain')));
-        this.set('currentNode.errorNode', this.get('clonedErrorNode'));
-        if(this.currentNode.type === 'kill'){
-          this.set('currentNode.killMessage', this.get('clonedKillMessage'));
-        }
+        this.send('undo');
       }
       this.set('showActionEditor', false);
-      this.rerender();
+      var newGraph = this.flowRenderer.getGraph();
+      if(!this.get('flowGraph').same(newGraph)){
+        this.showUndo('transition');
+      }
     },
     saveDraft(){
       this.persistWorkInProgress();

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/components/transition-config.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/transition-config.js
b/contrib/views/wfmanager/src/main/resources/ui/app/components/transition-config.js
index ce04863..6c63ac4 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/transition-config.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/transition-config.js
@@ -62,6 +62,9 @@ export default Ember.Component.extend(FindNodeMixin, Validations, {
     okToHandler (name){
       var validOkToNodes = this.get('currentNode.validOkToNodes');
       var node = validOkToNodes.findBy('name',name);
+      if(!node){
+        node = this.get('killNodes').findBy('name',name);
+      }
       if(node.id !== this.get('defaultOkToNode').id){
         this.set('showWarning', true);
       }else{

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
b/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
index 09bffe7..7bf3534 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/components/workflow-action-editor.js
@@ -115,6 +115,8 @@ export default Ember.Component.extend( Ember.Evented,{
         }
         if(Ember.isBlank(temp[actionType])){
           this.set('actionModel', {});
+        }else if(typeof temp[actionType] === 'string'){
+          this.get('errors').pushObject({message:'Invalid definition'});
         }else{
           this.set('actionModel', temp[actionType]);
         }
@@ -163,6 +165,7 @@ export default Ember.Component.extend( Ember.Evented,{
       delete this.get('actionModel').slaInfo;
       delete this.get('actionModel').slaEnabled;
     }
+    this.set('errors', Ember.A([]));
   }.on('init'),
   initialize : function(){
     this.$('#action_properties_dialog').modal({
@@ -171,7 +174,7 @@ export default Ember.Component.extend( Ember.Evented,{
     });
     this.$('#action_properties_dialog').modal('show');
     this.$('#action_properties_dialog').modal().on('hidden.bs.modal', function() {
-      this.sendAction('closeActionEditor', this.get('saveClicked'));
+      this.sendAction('closeActionEditor', this.get('saveClicked'), this.get('transition'));
     }.bind(this));
     this.get('fileBrowser').on('fileBrowserOpened',function(context){
       this.get('fileBrowser').setContext(context);
@@ -211,24 +214,23 @@ export default Ember.Component.extend( Ember.Evented,{
       }
     });
   },
-  validateDecisionNode(){
-    let containsOtherNodes = false;
-    this.get('actionModel').forEach((model)=>{
-      if(model.node.type !== 'kill'){
-        containsOtherNodes = true;
-      }
+  validateFlowGraph(){
+    return new Ember.RSVP.Promise((resolve, reject) =>{
+      var deferred = new Ember.RSVP.defer();
+      this.sendAction('validateWorkflow', deferred);
+      deferred.promise.then(()=>{
+        resolve();
+      }).catch(()=>{
+        reject();
+      });
     });
-    if(!containsOtherNodes){
-      this.get('errors').pushObject({message:'Atleast one of the decision branches should
transition to a node other than a kill node.'});
-    }else{
-      this.get('errors').clear();
-    }
   },
   actions : {
     closeEditor (){
       this.sendAction('close');
     },
     save () {
+      this.set('validationErrors', Ember.A([]));
       var isChildComponentsValid = this.validateChildrenComponents();
       if(this.get('validations.isInvalid') || !isChildComponentsValid || this.get('errors').length
> 0) {
         this.set('showErrorMessage', true);
@@ -240,9 +242,14 @@ export default Ember.Component.extend( Ember.Evented,{
       }
       this.processMultivaluedComponents();
       this.processStaticProps();
-      this.$('#action_properties_dialog').modal('hide');
       this.sendAction('setNodeTransitions', this.get('transition'));
-      this.set('saveClicked', true);
+      this.validateFlowGraph().then(()=>{
+        this.set('saveClicked', true);
+        this.$('#action_properties_dialog').modal('hide');
+      }).catch(()=>{
+        this.set('saveClicked', false);
+        this.get('validationErrors').pushObject({message : "Invalid workflow structure. There
is no flow to end node."});
+      });
     },
     openFileBrowser(model, context){
       if(!context){

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
b/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
index ae178b3..f8796ae 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/cytoscape-flow-renderer.js
@@ -369,13 +369,16 @@ var CytoscapeRenderer= Ember.Object.extend({
       return descendantNode.get('type') === 'placeholder' || descendantNode.get('type') ===
'kill' || descendantNode.id === node.id;
     }, this);
     errorToNodes = descendantNodes.reject((descendantNode)=>{
-      return descendantNode.get('type') === 'placeholder' || descendantNode.id === node.id;
+      return descendantNode.get('type') === 'placeholder' || descendantNode.get('type') ===
'kill' || descendantNode.id === node.id;
     }, this);
     node.set('validOkToNodes', okToNodes);
     node.set('validErrorToNodes', errorToNodes);
   },
+  getGraph(){
+    return this.cy.$('node');
+  },
   isWorkflowValid(){
-    return this.cy.nodes("node[name][type='start']").successors("node[name]").intersection(this.cy.nodes("node[name][type='end']").length
> 0);
+    return this.cy.nodes("node[name][type='start']").successors("node[name]").intersection(this.cy.nodes("node[name][type='end']")).length
> 0;
   },
   renderWorkflow(workflow){
     this._getCyDataNodes(workflow);

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/domain/node.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/node.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/node.js
index d815df1..70ac19f 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/node.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/node.js
@@ -39,6 +39,9 @@ var Node = Ember.Object.extend(FindNodeMixin,{
       var i=0;
       this.get("domain").forEach(function(tran){
         self.get("transitions")[i].condition=tran.condition;
+        if(self.get("transitions")[i].targetNode.id !== tran.node.id){
+          self.get("transitions")[i].targetNode = tran.node;
+        }
         i++;
       });
     }else if (this.isActionNode()){
@@ -66,7 +69,7 @@ var Node = Ember.Object.extend(FindNodeMixin,{
     if (this.isDecisionNode()){
       var flows=[];
       this.get("transitions").forEach(function(tran){
-        flows.push({condition: tran.condition, targetName: tran.getTargetNode().getName()});
+        flows.push({condition: tran.condition, node: tran.getTargetNode(true)});
       });
       this.set("domain",flows);
       return this.get("domain");
@@ -199,7 +202,7 @@ var Node = Ember.Object.extend(FindNodeMixin,{
     }else{
       target=transitions[0].targetNode;
     }
-    if (target.isPlaceholder()){
+    if (target && target.isPlaceholder()){
       return target.getDefaultTransitionTarget();
     }
     return target;

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow.js b/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow.js
index 228f0e2..a8e45c1 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow.js
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/domain/workflow.js
@@ -186,7 +186,7 @@ var Workflow= Ember.Object.extend(FindNodeMixin,{
   deleteNode(node,transitionslist){
     var self=this;
     var target=node.getDefaultTransitionTarget();
-    if (!target.isEndNode() && (node.isForkNode()|| node.isDecisionNode())){
+    if (target && !target.isEndNode() && (node.isForkNode()|| node.isDecisionNode())){
       target=this.findJoinNode(node);
       if (!target){//A bug will give target as null if the decision has single path.
         target=node.getDefaultTransitionTarget();

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/decision-config.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/decision-config.hbs
b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/decision-config.hbs
index cb7ff46..87274b0 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/decision-config.hbs
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/decision-config.hbs
@@ -29,7 +29,13 @@
       {{#each actionModel as |flow index|}}
       <tr class="{{if (eq flow.condition 'default') 'active'}}">
         <td>{{input type="text" class="form-control" value=flow.condition placeholder="condition"}}</td>
-        <td>{{flow.targetName}}</td>
+        <td>
+          <select id="target-node-select-{{index}}" {{action "onTargetNodeChange" index
on="change"}} name="select-node" class="form-control">
+            {{#each targetNodes as |node index|}}
+              <option value={{node.id}} selected={{eq node.name flow.node.name}}>{{node.name}}</option>
+            {{/each}}
+          </select>
+        </td>
       </tr>
       {{/each}}
   </tbody>

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
index d428815..2c85985 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/flow-designer.hbs
@@ -251,7 +251,7 @@
               <i class="fa fa-cloud-upload"></i>
             </span>
           </div>
-          {{decision-add-branch node=node registerAddBranchAction="registerAddBranchAction"
addDecisionBranch="addDecisionBranch" workflow=workflow flowRenderer=flowRenderer}}
+          {{decision-add-branch node=node killNodes=workflow.killNodes registerAddBranchAction="registerAddBranchAction"
addDecisionBranch="addDecisionBranch" workflow=workflow flowRenderer=flowRenderer}}
         </div>
           {{#if cyOverflow.overflown}}
             <div class="cyScrollMsg"><i class="fa fa-ellipsis-h cyScrollMsgContent"
title="Use the pan tool or drag on canvas to see more" aria-hidden="true"></i></div>
@@ -269,7 +269,7 @@
 
 
 {{#if showActionEditor}}
-  {{workflow-action-editor actionType=currentAction closeActionEditor="closeActionEditor"
setNodeTransitions="setNodeTransitions" actionModel=currentNode.domain nodeType=currentNode.type
currentNode=currentNode killNodes=workflow.killNodes credentials=workflow.credentials}}
+  {{workflow-action-editor actionType=currentAction closeActionEditor="closeActionEditor"
setNodeTransitions="setNodeTransitions" actionModel=currentNode.domain nodeType=currentNode.type
currentNode=currentNode killNodes=workflow.killNodes credentials=workflow.credentials validateWorkflow="validateWorkflow"}}
 {{/if}}
 {{#if showingSaveWorkflow}}
   {{save-wf type='wf' close="closeSaveWorkflow" showSuccessMessage="showSuccessMessage" jobFilePath=workflowFilePath
openFileBrowser="openFileBrowser" closeFileBrowser="closeFileBrowser" jobConfigs=configForSave}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/transition-config.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/transition-config.hbs
b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/transition-config.hbs
index fe46446..83fe96c 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/transition-config.hbs
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/transition-config.hbs
@@ -37,6 +37,11 @@
   <label class="control-label col-xs-2">Ok To<span class="requiredField">&nbsp;*</span></label>
   <div class=" col-xs-7">
     <select onchange={{action "okToHandler" value="target.value"}} name="select-node"
class="form-control" data-show-icon="true">
+      <optgroup label="Kill Nodes"></optgroup>
+      {{#each killNodes as |node index|}}
+      <option value={{node.name}} selected={{eq node.name transition.okToNode.name}}>{{node.name}}</option>
+      {{/each}}
+      <optgroup label="Other Nodes"></optgroup>
       {{#each currentNode.validOkToNodes as |node index|}}
         <option value={{node.name}} selected={{eq node.name transition.okToNode.name}}>{{node.name}}</option>
       {{/each}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
index 788916b..c9064a5 100644
--- a/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/templates/components/workflow-action-editor.hbs
@@ -31,8 +31,8 @@
       <div class="modal-body">
         <div>
             <form class="form-horizontal" id="action_properties">
+              {{designer-errors errors=errors validationErrors=validationErrors}}
               {{#if (eq nodeType 'decision')}}
-                {{designer-errors errors=errors}}
                 {{#decision-config currentNode=currentNode actionModel=actionModel killNodes=killNodes
register="registerChild"}}{{/decision-config}}
               {{/if}}
               {{#if (eq nodeType 'action')}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/f7472a09/contrib/views/wfmanager/src/main/resources/ui/app/validators/workflow-dag.js
----------------------------------------------------------------------
diff --git a/contrib/views/wfmanager/src/main/resources/ui/app/validators/workflow-dag.js
b/contrib/views/wfmanager/src/main/resources/ui/app/validators/workflow-dag.js
new file mode 100644
index 0000000..18da25b
--- /dev/null
+++ b/contrib/views/wfmanager/src/main/resources/ui/app/validators/workflow-dag.js
@@ -0,0 +1,43 @@
+/*
+*    Licensed to the Apache Software Foundation (ASF) under one or more
+*    contributor license agreements.  See the NOTICE file distributed with
+*    this work for additional information regarding copyright ownership.
+*    The ASF licenses this file to You 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.
+*/
+import Ember from 'ember';
+import BaseValidator from 'ember-cp-validations/validators/base';
+
+const DuplicateDataNodeName = BaseValidator.extend({
+  validate(value, options, model, attribute) {
+    if (model.get('dataNodes')) {
+      if(!model.get('flowRenderer').isWorkflowValid()){
+        return "Invalid workflow structure. There is no flow to end node."
+      }
+    }
+  }
+});
+
+DuplicateDataNodeName.reopenClass({
+  /**
+   * Define attribute specific dependent keys for your validator
+   *
+   * @param {String}  attribute   The attribute being evaluated
+   * @param {Unknown} options     Options passed into your validator
+   * @return {Array}
+   */
+  getDependentsFor(/* attribute, options */) {
+    return [];
+  }
+});
+
+export default DuplicateDataNodeName;


Mime
View raw message