Skip to content

Commit

Permalink
Merge pull request #14 from SyncfusionExamples/405222-IntegrateAPI
Browse files Browse the repository at this point in the history
feature(405222): integrate Get api changes
  • Loading branch information
NavinVinayagam authored Dec 23, 2024
2 parents 151a4ee + 8cdee83 commit 017c669
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 101 deletions.
3 changes: 3 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,8 @@
}
}
}
},
"cli": {
"analytics": false
}
}
2 changes: 1 addition & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<app-workflow-diagram></app-workflow-diagram>
<app-workflow-diagram [workflowID]="workflowID" ></app-workflow-diagram>
1 change: 1 addition & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ import { WorkflowDiagramComponent } from './components/workflow-diagram/workflow
})

export class AppComponent {
public workflowID: number = 7;
}
43 changes: 17 additions & 26 deletions src/app/components/workflow-diagram/workflow-diagram.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
id="diagram" [width]="'100%'" [height]="649" [nodes]="nodes"
[connectors]="connectors" [layout]="layout" [getNodeDefaults]="getNodeDefaults"
[getConnectorDefaults]="getConnectorDefaults" (created)="onDiagramCreated()" [selectedItems]="selectedItems"
(onUserHandleMouseDown)="onUserHandleMouseDown($event)" (click)="onNodeClick($event)" [snapSettings]="snapSettings">
(onUserHandleMouseDown)="onUserHandleMouseDown($event)" (click)="onNodeClick($event)" [snapSettings]="snapSettings" [dataSourceSettings]='dataSourceSettings'>

<ng-template #userHandleTemplate let-data>
<div class="dropDown-container">
Expand All @@ -38,10 +38,10 @@
</ng-template>

