-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Experimental refactor of BlocksWorkflowComponent to dynamically load …
…block components
- Loading branch information
1 parent
30756a3
commit 4a516a0
Showing
2 changed files
with
62 additions
and
119 deletions.
There are no files selected for viewing
64 changes: 2 additions & 62 deletions
64
src/app/components/blocks-workflow/blocks-workflow.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,2 @@ | ||
<ng-container *ngFor="let block of blocks; let i = index"> | ||
<ng-container [ngSwitch]="block.type"> | ||
<app-form-block class="block-wrapper" *ngSwitchCase="'form'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-form-block> | ||
<app-debug-block class="block-wrapper" *ngSwitchCase="'debug'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-debug-block> | ||
<app-query-block class="block-wrapper" *ngSwitchCase="'query'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-query-block> | ||
<app-mapping-block class="block-wrapper" *ngSwitchCase="'mapping'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-mapping-block> | ||
<app-grid-block class="block-wrapper" *ngSwitchCase="'grid'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-grid-block> | ||
<app-http-block class="block-wrapper" *ngSwitchCase="'http'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-http-block> | ||
<app-chart-block class="block-wrapper" *ngSwitchCase="'chart'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-chart-block> | ||
<app-init-block class="block-wrapper" *ngSwitchCase="'init'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-init-block> | ||
<app-message-block class="block-wrapper" *ngSwitchCase="'message'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-message-block> | ||
<app-image-block class="block-wrapper" *ngSwitchCase="'image'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-image-block> | ||
<app-vimeo-block class="block-wrapper" *ngSwitchCase="'vimeoPlayer'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-vimeo-block> | ||
<app-template-block class="block-wrapper" *ngSwitchCase="'template'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-template-block> | ||
<app-button-block class="block-wrapper" *ngSwitchCase="'button'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-button-block> | ||
<app-dialog-block class="block-wrapper" *ngSwitchCase="'dialog'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-dialog-block> | ||
<app-actions-block class="block-wrapper" *ngSwitchCase="'actions'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-actions-block> | ||
<app-variable-get class="block-wrapper" *ngSwitchCase="'variable-get'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-variable-get> | ||
<app-variable-set class="block-wrapper" *ngSwitchCase="'variable-set'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-variable-set> | ||
<app-switch-block class="block-wrapper" *ngSwitchCase="'switch'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-switch-block> | ||
<app-batch-block class="block-wrapper" *ngSwitchCase="'batch'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-batch-block> | ||
<app-multi-block class="block-wrapper" *ngSwitchCase="'multi'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-multi-block> | ||
<app-event-dispatch-block class="block-wrapper" *ngSwitchCase="'dispatch'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-event-dispatch-block> | ||
<app-csv-import-block class="block-wrapper" *ngSwitchCase="'csv-import'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-csv-import-block> | ||
<app-csv-export-block class="block-wrapper" *ngSwitchCase="'csv-export'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-csv-export-block> | ||
<app-card-block class="block-wrapper" *ngSwitchCase="'card'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-card-block> | ||
<app-faker-block class="block-wrapper" *ngSwitchCase="'faker'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-faker-block> | ||
<app-data-import-block class="block-wrapper" *ngSwitchCase="'import'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-data-import-block> | ||
<app-data-export-block class="block-wrapper" *ngSwitchCase="'export'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-data-export-block> | ||
<app-file-input-block class="block-wrapper" *ngSwitchCase="'file-input'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-file-input-block> | ||
<app-parse-data-block class="block-wrapper" *ngSwitchCase="'parse-data'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-parse-data-block> | ||
<app-file-export-block class="block-wrapper" *ngSwitchCase="'file-export'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-file-export-block> | ||
<app-serialize-data-block class="block-wrapper" *ngSwitchCase="'serialize'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-serialize-data-block> | ||
<app-launch-block class="block-wrapper" *ngSwitchCase="'launch'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-launch-block> | ||
<app-db-block class="block-wrapper" *ngSwitchCase="'db'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-db-block> | ||
<app-reference-block class="block-wrapper" *ngSwitchCase="'reference'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-reference-block> | ||
<app-context-block class="block-wrapper" *ngSwitchCase="'context'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-context-block> | ||
<app-auth0-profile-data-block class="block-wrapper" *ngSwitchCase="'auth0'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-auth0-profile-data-block> | ||
<app-adapter-list-block class="block-wrapper" *ngSwitchCase="'adapter-list'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-adapter-list-block> | ||
<app-adapter-info-block class="block-wrapper" *ngSwitchCase="'adapter-info'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-adapter-info-block> | ||
<app-read-file-block class="block-wrapper" *ngSwitchCase="'read-file'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-read-file-block> | ||
<app-context-save-block class="block-wrapper" *ngSwitchCase="'context-save'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-context-save-block> | ||
<app-video-upload-block class="block-wrapper" *ngSwitchCase="'video-upload'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-video-upload-block> | ||
<app-gosub-block class="block-wrapper" *ngSwitchCase="'gosub'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-gosub-block> | ||
<app-gsheet-block class="block-wrapper" *ngSwitchCase="'gsheet'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-gsheet-block> | ||
<app-map-block class="block-wrapper" *ngSwitchCase="'map'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-map-block> | ||
<app-graphql-block class="block-wrapper" *ngSwitchCase="'graphql'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-graphql-block> | ||
<app-validator-block class="block-wrapper" *ngSwitchCase="'validator'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-validator-block> | ||
<app-load-auth-block class="block-wrapper" *ngSwitchCase="'load-auth'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-load-auth-block> | ||
<app-xlsx-template-block class="block-wrapper" *ngSwitchCase="'xlsx-template'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-xlsx-template-block> | ||
<app-validate-block class="block-wrapper" *ngSwitchCase="'validate'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-validate-block> | ||
<app-audio-player-block class="block-wrapper" *ngSwitchCase="'player'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-audio-player-block> | ||
<app-web-money-block class="block-wrapper" *ngSwitchCase="'web-money'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-web-money-block> | ||
<app-wallet-block class="block-wrapper" *ngSwitchCase="'wallet'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-wallet-block> | ||
<app-load-schema-block class="block-wrapper" *ngSwitchCase="'load-schema'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-load-schema-block> | ||
<app-app-layout-block class="block-wrapper" *ngSwitchCase="'app-layout'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-app-layout-block> | ||
<app-rename-fields-block class="block-wrapper" *ngSwitchCase="'rename-fields'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-rename-fields-block> | ||
<app-mermaid-block class="block-wrapper" *ngSwitchCase="'mermaid'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-mermaid-block> | ||
<app-comparison class="block-wrapper" *ngSwitchCase="'comparison'" [context]="context" [config]="block" [model]="models[i]" (output)="updateModel(i + 1, $event)"></app-comparison> | ||
</ng-container> | ||
</ng-container> | ||
<!-- <pre>workblock: {{ context | json }}</pre> --> | ||
<!-- blocks-workflow.component.html --> | ||
<ng-container #blockHost></ng-container> |
117 changes: 60 additions & 57 deletions
117
src/app/components/blocks-workflow/blocks-workflow.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,82 @@ | ||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; | ||
import {clone} from 'lodash-es'; | ||
import { Component, OnInit, ViewChild, ViewContainerRef, ComponentFactoryResolver, Input, Output, EventEmitter, OnChanges } from '@angular/core'; | ||
|
||
import { FormBlockComponent } from 'src/app/blocks/form-block/form-block.component'; | ||
import { DebugBlockComponent } from 'src/app/blocks/debug-block/debug-block.component'; | ||
import { QueryBlockComponent } from 'src/app/blocks/query-block/query-block.component'; | ||
// Add other imports for other block components here | ||
|
||
// Simple interface to describe the expected structure of dynamically loaded block components | ||
interface DynamicBlockComponent { | ||
output?: EventEmitter<any>; | ||
// TODO: Add other common properties and methods here | ||
} | ||
|
||
// Mapping from block types to component classes | ||
const blockComponentMapping = { | ||
'form': FormBlockComponent, | ||
'debug': DebugBlockComponent, | ||
'query': QueryBlockComponent, | ||
// TODO: Add other block types here | ||
}; | ||
|
||
@Component({ | ||
selector: 'app-blocks-workflow', | ||
templateUrl: './blocks-workflow.component.html', | ||
styleUrls: ['./blocks-workflow.component.scss'] | ||
styleUrls: ['./blocks-workflow.component.scss'], | ||
}) | ||
export class BlocksWorkflowComponent implements OnInit { | ||
export class BlocksWorkflowComponent implements OnInit, OnChanges { | ||
@ViewChild('blockHost', { read: ViewContainerRef }) blockHost: ViewContainerRef; | ||
|
||
@Input() blocks = []; | ||
@Input() models = []; | ||
@Input() context = {}; | ||
|
||
@Output() workflowComplete = new EventEmitter(); | ||
// TODO: Use output events to emit data so that if this component is used in a parent component, the parent component can listen to the output events and get the data from the blocks | ||
|
||
constructor() { } | ||
constructor(private componentFactoryResolver: ComponentFactoryResolver) { } | ||
|
||
ngOnInit() { | ||
// Logging the blocks array for debugging purposes | ||
console.log('BlocksWorkflowComponent init blocks:', this.blocks); | ||
this.loadBlocks(); | ||
// let's log the blocks, models and context to see if they are being passed correctly | ||
console.log('blocks:',this.blocks); | ||
console.log('models:',this.models); | ||
console.log('context:',this.context); | ||
} | ||
|
||
/** | ||
* 🚨 AI generated documentation, TO BE VERIFIED: | ||
* | ||
* Purpose: Update the model state within the BlocksWorkflowComponent, | ||
* essential for maintaining the application's current state as it processes various blocks. | ||
* | ||
* Parameters: | ||
* - modelNumber (type: number): Index of the model to be updated (zero-based). | ||
* - value (type: any): New value for the model at the specified index (modelNumber). | ||
* | ||
* Functionality: | ||
* 1. Update Models Array: Creates a new array with updated model values using spread operator. | ||
* - this.models.slice(0, modelNumber) creates a shallow copy up to the index modelNumber. | ||
* - Adds 'value' at position modelNumber. | ||
* - Adds the rest of the array elements after modelNumber. | ||
* 2. Force Change Detection: Reassigns this.blocks to force Angular change detection. | ||
* 3. Emit Workflow Completion: Emits workflowComplete event if updating process reaches final block. | ||
*/ | ||
updateModel(modelNumber, value) { | ||
// Logging the model index and new value for debugging purposes | ||
console.log('BlocksWorkflowComponent updating modelNumber with value:', { modelNumber, value }); | ||
console.log('BlocksWorkflowComponent models:', this.models); | ||
|
||
// Update the specified model in the models array: | ||
// 1. Keep all models up to the specified index (modelNumber) unchanged. | ||
// 2. Replace the model at the specified index (modelNumber) with the new value. | ||
// 3. Retain all models after the specified index (modelNumber). | ||
this.models = [ | ||
...this.models.slice(0, modelNumber), // Copy elements before modelNumber | ||
value, // Insert the new value | ||
...this.models.slice(modelNumber + 1) // Copy elements after modelNumber | ||
]; | ||
|
||
// Force a change detection cycle in Angular by creating a new reference for the blocks array. | ||
// This is necessary as Angular may not detect changes to the contents of an array. | ||
this.blocks = [...this.blocks]; | ||
|
||
// Check if the current model update is for the final block in the workflow. | ||
// If it is the final block, emit an event to signify the completion of the workflow. | ||
if (modelNumber >= this.blocks.length) { | ||
console.log('Emitting workflowComplete with value:', value); | ||
this.workflowComplete.emit(value); // Emit workflow completion event | ||
|
||
ngOnChanges(changes) { | ||
if (changes.blocks || changes.models || changes.context) { | ||
this.loadBlocks(); | ||
} | ||
} | ||
loadBlocks(this) { | ||
console.log('loadBlocks is running with blocks:',this.blocks); | ||
window['data'] = {"blocks": this.blocks, "models": this.models, "context":this.context}; | ||
this.blocks.forEach((block, index) => { | ||
console.log('loadBlocks block:',block, 'index',index); | ||
const blockComponent = blockComponentMapping[block.type]; | ||
if (blockComponent) { | ||
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(blockComponent); | ||
const componentRef = this.blockHost.createComponent(componentFactory); | ||
console.log('loadBlocks blockComponent:',blockComponent, componentRef); | ||
|
||
// Assign inputs to the component instance, adjust according to your block component's inputs | ||
if (block.config) { | ||
Object.assign(componentRef.instance, block.config); | ||
} | ||
|
||
// This function seems to be no longer used! | ||
// src/app/blocks/actions-block/actions-block.component.ts does a similar thing though | ||
// TODO: Verify that runWorkflow is no longer used and remove it | ||
// Use type assertion with the DynamicBlockComponent interface so that TypeScript knows the type of the component instance | ||
const instance = componentRef.instance as DynamicBlockComponent; | ||
|
||
runWorkflow() { | ||
if (this.models.length > 0) { | ||
this.models[0] = clone(this.models[0]); | ||
} | ||
console.log(`Loading block: ${block.type}`, { config: block.config }); | ||
|
||
// Subscribe to the output EventEmitter if it exists | ||
instance.output?.subscribe(output => { | ||
console.log(`Output from block: ${block.type}`, output); | ||
}); | ||
} else { | ||
console.log(`No component mapped for type: ${block.type}`); | ||
} | ||
}); | ||
} | ||
} |