retejs / rete

JavaScript framework for visual programming
https://retejs.org
MIT License
10.17k stars 653 forks source link

Custom Input Control ui not loading #687

Closed simonetassi closed 9 months ago

simonetassi commented 9 months ago

I am trying to add a DropDownInputControl to one of my nodes but it doesn't load and the node is shown without any input. This is my code:

// custom-dropdown.component.ts
import { Component, Input } from '@angular/core';
import { ClassicPreset } from 'rete';

export class CustomDropdownControl extends ClassicPreset.Control {
  constructor(public enumValues: string[]) {
    super();
  }

  trackFn(index: number, item: string): string {
    return item; // or return a unique identifier if available
  }
}

@Component({
  selector: 'app-custom-dropdown',
  templateUrl: './custom-dropdown.component.html',
  styleUrls: ['./custom-dropdown.component.css']
})
export class CustomDropdownComponent {
  @Input() data!: CustomDropdownControl;
}
\\ custom-dropdown.component.html
<mat-form-field>
    <mat-label>enum</mat-label>
    <select matNativeControl required>
        <option *ngFor="let e of data.enumValues; trackBy: data.trackFn" [value]="e">{{e}}</option>
    </select>
</mat-form-field>
// action-node.class.ts
import { ClassicPreset as Classic } from "rete";
import { CustomDropdownComponent, CustomDropdownControl } from "src/app/custom-dropdown/custom-dropdown.component";

const socket = new Classic.Socket('socket');
export class ActionNode extends Classic.Node {
    width = 180;
    height = 120;
    thingId: string;
    name: string;
    constructor(name: string, thingId: string) {
        super(name);
        this.name = name;
        this.thingId = thingId;
        this.addInput('in', new Classic.Input(socket));
        this.addOutput('value', new Classic.Output(socket));
        this.addControl('enum', new CustomDropdownControl(["one", "two", "three"]));
        return this;
    }
}

If instead of CustomDropDownControl I add a simple InputControl in my button, it is shown properly.

Any help is appreciated! Thanks!

simonetassi commented 9 months ago

I was't customizing the preset setup correctly. This is how it should be done:

...
angularRender.addPreset(
    AngularPresets.classic.setup({
      customize: {
        control(data) {
          if (data.payload instanceof CustomDropdownControl) {
            return CustomDropdownComponent;
          }
          return ControlComponent;
        }
      },
    })
  );
...

For a more complete example you can look at the https://retejs.org/examples/controls/angular example.

I think this issue can be considered closed!