Skip to content

Commit

Permalink
Merge pull request #24 from SyncfusionExamples/402675-BranchonPickerI…
Browse files Browse the repository at this point in the history
…nput

Feature(402675):Branching on Picker Input
  • Loading branch information
NavinVinayagam authored Jan 3, 2025
2 parents a7e4d41 + 7739a51 commit f0ecf03
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 67 deletions.
2 changes: 1 addition & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ import { WorkflowDiagramComponent } from './components/workflow-diagram/workflow
})

export class AppComponent {
public workflowID: number = 7;
public workflowID: number = 8;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<div>
<ejs-diagram class="diagram-container" #diagram
id="diagram" [width]="'100%'" [height]="649" [nodes]="nodes"
id="diagram" [width]="'100%'" [height]="'900'" [nodes]="nodes"
[connectors]="connectors" [layout]="layout" [getNodeDefaults]="getNodeDefaults"
[getConnectorDefaults]="getConnectorDefaults" (created)="onDiagramCreated()" [selectedItems]="selectedItems"
(onUserHandleMouseDown)="onUserHandleMouseDown($event)" (click)="onNodeClick($event)" [snapSettings]="snapSettings" [dataSourceSettings]='dataSourceSettings'>
Expand Down Expand Up @@ -137,13 +137,43 @@
}
}
}
@case(chatWorkflowBlockTypeEnum.BranchOnPickerInput){
@switch (data.data.chatWorkflowEditorTypeId){
@case (chatWorkflowEditorTypeEnum.ButtonsBranch){
<ng-container>
@for(option of data.data.fieldOptionDetails; track $index){
<div class="button-item">
<button ejs-button cssClass="e-primary" style="width: 75%;">{{$index+1}}.{{option.label}}</button>
@if(checkBranchAdd(data.data.branchDetails, option.value)){
<button #addbtn ejs-button id="addbtn{{$index}}" iconCss='e-icons e-plus' cssClass='e-caret-hide'
(click)="onClickAddBtn(option, $index)"></button>
}
</div>
}
</ng-container>
}
@case (chatWorkflowEditorTypeEnum.DropdownBranch){
<ng-container>
<ejs-dropdownlist [dataSource]="data.data.fieldOptionDetails" [fields]="ddlFields"
[placeholder]="data.data.fieldDetails.placeholder" cssClass="e-primary" width="85%">
</ejs-dropdownlist>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.ListBranch){
<ng-container>
<ejs-listview id='sample-list' [dataSource]='data.data.fieldOptionDetails'
[fields]='ddlFields'></ejs-listview>
</ng-container>
}
}
}
}
</ng-template>
</ejs-diagram>
</div>
</div>

<app-workflow-sidebar #workflowSidebar [nodeEditType]="nodeEditType" [nodeBlockType]="nodeBlockType" [sidebarHeader]="sidebarHeader" [clickedNodeRuleId]="clickedNodeRuleId" [selectedWorkFlowId]="selectedWorkFlowId" (ruleNodeChange)="onRuleNodeChange()"></app-workflow-sidebar>
<app-workflow-sidebar #workflowSidebar [nodeEditType]="nodeEditType" [nodeBlockType]="nodeBlockType" [sidebarHeader]="sidebarHeader" [clickedNodeRuleId]="clickedNodeRuleId" [selectedWorkFlowId]="selectedWorkFlowId" [optionValue]="optionValue" (ruleNodeChange)="onRuleNodeChange()"></app-workflow-sidebar>