<ng-template #nodeTemplate let-data>
<div><label style="padding: 5px;">{{ data.addInfo.fieldDetails.label }}</label></div>
@switch (data.addInfo.chatWorkflowBlockId){
<div><label style="padding: 5px;">{{ data.data.fieldDetails.label }}</label></div>
@switch (data.data.chatWorkflowBlockId){
@case(chatWorkflowBlockTypeEnum.GetPickerInput){
@switch (data.addInfo.chatWorkflowEditorTypeId){
@switch (data.data.chatWorkflowEditorTypeId){
@case (chatWorkflowEditorTypeEnum.Boolean){
<ng-container>
<div><button type="button" ejs-button style="width: 85%;" class="e-btn e-success">Yes</button></div>
Expand All @@ -50,75 +50,66 @@
}
@case (chatWorkflowEditorTypeEnum.Buttons){
<ng-container>
@for(option of data.addInfo.fieldOptionDetails; track $index){
@for(option of data.data.fieldOptionDetails; track $index){
<button ejs-button cssClass="e-primary" style="width: 85%;">{{option.label}}</button>
}
</ng-container>
}
@case (chatWorkflowEditorTypeEnum.DropDown){
<ng-container>
<ejs-dropdownlist [dataSource]="data.addInfo.fieldOptionDetails" [fields]="ddlFields"
[placeholder]="data.addInfo.fieldDetails.placeholder" cssClass="e-primary" width="85%">
<ejs-dropdownlist [dataSource]="data.data.fieldOptionDetails" [fields]="ddlFields"
[placeholder]="data.data.fieldDetails.placeholder" cssClass="e-primary" width="85%">
</ejs-dropdownlist>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.MultiSelect){
<ng-container >
<ejs-multiselect [dataSource]="data.addInfo.fieldOptionDetails" [fields]="ddlFields"
[placeholder]="data.addInfo.fieldDetails.placeholder"
[maximumSelectionLength]="data.addInfo.fieldDetails.fieldValidation.max" cssClass="e-primary" width="85%">
<ejs-multiselect [dataSource]="data.data.fieldOptionDetails" [fields]="ddlFields" [placeholder]="data.data.fieldDetails.placeholder" cssClass="e-primary" width="85%">
</ejs-multiselect>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.List){
<ng-container>
<ejs-listview id='sample-list' [dataSource]='data.addInfo.fieldOptionDetails'
[fields]='ddlFields'></ejs-listview>
<ejs-listview id='sample-list' [dataSource]='data.data.fieldOptionDetails' [fields]='ddlFields'></ejs-listview>
</ng-container>
}
}
}
@case(chatWorkflowBlockTypeEnum.GetTextInput){
@switch (data.addInfo.chatWorkflowEditorTypeId){
@switch (data.data.chatWorkflowEditorTypeId){
@case(chatWorkflowEditorTypeEnum.Text){
<ng-container>
<ejs-textbox [placeholder]="data.addInfo.fieldDetails.placeholder" readonly="true"></ejs-textbox>
<ejs-textbox [placeholder]="data.data.fieldDetails.placeholder" readonly="true"></ejs-textbox>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.TextArea){
<ng-container>
<ejs-textarea [placeholder]="data.addInfo.fieldDetails.placeholder" readonly="true"
[maxLength]="data.addInfo.fieldDetails.fieldValidation.max"></ejs-textarea>
<ejs-textarea [placeholder]="data.data.fieldDetails.placeholder" readonly="true"></ejs-textarea>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.Date){
<ng-container>
<ejs-datepicker [placeholder]="data.addInfo.fieldDetails.placeholder" [readonly]="true"></ejs-datepicker>
<ejs-datepicker [placeholder]="data.data.fieldDetails.placeholder" [readonly]="true"></ejs-datepicker>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.DateTime){
<ng-container>
<ejs-datetimepicker [placeholder]="data.addInfo.fieldDetails.placeholder"
[readonly]="true"></ejs-datetimepicker>
<ejs-datetimepicker [placeholder]="data.data.fieldDetails.placeholder" [readonly]="true"></ejs-datetimepicker>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.Number){
<ng-container>
<ejs-numerictextbox format='n0' [min]="'data.addInfo.fieldDetails.fieldValidation.min'"
[max]="'data.addInfo.fieldDetails.fieldValidation.max'" [placeholder]="data.addInfo.fieldDetails.placeholder"
readonly="true" floatLabelType='Auto'></ejs-numerictextbox>
<ejs-numerictextbox format='n0' [placeholder]="data.data.fieldDetails.placeholder" readonly="true"></ejs-numerictextbox>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.Decimal){
<ng-container>
<ejs-numerictextbox [min]="'data.addInfo.fieldDetails.fieldValidation.min'"
[max]="'data.addInfo.fieldDetails.fieldValidation.max'" [placeholder]="data.addInfo.fieldDetails.placeholder"
readonly="true" floatLabelType='Auto'></ejs-numerictextbox>
<ejs-numerictextbox [placeholder]="data.data.fieldDetails.placeholder" readonly="true"></ejs-numerictextbox>
</ng-container>
}
@case(chatWorkflowEditorTypeEnum.Regex){
<ng-container>
<ejs-textbox [placeholder]="data.addInfo.fieldDetails.placeholder" readonly="true"></ejs-textbox>
<ejs-textbox [placeholder]="data.data.fieldDetails.placeholder" readonly="true"></ejs-textbox>
</ng-container>
}
}
Expand Down
119 changes: 47 additions & 72 deletions src/app/components/workflow-diagram/workflow-diagram.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, Output, viewChild, ViewChild } from '@angular/core';
import { ComplexHierarchicalTree, ConnectionPointOrigin, ConnectorConstraints, ConnectorModel, DecoratorModel, Diagram, DiagramComponent, DiagramModule, HierarchicalTree, HierarchicalTreeService, HtmlModel, IClickEventArgs, IExportOptions, LayoutModel, LineDistribution, Node, NodeModel, PrintAndExport, SelectorConstraints, SelectorModel, SnapSettingsModel, TextModel, UserHandleEventsArgs, UserHandleModel } from '@syncfusion/ej2-angular-diagrams';
import { FieldDetails, FieldOptionDetail, FieldValidation, MessageDetails, RuleData, RuleData2 } from '../../models/appModel';
import { ComplexHierarchicalTree, ConnectionPointOrigin, ConnectorConstraints, ConnectorModel, DecoratorModel, Diagram, DiagramComponent, DiagramModule,
HierarchicalTree, HierarchicalTreeService, HtmlModel, IClickEventArgs, IExportOptions, LayoutModel, LineDistribution, Node, NodeModel, PrintAndExport,
SelectorConstraints, SelectorModel, SnapSettingsModel, TextModel, UserHandleEventsArgs, UserHandleModel, DataSourceModel,
DataBindingService} from '@syncfusion/ej2-angular-diagrams';
import { ChatWorkflowRulesData, FieldDetails, FieldOptionDetail, FieldValidation, MessageDetails, RuleData2 } from '../../models/appModel';
import { RULE_DATA, RULE_DATA2, RULE_DATA3 } from '../../data/rule-data';
import { DialogModule } from '@syncfusion/ej2-angular-popups';
import { BeforeOpenCloseMenuEventArgs, DropDownButtonComponent, DropDownButtonModule, ItemModel, OpenCloseMenuEventArgs } from '@syncfusion/ej2-angular-splitbuttons';
Expand All @@ -18,25 +21,28 @@ import { ButtonModule, SwitchModule } from '@syncfusion/ej2-angular-buttons';
import sampleWorkflowData from '../../data/sample-workflow-data.json'; // Adjust the path as needed
import { AsyncSettingsModel, FileInfo, Uploader } from '@syncfusion/ej2-inputs';
import { WorkflowSidebarComponent } from '../workflow-sidebar/workflow-sidebar.component'; // Import child component
import { Adaptor, DataManager, WebApiAdaptor } from '@syncfusion/ej2-data';


Diagram.Inject(HierarchicalTree, LineDistribution, PrintAndExport);

@Component({
selector: 'app-workflow-diagram',
standalone: true,
providers: [HierarchicalTreeService],
providers: [HierarchicalTreeService, DataBindingService],
imports: [DiagramModule, DialogModule, DropDownButtonModule, ButtonModule, CommonModule, ListViewModule, DropDownListModule, MultiSelectModule, NumericTextBoxModule, TextBoxModule, TextAreaModule, DatePickerModule, DateTimePickerModule, SwitchModule, ToolbarModule, UploaderModule, WorkflowSidebarComponent],
templateUrl: './workflow-diagram.component.html',
styleUrl: './workflow-diagram.component.scss'
})
export class WorkflowDiagramComponent implements AfterViewInit{
export class WorkflowDiagramComponent implements AfterViewInit {
@ViewChild('diagram') diagram!: DiagramComponent;
@ViewChild('dropdownbutton') dropdownbutton!: DropDownButtonComponent;
@ViewChild('listview') listView!: ListViewComponent;
@ViewChild('workflowSidebar') sidebarComponent!: WorkflowSidebarComponent;
@ViewChild('fileInput', { static: false }) fileInput!: ElementRef;

@Input() workflowID!: number | null;

public chatWorkflowEditorTypeEnum = ChatWorkflowEditorTypeEnum;
public chatWorkflowBlockTypeEnum = ChatWorkflowBlockTypeEnum;
// public data: RuleData[] = RULE_DATA;
Expand Down Expand Up @@ -84,79 +90,49 @@ export class WorkflowDiagramComponent implements AfterViewInit{
private nodeIdCounter: number = 0;
private connectorIdCounter: number = 0;
public newNodeData: RuleData2[] = [];
textFormatDDLOptions: Array<{ text: string, value: number }>;
ddlTextFormatFields: Object = { text: 'text', value: 'value' };

public sidebarHeader!: string;
public nodeBlockType!: number;
public nodeEditType!: number;
public selectedBlockId!: string;
public selectedWorkFlowId!: number;

public dataSourceSettings!: DataSourceModel;

constructor() {
// Initialize nodes and connectors based on the data
this.initializeDiagramElements();
this.textFormatDDLOptions = this.enumToArray(TextFormatEnum);
}

ngAfterViewInit() {
ngOnInit() {

let baseUrl = 'https://localhost:44303/chatwidget-api/v1/workflow-designer/'+ this.workflowID+'/rules';

this.dataSourceSettings = {
id: 'id', parentId: 'parentRuleId',
dataManager: new DataManager (
{
url: baseUrl,
crossDomain: true
},
),
//binds the external data with node
doBinding: (nodeModel: NodeModel, data: ChatWorkflowRulesData, diagram: Diagram) => {
let buttonCount = 0;
if(data.chatWorkflowEditorTypeId == 2) {
buttonCount = data.fieldOptionDetails?.length || 0;
}
nodeModel.id= `node${data.id}`;
nodeModel.width= 200;
nodeModel.height= 150 + (buttonCount * 25);
}
};
}

// Convert enum to array of objects
private enumToArray(enumObj: any): Array<{ text: string, value: number }> {
return Object.keys(enumObj)
.filter(key => isNaN(Number(key)))
.map(key => {
return {
text: key,
value: enumObj[key as keyof typeof enumObj]
}
});
}

private initializeDiagramElements(): void {
this.selectedWorkFlowId = 1; // Get from DB
sampleWorkflowData.forEach(item => {
let buttonCount = 0;
if(item.chatWorkflowEditorTypeId == 2){
buttonCount = item.fieldOptionDetails?.length || 0;
}
// Create nodes based on the data
this.nodes.push({
id: `node${item.id}`,
// annotations: [{ content: `node${item['id']}` }],
width: 200,
height: 150 + (buttonCount * 25),
addInfo: item
});

// Create connectors from success_rule_id
if (item['successRuleId']) {
this.connectors.push({
id: `connector${item['id']}-s${item['successRuleId']}`,
sourceID: `node${item['id']}`,
targetID: `node${item['successRuleId']}`,
// annotations: [{ content: 'success', alignment: 'Center'}]
});
}
// if (item.branchDetails) {
// item.branchDetails.forEach(branch: any => {
// if (branch.successRuleId) {
// this.connectors.push({
// id: `connector${item.id}-s${branch.successRuleId}`,
// sourceID: `node${item.id}`,
// targetID: `node${branch.successRuleId}`,
// annotations: [{ content: 'success', alignment: 'Center' }]
// });
// }
// });
// }
});
ngAfterViewInit() {

}

public onDiagramCreated(): void {
(this.diagram as DiagramComponent).fitToPage();
};
}

// Configure snapSettings to hide grid lines
public snapSettings: SnapSettingsModel = {
Expand All @@ -175,9 +151,9 @@ export class WorkflowDiagramComponent implements AfterViewInit{
connectionPointOrigin: ConnectionPointOrigin.DifferentPoint,
horizontalSpacing: 40,
verticalSpacing: 40,
horizontalAlignment: 'Left',
verticalAlignment: 'Top',
margin: { left: 0, right: 0, top: 0, bottom: 0 },
horizontalAlignment: 'Center',
verticalAlignment: 'Center',
margin: { left: 0, right: 0, top: 50, bottom: 0 },
orientation: 'TopToBottom',
};

Expand Down Expand Up @@ -232,7 +208,7 @@ export class WorkflowDiagramComponent implements AfterViewInit{
// Add the new node to the diagram
this.diagram.addNode(newNode);
const index = this.diagram.nodes.findIndex(node => node.id === sourceNodeId);
(this.diagram.nodes[index].addInfo as RuleData2).successRuleId = (newNode.addInfo as RuleData2).id;
(this.diagram.nodes[index].data as RuleData2).successRuleId = (newNode.data as RuleData2).id;
// Create a new connector to link the new node to the source node
const newConnectorId = `connector${++this.connectorIdCounter}`;
const newConnector: ConnectorModel = {
Expand All @@ -249,10 +225,9 @@ export class WorkflowDiagramComponent implements AfterViewInit{

public onUpdateNode([sourceNodeId, newNode]: [string, RuleData2]) : void {
const index = this.diagram.nodes.findIndex(node => node.id === sourceNodeId);
newNode.id = (this.diagram.nodes[index].addInfo as RuleData2).id;
this.diagram.nodes[index].addInfo = newNode;
newNode.id = (this.diagram.nodes[index].data as RuleData2).id;
this.diagram.nodes[index].data = newNode;
this.diagram.refresh();
this.diagram.fitToPage();
}

public onUserHandleMouseDown(event: UserHandleEventsArgs) {
Expand All @@ -279,9 +254,9 @@ export class WorkflowDiagramComponent implements AfterViewInit{
this.diagram.selectedItems.userHandles[2].visible = false;
}
let nodeObject = this.diagram.getNodeObject(this.selectedBlockId);
let id = (nodeObject.addInfo as RuleData2).id;
const index = this.diagram.nodes.findIndex(node => (node.addInfo as RuleData2).successRuleId === id);
(this.diagram.nodes[index].addInfo as RuleData2).successRuleId = null;
let id = (nodeObject.data as RuleData2).id;
const index = this.diagram.nodes.findIndex(node => (node.data as RuleData2).successRuleId === id);
(this.diagram.nodes[index].data as RuleData2).successRuleId = null;
this.diagram.remove(nodeObject);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export class WorkflowSidebarComponent {
// Set the node(block) values
setBlockValues(nodeInfo: NodeModel) {
this.isEdit = true;
let nodeDetails = nodeInfo.addInfo as RuleData2;
let nodeDetails = nodeInfo.data as RuleData2;
this.soureId = nodeInfo?.id ?? "";
this.nodeBlockType = nodeDetails.chatWorkflowBlockId;
this.nodeEditType = nodeDetails.chatWorkflowEditorTypeId ?? 0;
Expand Down Expand Up @@ -351,7 +351,7 @@ export class WorkflowSidebarComponent {
shape: {
type: 'HTML',
},
addInfo: nodeInfo
data: nodeInfo
};
}

Expand Down
14 changes: 14 additions & 0 deletions src/app/models/appModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,18 @@ export interface RuleData2 {
branchDetails?: BranchDetail[] | null;
messageDetails?: MessageDetails | null;
fieldOptionDetails?: FieldOptionDetail[] | null;
}

// Define the main Workflow interface
export interface ChatWorkflowRulesData {
id: number;
successWorkflowId?: number | null;
successRuleId?: number | null;
chatWorkflowBlockId: number;
chatWorkflowEditorTypeId?: number | null;
fieldDetails?: FieldDetails | null;
branchDetails?: BranchDetail[] | null;
messageDetails?: MessageDetails | null;
fieldOptionDetails?: FieldOptionDetail[] | null;
parentId?: number | null;
}

0 comments on commit 017c669

Please sign in to comment.