add config upload and viewing returned errors for modules and routes

This commit is contained in:
Joel Wetzell
2026-03-12 17:07:09 -05:00
parent 9570428df9
commit 597e0c4aa4
17 changed files with 248 additions and 142 deletions
@@ -3,7 +3,7 @@ import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatTooltipModule } from '@angular/material/tooltip';
import { Config, ModuleConfiguration, RouteConfiguration } from '../../models/config.models';
import { Config, ModuleConfig, RouteConfig } from '../../models/config.models';
import { ConfigService } from '../../services/config.service';
import { SchemaService } from '../../services/schema.service';
import { ModuleListComponent } from '../module-list/module-list.component';
@@ -42,7 +42,7 @@ export class ConfigComponent {
public eventsService = inject(EventsService);
modulesUpdated(modules: ModuleConfiguration[] | undefined) {
modulesUpdated(modules: ModuleConfig[] | undefined) {
if (modules === undefined) {
console.error('modules is undefined, not updating');
return;
@@ -58,7 +58,7 @@ export class ConfigComponent {
});
}
routesUpdated(routes: RouteConfiguration[] | undefined) {
routesUpdated(routes: RouteConfig[] | undefined) {
if (routes === undefined) {
console.error('routes is undefined, not updating');
return;
@@ -1,7 +1,7 @@
import { Component, inject, model } from '@angular/core';
import { ModuleComponent } from '../module/module.component';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ModuleConfiguration } from '../../models/config.models';
import { ModuleConfig } from '../../models/config.models';
import { SchemaService } from '../../services/schema.service';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
@@ -21,12 +21,12 @@ import { MatTooltipModule } from '@angular/material/tooltip';
styleUrl: './module-list.component.css',
})
export class ModuleListComponent {
modules = model<ModuleConfiguration[]>();
modules = model<ModuleConfig[]>();
public schemaService = inject(SchemaService);
private snackBar = inject(MatSnackBar);
moduleUpdated(index: number, module: ModuleConfiguration | undefined) {
moduleUpdated(index: number, module: ModuleConfig | undefined) {
if (module === undefined) {
console.error('module is undefined, not updating');
return;
@@ -43,5 +43,20 @@
</div>
</form>
</div>
<div>
@if (moduleConfigErrors().length > 0) {
<div class="m-2 p-2 border-2 border-red-500">
<div class="flex items-center mb-2 text-red-500">
<mat-icon>error</mat-icon>
<span class="ml-1">Module Errors</span>
</div>
@for (error of moduleConfigErrors(); track error) {
<div class="ml-4 mb-1 text-white">
{{ error.error }}
</div>
}
</div>
}
</div>
</div>
}
+23 -2
View File
@@ -3,13 +3,14 @@ import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angula
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { ModuleConfiguration } from '../../models/config.models';
import { ModuleConfig } from '../../models/config.models';
import { SchemaService } from '../../services/schema.service';
import { ParamsFormComponent } from '../params-form/params-form.component';
import { JsonPipe } from '@angular/common';
import { MatTooltipModule } from '@angular/material/tooltip';
import { EventsService } from '../../services/events.service';
import { tap, debounceTime } from 'rxjs';
import { ConfigService } from '../../services/config.service';
@Component({
selector: 'app-module',
@@ -27,7 +28,17 @@ import { tap, debounceTime } from 'rxjs';
})
export class ModuleComponent {
path = input<string>('');
module = model<ModuleConfiguration>();
index = computed(() => {
const path = this.path();
if (path) {
const parts = path.split('/');
const lastPart = parts[parts.length - 1];
return parseInt(lastPart, 10);
}
return undefined;
});
module = model<ModuleConfig>();
delete = output<void>();
params = computed(() => this.module()!.params);
@@ -39,6 +50,15 @@ export class ModuleComponent {
: undefined;
});
moduleConfigErrors = computed(() => {
const index = this.index();
const moduleErrors = this.configService.moduleErrors();
if (index !== undefined) {
return moduleErrors.filter((error) => error.index === index);
}
return [];
});
formGroup: FormGroup = new FormGroup({
id: new FormControl('', [Validators.required]),
type: new FormControl(''),
@@ -49,6 +69,7 @@ export class ModuleComponent {
private schemaService = inject(SchemaService);
private eventsService = inject(EventsService);
private configService = inject(ConfigService);
ngOnInit(): void {
this.formGroup.patchValue({
id: this.module()?.id,
@@ -9,7 +9,7 @@
<div class="flex-grow ml-1 mr-3 text-white">
{{ schema()?.title || processor()?.type }}
</div>
<div class="flex items-center justify-center" (click)="delete.emit()">
<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>
@@ -1,5 +1,5 @@
import { Component, computed, inject, input, model, output, signal } from '@angular/core';
import { ProcessorConfiguration } from '../../models/config.models';
import { ProcessorConfig } from '../../models/config.models';
import { SchemaService } from '../../services/schema.service';
import { MatIconModule } from '@angular/material/icon';
import { ParamsFormComponent } from '../params-form/params-form.component';
@@ -13,7 +13,7 @@ import { ReactiveFormsModule } from '@angular/forms';
})
export class ProcessorComponent {
path = input<string>('');
processor = model<ProcessorConfiguration>();
processor = model<ProcessorConfig>();
delete = output<void>();
params = computed(() => this.processor()!.params);
@@ -1,6 +1,6 @@
import { Component, inject, input, model } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ModuleConfiguration, RouteConfiguration } from '../../models/config.models';
import { ModuleConfig, RouteConfig } from '../../models/config.models';
import { SchemaService } from '../../services/schema.service';
import { RouteComponent } from '../route/route.component';
import { MatButtonModule } from '@angular/material/button';
@@ -22,7 +22,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
})
export class RouteListComponent {
routes = model<RouteConfiguration[]>();
routes = model<RouteConfig[]>();
moduleIds = input<string[]>();
public schemaService = inject(SchemaService);
@@ -41,7 +41,7 @@ export class RouteListComponent {
});
}
routeUpdated(index: number, route: RouteConfiguration | undefined) {
routeUpdated(index: number, route: RouteConfig | undefined) {
if (route === undefined) {
console.error('route is undefined, not updating');
return;
@@ -49,7 +49,6 @@ export class RouteListComponent {
this.routes.update((routes) => {
if (routes) {
routes[index].input = route.input;
routes[index].output = route.output;
return [...routes];
}
return routes;
@@ -73,6 +73,21 @@
}
</div>
</div>
<div>
@if (routeConfigErrors().length > 0) {
<div class="m-2 p-2 border-2 border-red-500">
<div class="flex items-center mb-2 text-red-500">
<mat-icon>error</mat-icon>
<span class="ml-1">Route Errors</span>
</div>
@for (error of routeConfigErrors(); track error) {
<div class="ml-4 mb-1 text-white">
{{ error.error }}
</div>
}
</div>
}
</div>
</div>
<!-- </div> -->
+14 -3
View File
@@ -3,7 +3,7 @@ import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angula
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 { ProcessorConfig, RouteConfig } from '../../models/config.models';
import { SchemaService } from '../../services/schema.service';
import { JsonPipe } from '@angular/common';
import { ProcessorComponent } from '../processor/processor.component';
@@ -11,6 +11,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { EventsService } from '../../services/events.service';
import { debounceTime, tap } from 'rxjs';
import { ConfigService } from '../../services/config.service';
@Component({
selector: 'app-route',
@@ -39,7 +40,7 @@ export class RouteComponent {
return undefined;
});
route = model<RouteConfiguration>();
route = model<RouteConfig>();
moduleIds = input<string[]>([]);
delete = output<void>();
@@ -51,6 +52,15 @@ export class RouteComponent {
return [];
});
routeConfigErrors = computed(() => {
const index = this.index();
const routeErrors = this.configService.routeErrors();
if (index !== undefined) {
return routeErrors.filter((error) => error.index === index);
}
return [];
});
formGroup: FormGroup = new FormGroup({
input: new FormControl('', [Validators.required]),
});
@@ -58,6 +68,7 @@ export class RouteComponent {
public schemaService = inject(SchemaService);
private snackBar = inject(MatSnackBar);
private eventsService = inject(EventsService);
private configService = inject(ConfigService);
indicatorColor = signal<string>('gray');
@@ -119,7 +130,7 @@ export class RouteComponent {
});
}
processorUpdated(index: number, processor: ProcessorConfiguration | undefined) {
processorUpdated(index: number, processor: ProcessorConfig | undefined) {
if (processor === undefined) {
console.error('processor is undefined, not updating');
return;