mirror of
https://github.com/jwetzell/showbridge-webui.git
synced 2026-09-09 23:29:27 +00:00
add basic support for adding processors to routes
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
@if (processor() && schema()) {
|
||||||
|
<div class="flex items-start m-2 w-fit">
|
||||||
|
<div
|
||||||
|
class="flex flex-col bg-gray-800 border-2 {{
|
||||||
|
isInError() ? 'border-red-500' : 'border-gray-200'
|
||||||
|
}} border-solid w-fit h-full"
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-center bg-gray-600">
|
||||||
|
<div class="flex-grow ml-1 mr-3 text-gray-200">
|
||||||
|
{{ processor()?.type }}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-center" (click)="delete.emit()">
|
||||||
|
<mat-icon class="!text-red-500">close</mat-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if (hasParams()) {
|
||||||
|
<div>
|
||||||
|
<app-params-form
|
||||||
|
[paramsSchema]="schema()?.properties?.params"
|
||||||
|
[data]="params()"
|
||||||
|
(updated)="paramsUpdated($event)"
|
||||||
|
></app-params-form>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { Component, computed, inject, input, model, output, signal } from '@angular/core';
|
||||||
|
import { ProcessorConfiguration } from '../../models/config.models';
|
||||||
|
import { SchemaService } from '../../services/schema.service';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { ParamsFormComponent } from '../params-form/params-form.component';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-processor',
|
||||||
|
imports: [MatIconModule, ParamsFormComponent, ReactiveFormsModule],
|
||||||
|
templateUrl: './processor.component.html',
|
||||||
|
styleUrl: './processor.component.css',
|
||||||
|
})
|
||||||
|
export class ProcessorComponent {
|
||||||
|
path = input<string>('');
|
||||||
|
processor = model<ProcessorConfiguration>();
|
||||||
|
delete = output<void>();
|
||||||
|
|
||||||
|
params = computed(() => this.processor()!.params);
|
||||||
|
|
||||||
|
schema = computed(() => {
|
||||||
|
return this.processor()?.type
|
||||||
|
? this.schemaService.getSchemaForProcessorType(this.processor()!.type)
|
||||||
|
: undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
hasParams = computed(() => {
|
||||||
|
const schema = this.schema();
|
||||||
|
return (
|
||||||
|
schema !== undefined &&
|
||||||
|
schema.properties !== undefined &&
|
||||||
|
schema.properties.params !== undefined
|
||||||
|
);
|
||||||
|
});
|
||||||
|
private schemaService = inject(SchemaService);
|
||||||
|
|
||||||
|
paramsUpdated(params: any) {
|
||||||
|
this.processor.update((processor) => {
|
||||||
|
if (processor !== undefined) {
|
||||||
|
processor.params = params;
|
||||||
|
return {
|
||||||
|
...processor,
|
||||||
|
params: processor.params,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteMe() {
|
||||||
|
this.delete.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
isInError(): boolean {
|
||||||
|
const path = this.path();
|
||||||
|
if (path) {
|
||||||
|
return this.schemaService.errorPaths.includes(path);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
input::placeholder {
|
||||||
|
color: #d2d2d2;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
background-color: #424242;
|
||||||
|
}
|
||||||
|
|||||||
@@ -51,7 +51,56 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<div>
|
||||||
|
<div class="text-md text-gray-300 text-center">Processors</div>
|
||||||
|
<div class="border-2 border-gray-500 m-2 rounded-sm">
|
||||||
|
@if (processors() === undefined || processors()?.length === 0) {
|
||||||
|
<div class="w-full h-6"></div>
|
||||||
|
} @else {
|
||||||
|
@for (processor of processors(); track processor; let i = $index) {
|
||||||
|
<div cdkDrag>
|
||||||
|
<app-processor
|
||||||
|
[path]="path() + '/processors/' + i"
|
||||||
|
(processorChange)="processorUpdated(i, $event)"
|
||||||
|
[processor]="processor"
|
||||||
|
(delete)="deleteProcessor(i)"
|
||||||
|
></app-processor>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex mb-2">
|
||||||
|
@if (schemaService.moduleTypes.length > 0) {
|
||||||
|
<div
|
||||||
|
matTooltip="Add Module"
|
||||||
|
class="flex items-center justify-center w-full h-10 rounded-lg bg-gray-200 hover:cursor-pointer hover:bg-gray-300 m-2"
|
||||||
|
[matMenuTriggerFor]="addProcessorMenu"
|
||||||
|
>
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
</div>
|
||||||
|
<mat-menu #addProcessorMenu="matMenu">
|
||||||
|
@for (processorType of schemaService.processorTypes; track processorType) {
|
||||||
|
<button mat-menu-item (click)="addProcessor(processorType.type)">
|
||||||
|
<span>{{ processorType.type }}</span>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</mat-menu>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ng-template #addProcessorMenu>
|
||||||
|
@if (schemaService.processorTypes.length > 0) {
|
||||||
|
<div cdkMenu class="context-menu">
|
||||||
|
@for (processorType of schemaService.processorTypes; track processorType) {
|
||||||
|
<button cdkMenuItem class="context-menu-item" (click)="addProcessor(processorType.type)">
|
||||||
|
<span>{{ processorType.name }}</span>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</ng-template>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
import { Component, inject, input, model, output } from '@angular/core';
|
import { Component, computed, inject, input, model, output } from '@angular/core';
|
||||||
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { RouteConfiguration } from '../../models/config.models';
|
import { ProcessorConfiguration, RouteConfiguration } from '../../models/config.models';
|
||||||
import { SchemaService } from '../../services/schema.service';
|
import { SchemaService } from '../../services/schema.service';
|
||||||
import { JsonPipe } from '@angular/common';
|
import { JsonPipe } from '@angular/common';
|
||||||
|
import { ProcessorComponent } from '../processor/processor.component';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-route',
|
selector: 'app-route',
|
||||||
imports: [MatFormFieldModule, MatIconModule, ReactiveFormsModule, MatMenuModule, JsonPipe],
|
imports: [
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatIconModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
MatMenuModule,
|
||||||
|
JsonPipe,
|
||||||
|
ProcessorComponent,
|
||||||
|
],
|
||||||
templateUrl: './route.component.html',
|
templateUrl: './route.component.html',
|
||||||
styleUrl: './route.component.css',
|
styleUrl: './route.component.css',
|
||||||
})
|
})
|
||||||
@@ -19,12 +28,21 @@ export class RouteComponent {
|
|||||||
moduleIds = input<string[]>([]);
|
moduleIds = input<string[]>([]);
|
||||||
delete = output<void>();
|
delete = output<void>();
|
||||||
|
|
||||||
|
processors = computed(() => {
|
||||||
|
const route = this.route();
|
||||||
|
if (route) {
|
||||||
|
return route.processors;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
formGroup: FormGroup = new FormGroup({
|
formGroup: FormGroup = new FormGroup({
|
||||||
input: new FormControl('', [Validators.required]),
|
input: new FormControl('', [Validators.required]),
|
||||||
output: new FormControl('', [Validators.required]),
|
output: new FormControl('', [Validators.required]),
|
||||||
});
|
});
|
||||||
|
|
||||||
private schemaService = inject(SchemaService);
|
public schemaService = inject(SchemaService);
|
||||||
|
private snackBar = inject(MatSnackBar);
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.formGroup.patchValue({
|
this.formGroup.patchValue({
|
||||||
@@ -55,4 +73,53 @@ export class RouteComponent {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addProcessor(processorType: string) {
|
||||||
|
const processorTemplate = this.schemaService.getSkeletonForProcessor(processorType);
|
||||||
|
this.route.update((route) => {
|
||||||
|
if (route) {
|
||||||
|
if (!route.processors) {
|
||||||
|
route.processors = [];
|
||||||
|
}
|
||||||
|
route.processors?.push(processorTemplate);
|
||||||
|
return {
|
||||||
|
...route,
|
||||||
|
processors: route.processors,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return route;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
processorUpdated(index: number, processor: ProcessorConfiguration | undefined) {
|
||||||
|
if (processor === undefined) {
|
||||||
|
console.error('processor is undefined, not updating');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.route.update((route) => {
|
||||||
|
if (route && route.processors) {
|
||||||
|
return {
|
||||||
|
...route,
|
||||||
|
processors: route.processors,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return route;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteProcessor(index: number) {
|
||||||
|
this.route.update((route) => {
|
||||||
|
if (route && route.processors) {
|
||||||
|
route?.processors?.splice(index, 1);
|
||||||
|
return {
|
||||||
|
...route,
|
||||||
|
processors: route.processors,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return route;
|
||||||
|
});
|
||||||
|
this.snackBar.open('Processor Removed', 'Dismiss', {
|
||||||
|
duration: 3000,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user