<!-- <div style="display: none;">
<ejs-uploader #defaultupload id='fileupload' (success)='onUploadSuccess($event)' [asyncSettings]='asyncSettings'></ejs-uploader>
Expand Down
53 changes: 38 additions & 15 deletions src/app/components/workflow-diagram/workflow-diagram.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { AfterViewInit, Component, ElementRef, EventEmitter, Input, ViewChild }
import { ConnectionPointOrigin, ConnectorConstraints, ConnectorModel, DecoratorModel, Diagram, DiagramComponent, DiagramModule,
HierarchicalTree, HierarchicalTreeService, HtmlModel, IClickEventArgs, LayoutModel, LineDistribution, Node, NodeModel, PrintAndExport,
SelectorConstraints, SelectorModel, SnapSettingsModel, UserHandleEventsArgs, UserHandleModel, DataSourceModel,
DataBindingService} from '@syncfusion/ej2-angular-diagrams';
import { ChatWorkflowRulesData } from '../../models/appModel';
DataBindingService,
SnapConstraints} from '@syncfusion/ej2-angular-diagrams';
import { BranchDetail, ChatWorkflowRulesData, FieldOptionDetail } from '../../models/appModel';
import { DialogModule } from '@syncfusion/ej2-angular-popups';
import { BeforeOpenCloseMenuEventArgs} from '@syncfusion/ej2-angular-splitbuttons';
import { CommonModule } from '@angular/common';
Expand Down Expand Up @@ -78,7 +79,7 @@ export class WorkflowDiagramComponent implements AfterViewInit {
public headertitle = 'Block';
public animation: Object = { duration: 0};
public isParentListItem : boolean = false;

public optionValue!: string;

private nodeIdCounter: number = 0;
private connectorIdCounter: number = 0;
Expand Down Expand Up @@ -131,9 +132,8 @@ export class WorkflowDiagramComponent implements AfterViewInit {

// Configure snapSettings to hide grid lines
public snapSettings: SnapSettingsModel = {
horizontalGridlines: { lineColor: 'transparent', lineIntervals: [] },
verticalGridlines: { lineColor: 'transparent', lineIntervals: [] },
constraints: 0 // Disable all snapping
constraints: SnapConstraints.All,
gridType: 'Dots'
};

public selectedItems: SelectorModel = {
Expand Down Expand Up @@ -180,8 +180,15 @@ export class WorkflowDiagramComponent implements AfterViewInit {
if (args.actualObject instanceof Node) {
const clickedBlock = args.actualObject as Node;
let isLastNode = clickedBlock.outEdges.length == 0;
this.selectedBlockId = clickedBlock.id;
this.clickedNodeRuleId = (clickedBlock.data as ChatWorkflowRulesData).id;
this.selectedWorkFlowId = this.workflowID;
if(isLastNode && this.diagram.selectedItems.userHandles) {
this.diagram.selectedItems.userHandles[0].visible = true;
const index = this.diagram.nodes.findIndex(node => node.id === this.selectedBlockId);
let isBranchNode = (this.diagram.nodes[index].data as ChatWorkflowRulesData).chatWorkflowBlockId == 10;
if(!isBranchNode){
this.diagram.selectedItems.userHandles[0].visible = true;
}
this.diagram.selectedItems.userHandles[1].visible = true;
this.diagram.selectedItems.userHandles[2].visible = true;
}
Expand All @@ -190,14 +197,8 @@ export class WorkflowDiagramComponent implements AfterViewInit {
this.diagram.selectedItems.userHandles[1].visible = true;
this.diagram.selectedItems.userHandles[2].visible = false;
}
this.selectedBlockId = clickedBlock.id;
this.clickedNodeRuleId = (clickedBlock.data as ChatWorkflowRulesData).id;
this.selectedWorkFlowId = this.workflowID;
}
}

public getDiagramLength(): number{
return this.diagram.nodes.length;
}
}

// Need to refresh the diagram whenever a node is added or modified
Expand All @@ -206,7 +207,7 @@ export class WorkflowDiagramComponent implements AfterViewInit {
this.diagram.refresh();
}

// on node delete
// on rule node delete
public onDeleteNode(nodeObject) : void {
let ruleData : ChatWorkflowRulesData = nodeObject.data as ChatWorkflowRulesData;
const index = this.diagram.nodes.findIndex(node => (node.data as ChatWorkflowRulesData).successRuleId === ruleData.id);
Expand All @@ -220,6 +221,7 @@ export class WorkflowDiagramComponent implements AfterViewInit {
}
});
}

