mirror of
https://github.com/jwetzell/showbridge-webui.git
synced 2026-08-19 13:14:00 +00:00
add config preview with a bunch of other tweaks
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
<div class="h-full flex flex-col">
|
||||
<div class="flex items-center">
|
||||
<div class="text-white">Config Preview</div>
|
||||
<div class="flex-grow"></div>
|
||||
<div>
|
||||
<button mat-icon-button matTooltip="Download Config" (click)="downloadConfig()">
|
||||
<mat-icon class="!text-white">download</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 border border-gray-500 overflow-y-auto">
|
||||
<pre class="p-3 text-xs text-white leading-relaxed whitespace-pre-wrap">{{ yamlString() }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,67 @@
|
||||
import { JsonPipe } from '@angular/common';
|
||||
import { Component, computed, input } from '@angular/core';
|
||||
import * as yaml from 'js-yaml';
|
||||
import { Config } from '../../models/config.models';
|
||||
import { MatIcon, MatIconModule } from "@angular/material/icon";
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
|
||||
@Component({
|
||||
selector: 'app-config-preview',
|
||||
imports: [
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
MatTooltipModule
|
||||
],
|
||||
templateUrl: './config-preview.component.html',
|
||||
styleUrl: './config-preview.component.css',
|
||||
})
|
||||
export class ConfigPreviewComponent {
|
||||
config = input<Config | undefined>();
|
||||
|
||||
yamlString = computed(() => {
|
||||
if (this.config() === undefined) {
|
||||
return '';
|
||||
}
|
||||
return yaml.dump(this.config());
|
||||
});
|
||||
|
||||
downloadConfig() {
|
||||
const config = this.config();
|
||||
if (config) {
|
||||
this.downloadYAML(config, 'config.yaml');
|
||||
}
|
||||
}
|
||||
|
||||
downloadJSON(data: object, filename: string) {
|
||||
const content = JSON.stringify(data, null, 2);
|
||||
const dataUri = URL.createObjectURL(
|
||||
new Blob([content], {
|
||||
type: 'application/json;charset=utf-8',
|
||||
}),
|
||||
);
|
||||
const dummyLink = document.createElement('a');
|
||||
dummyLink.href = dataUri;
|
||||
dummyLink.download = filename;
|
||||
|
||||
document.body.appendChild(dummyLink);
|
||||
dummyLink.click();
|
||||
document.body.removeChild(dummyLink);
|
||||
}
|
||||
|
||||
downloadYAML(data: object, filename: string) {
|
||||
const content = yaml.dump(data);
|
||||
const dataUri = URL.createObjectURL(
|
||||
new Blob([content], {
|
||||
type: 'application/yaml;charset=utf-8',
|
||||
}),
|
||||
);
|
||||
const dummyLink = document.createElement('a');
|
||||
dummyLink.href = dataUri;
|
||||
dummyLink.download = filename;
|
||||
|
||||
document.body.appendChild(dummyLink);
|
||||
dummyLink.click();
|
||||
document.body.removeChild(dummyLink);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
@if (config() && schemaService.schemasLoaded()) {
|
||||
<app-module-list [modules]="config()?.modules" (modulesChange)="modulesUpdated($event)"></app-module-list>
|
||||
<app-route-list [routes]="config()?.routes" [moduleIds]="moduleIds()" (routesChange)="routesUpdated($event)"></app-route-list>
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
import { Component, computed, inject } from '@angular/core';
|
||||
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, 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';
|
||||
import { RouteListComponent } from '../route-list.component/route-list.component';
|
||||
import { EventsService } from '../../services/events.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-config',
|
||||
imports: [
|
||||
MatMenuModule,
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
MatTooltipModule,
|
||||
ModuleListComponent,
|
||||
RouteListComponent,
|
||||
],
|
||||
templateUrl: './config.component.html',
|
||||
styleUrl: './config.component.css',
|
||||
})
|
||||
export class ConfigComponent {
|
||||
config = computed<Config | undefined>(() => this.configService.currentlyShownConfig());
|
||||
|
||||
modules = computed(() => this.config()?.modules ?? []);
|
||||
routes = computed(() => this.config()?.routes ?? []);
|
||||
|
||||
moduleIds = computed(() => {
|
||||
const config = this.config();
|
||||
if (config !== undefined && config.modules !== undefined) {
|
||||
return config.modules.map((module) => module.id!) ?? [];
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
public configService = inject(ConfigService);
|
||||
public schemaService = inject(SchemaService);
|
||||
|
||||
public eventsService = inject(EventsService);
|
||||
|
||||
modulesUpdated(modules: ModuleConfig[] | undefined) {
|
||||
if (modules === undefined) {
|
||||
console.error('modules is undefined, not updating');
|
||||
return;
|
||||
}
|
||||
this.configService.currentlyShownConfig.update((config) => {
|
||||
if (config) {
|
||||
return {
|
||||
...config,
|
||||
modules: modules,
|
||||
};
|
||||
}
|
||||
return config;
|
||||
});
|
||||
}
|
||||
|
||||
routesUpdated(routes: RouteConfig[] | undefined) {
|
||||
if (routes === undefined) {
|
||||
console.error('routes is undefined, not updating');
|
||||
return;
|
||||
}
|
||||
this.configService.currentlyShownConfig.update((config) => {
|
||||
if (config) {
|
||||
return {
|
||||
...config,
|
||||
routes: routes,
|
||||
};
|
||||
}
|
||||
return config;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
{{ schema().title || module()?.type }}
|
||||
</div>
|
||||
<div class="flex-grow"></div>
|
||||
<div class="flex items-center justify-center hover:bg-gray-700" (click)="delete.emit()">
|
||||
<div class="flex items-center justify-center hover:bg-gray-700 hover:cursor-pointer" (click)="delete.emit()">
|
||||
<mat-icon class="!text-red-500">close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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 hover:bg-gray-700" (click)="delete.emit()">
|
||||
<div class="flex items-center justify-center hover:bg-gray-700 hover:cursor-pointer" (click)="delete.emit()">
|
||||
<mat-icon class="!text-red-500">close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
<div class="flex-grow overflow-x-hidden overflow-y-auto gap-1.5">
|
||||
@for (route of routes(); track route; let i = $index) {
|
||||
<div class="m-2">
|
||||
<app-route
|
||||
<app-route
|
||||
[path]="`routes/${i}`"
|
||||
(routeChange)="routeUpdated(i, $event)"
|
||||
[route]="route"
|
||||
@@ -3,14 +3,14 @@
|
||||
<div
|
||||
class="flex flex-col bg-gray-800 border-2 {{
|
||||
isInError() ? 'border-red-500' : 'border-gray-600'
|
||||
}} border-solid w-full h-full"
|
||||
}} border-solid w-full"
|
||||
>
|
||||
<div class="flex items-center justify-end">
|
||||
<div class="flex items-center">
|
||||
<mat-icon [style.color]="indicatorColor()" matTooltip="Route Indicator">chevron_right</mat-icon>
|
||||
</div>
|
||||
<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()">
|
||||
<div class="flex items-center justify-center hover:bg-gray-700 hover:cursor-pointer" (click)="delete.emit()">
|
||||
<mat-icon class="!text-red-500">close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user