mirror of
https://github.com/jwetzell/showbridge-webui.git
synced 2026-08-20 05:28:59 +00:00
relayout folders
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
input::placeholder {
|
||||
color: #d2d2d2;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
select {
|
||||
background-color: #424242;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
@if (route()) {
|
||||
<!-- <div class="flex items-start m-2 w-fit border-2 border-red-500"> -->
|
||||
<div
|
||||
class="flex flex-col bg-gray-800 border-2 {{
|
||||
isInError() ? 'border-red-500' : 'border-gray-600'
|
||||
}} border-solid w-full h-full"
|
||||
>
|
||||
<div class="flex items-center justify-end border-gray-600 border-b-2">
|
||||
<div class="flex-grow text-left ml-2 text-white">Route {{ index() }}</div>
|
||||
<div class="flex items-center justify-center hover:bg-gray-700" (click)="delete.emit()">
|
||||
<mat-icon class="!text-red-500">close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<form [formGroup]="formGroup">
|
||||
<div class="m-2">
|
||||
<div class="flex items-center m-1">
|
||||
<label class="mr-2 text-white"> Input: </label>
|
||||
<select
|
||||
class="pl-1 border-2 border-gray-200 text-white border-solid rounded-sm w-full"
|
||||
formControlName="input"
|
||||
>
|
||||
@for (option of moduleIds(); track option) {
|
||||
<option [value]="option">
|
||||
{{ option }}
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
@if (!formGroup.controls['input'].valid) {
|
||||
<!-- TODO(jwetzell): better error displaying -->
|
||||
<div class="ml-2 text-red-500">{{ formGroup.controls['input'].errors | json }}</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<div class="flex items-center">
|
||||
@if (schemaService.processorTypes.length > 0) {
|
||||
<div
|
||||
matTooltip="Add Processor"
|
||||
class="flex items-center justify-center w-10 h-10 bg-transparent hover:bg-gray-700 hover:cursor-pointer text-blue-400"
|
||||
[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.name }}</span>
|
||||
</button>
|
||||
}
|
||||
</mat-menu>
|
||||
}
|
||||
<div class="text-md text-white text-center">Processors</div>
|
||||
</div>
|
||||
@if (processors() !== undefined && processors()!.length > 0) {
|
||||
<div class="border-2 border-gray-500 m-2">
|
||||
@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>
|
||||
<!-- </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>
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
import { Component, computed, inject, input, model, output } from '@angular/core';
|
||||
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { ProcessorConfiguration, RouteConfiguration } from '../../models/config.models';
|
||||
import { SchemaService } from '../../services/schema.service';
|
||||
import { JsonPipe } from '@angular/common';
|
||||
import { ProcessorComponent } from '../processor/processor.component';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
|
||||
@Component({
|
||||
selector: 'app-route',
|
||||
imports: [
|
||||
MatFormFieldModule,
|
||||
MatIconModule,
|
||||
ReactiveFormsModule,
|
||||
MatMenuModule,
|
||||
JsonPipe,
|
||||
ProcessorComponent,
|
||||
MatTooltipModule,
|
||||
],
|
||||
templateUrl: './route.component.html',
|
||||
styleUrl: './route.component.css',
|
||||
})
|
||||
export class RouteComponent {
|
||||
path = input<string>('');
|
||||
|
||||
index = computed(() => {
|
||||
const path = this.path();
|
||||
if (path) {
|
||||
const parts = path.split('/');
|
||||
const lastPart = parts[parts.length - 1];
|
||||
return parseInt(lastPart, 10);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
route = model<RouteConfiguration>();
|
||||
moduleIds = input<string[]>([]);
|
||||
delete = output<void>();
|
||||
|
||||
processors = computed(() => {
|
||||
const route = this.route();
|
||||
if (route) {
|
||||
return route.processors;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
formGroup: FormGroup = new FormGroup({
|
||||
input: new FormControl('', [Validators.required]),
|
||||
});
|
||||
|
||||
public schemaService = inject(SchemaService);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
|
||||
ngOnInit(): void {
|
||||
this.formGroup.patchValue({
|
||||
input: this.route()?.input,
|
||||
});
|
||||
|
||||
this.formGroup.valueChanges.subscribe((value) => {
|
||||
this.route.update((route) => {
|
||||
if (route) {
|
||||
route.input = value.input;
|
||||
return {
|
||||
...route,
|
||||
input: route.input,
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
isInError(): boolean {
|
||||
const path = this.path();
|
||||
if (path) {
|
||||
return this.schemaService.errorPaths.includes(path);
|
||||
}
|
||||
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;
|
||||
});
|
||||
this.snackBar.open('Processor Added', 'Dismiss', {
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
route.processors[index].type = processor.type;
|
||||
if (processor.params !== undefined) {
|
||||
route.processors[index].params = processor.params;
|
||||
}
|
||||
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