public onUserHandleMouseDown(event: UserHandleEventsArgs) {
if(event.element.name === 'addBlock') {
if(this.diagram.selectedItems.userHandles){
Expand Down Expand Up @@ -262,6 +264,27 @@ export class WorkflowDiagramComponent implements AfterViewInit {
}
}

public checkBranchAdd(branchInfo : BranchDetail[] | null, value: string ): boolean{
if(branchInfo != null){
for (const branch of branchInfo) {
if (branch.value === value && branch.successRuleId == null) {
return true;
}
}
}
return false;
}

public onClickAddBtn(option : FieldOptionDetail | null, index : string){
console.log(option + " \n" + index)
var addbtn=document.getElementById('addbtn' + index);
var addPos = addbtn.getBoundingClientRect();
this.optionValue = option.value;
this.contextmenu.open(addPos.top + window.scrollY, addPos.left+addPos.width +window.scrollX);
this.diagram.selectedItems.userHandles[1].visible = false;
this.diagram.selectedItems.userHandles[2].visible = false;
}

public onBeforeCloseContextMenu(args: BeforeOpenCloseMenuEventArgs) {
if(!this.isParentListItem && !((args.event.target as HTMLElement).closest(".e-menu-item")==null)) {
this.sidebarComponent?.sidebar?.show();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,27 @@
<button ejs-button type="button" iconCss='e-icons e-close' (click)="removeOption($index)"></button>
</div>
@if(editIndex==$index){
<div class="add-button-form" *ngTemplateOutlet="addButtonTemplate; context: { visibility: isVisible(nodeEditType) }"></div>
<div class="add-button-form" *ngTemplateOutlet="addButtonTemplate; context: { desc_visibility: isVisible(nodeEditType), value_visibility: isValueVisible(nodeBlockType)}"></div>
}
}
</ng-template>

<ng-template #addOptionTemplate let-isVisible="visibility">
<ng-template #addOptionTemplate let-isDescVisible="desc_visibility" let-isValueVisible="value_visibility">
<button ejs-button type="button" iconCss='e-icons e-plus' (click)="onAddOption()">Add Option</button>
@if(addOption){
<div class="add-button-form" *ngTemplateOutlet="addButtonTemplate; context: { visibility: isVisible }"></div>
<div class="add-button-form" *ngTemplateOutlet="addButtonTemplate; context: { desc_visibility: isDescVisible, value_visibility : isValueVisible }"></div>
}
</ng-template>

<ng-template #addButtonTemplate let-isVisible="visibility">
<ng-template #addButtonTemplate let-isDescVisible="desc_visibility" let-isValueVisible="value_visibility">
<div>
<input #optionLabel type="text" placeholder="Option Label" class="button-input" />
</div>
<div>
<input #optionValue type="text" placeholder="Option Value" class="button-input" />
<input #optionValue type="text" placeholder="Option Value" class="button-input" [style.display]="isValueVisible ? 'none' : 'block'"/>
</div>
<div>
<input #optionDescription type="text" placeholder="Option Description" class="button-input" [style.display]="isVisible ? 'block' : 'none'"/>
<input #optionDescription type="text" placeholder="Option Description" class="button-input" [style.display]="isDescVisible ? 'block' : 'none'"/>
</div>
<div>
<button ejs-button type="button" iconCss='e-icons e-check' (click)="addOrUpdateSaveOption(optionLabel.value, optionValue.value, isVisible ? optionDescription.value : null, optionLabel, optionValue, isVisible ? optionDescription : null)"></button>
Expand Down Expand Up @@ -101,7 +101,7 @@
<div>
<div *ngTemplateOutlet="sideBarPlaceholderTemplate"></div>
<div class="button-list" *ngTemplateOutlet="removeButtonTemplate"></div>
<div class="add-button-form" *ngTemplateOutlet="addOptionTemplate; context: { visibility: true }"></div>
<div class="add-button-form" *ngTemplateOutlet="addOptionTemplate; context: { desc_visibility: true , value_visibility: false}"></div>
</div>
}
}
Expand Down Expand Up @@ -173,6 +173,33 @@
<ejs-checkbox label="Get Customer Phone Number" [(ngModel)]="getPhoneNumberInfo" name="getPhoneNumberInfo"></ejs-checkbox>
</div>
}

@case(chatWorkflowBlockTypeEnum.BranchOnPickerInput){
@switch(nodeEditType){
@case(chatWorkflowEditorTypeEnum.ButtonsBranch){
<div>
<div class="button-list" *ngTemplateOutlet="removeButtonTemplate"></div>
<div class="add-button-form" *ngTemplateOutlet="addOptionTemplate; context: { desc_visibility: false, value_visibility: true }"></div>
</div>
}
@case(chatWorkflowEditorTypeEnum.DropdownBranch){
<div>
<div *ngTemplateOutlet="sideBarDescriptionTemplate"></div>
<div *ngTemplateOutlet="sideBarPlaceholderTemplate"></div>
<div class="button-list" *ngTemplateOutlet="removeButtonTemplate"></div>
<div class="add-button-form" *ngTemplateOutlet="addOptionTemplate; context: { desc_visibility: false, value_visibility: true }"></div>
</div>
}
@case(chatWorkflowEditorTypeEnum.ListBranch){
<div>
<div *ngTemplateOutlet="sideBarDescriptionTemplate"></div>
<div *ngTemplateOutlet="sideBarPlaceholderTemplate"></div>
<div class="button-list" *ngTemplateOutlet="removeButtonTemplate"></div>
<div class="add-button-form" *ngTemplateOutlet="addOptionTemplate; context: { desc_visibility: true, value_visibility: true }"></div>
</div>
}
}
}
}
</form>
</div>
Expand All @@ -185,4 +212,8 @@
}
<button ejs-button id="cancel" (click)="onCancelSideBarClick()" class="e-btn close-btn">Cancel</button>
</div>
</ejs-sidebar>
</ejs-sidebar>

<ejs-dialog id='dialog' #ejDialog [animationSettings]='animationSettings'
content='Are you sure you want to permanently delete all success rules?'
[visible]='false' [buttons]='buttons' [position]='position'>
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,10 @@
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}

#dialog {
align-items: center;
justify-content: center;
width: 300px;
}
Loading

0 comments on commit f0ecf03

Please sign in to comment.