Skip to content

Commit

Permalink
Merge pull request #836 from jwetzell/feat/webui-add-export-import-mi…
Browse files Browse the repository at this point in the history
…di-list

add export import midi list to patch editor
  • Loading branch information
jwetzell authored Oct 30, 2024
2 parents 28e6ebc + ea20332 commit 6e7f92f
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 44 deletions.
8 changes: 6 additions & 2 deletions webui/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
import { get } from 'lodash-es';
import { filter } from 'rxjs';
import { ClipboardDialogComponent } from './components/clipboard-dialog/clipboard-dialog.component';
import { ImportConfigComponent } from './components/import-config/import-config.component';
import { ImportJSONComponent } from './components/import-json/import-json.component';
import { MIDIInfoDialogComponent } from './components/midi-info-dialog/midi-info-dialog.component';
import { PatchEditorComponent } from './components/patch-editor/patch-editor.component';
import { ConfigState } from './models/config.models';
Expand Down Expand Up @@ -123,9 +123,13 @@ export class AppComponent {
}

importConfig() {
const dialogRef = this.dialog.open(ImportConfigComponent, {
const dialogRef = this.dialog.open(ImportJSONComponent, {
width: '400px',
height: '400px',
data: {
schema: this.schemaService.schema,
title: 'Import Config',
},
});

dialogRef
Expand Down
4 changes: 2 additions & 2 deletions webui/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ActionComponent } from './components/action/action.component';
import { ArrayFormComponent } from './components/array-form/array-form.component';
import { ClipboardDialogComponent } from './components/clipboard-dialog/clipboard-dialog.component';
import { ConfigComponent } from './components/config/config.component';
import { ImportConfigComponent } from './components/import-config/import-config.component';
import { ImportJSONComponent } from './components/import-json/import-json.component';
import { MessageTypeComponent } from './components/message-type/message-type.component';
import { MIDIInfoDialogComponent } from './components/midi-info-dialog/midi-info-dialog.component';
import { ParamsFormComponent } from './components/params-form/params-form.component';
Expand All @@ -41,7 +41,7 @@ import { TriggerComponent } from './components/trigger/trigger.component';
MessageTypeComponent,
ParamsFormComponent,
ArrayFormComponent,
ImportConfigComponent,
ImportJSONComponent,
MIDIInfoDialogComponent,
ClipboardDialogComponent,
PatchEditorComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Component } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms';
import { MatDialogRef } from '@angular/material/dialog';
import { CopyService } from 'src/app/services/copy.service';
import { ImportConfigComponent } from '../import-config/import-config.component';

@Component({
selector: 'app-clipboard-dialog',
Expand All @@ -14,7 +13,7 @@ export class ClipboardDialogComponent {

constructor(
private copyService: CopyService,
public dialogRef: MatDialogRef<ImportConfigComponent>
public dialogRef: MatDialogRef<ClipboardDialogComponent>
) {
this.formGroup = new FormGroup({
clipboard: new FormControl(null, [Validators.required, this.jsonValidator()]),
Expand Down
30 changes: 0 additions & 30 deletions webui/src/app/components/import-config/import-config.component.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<div class="flex flex-col h-full">
<h1 mat-dialog-title>Import Config</h1>
<h1 mat-dialog-title>{{ this.data.title }}</h1>
<ng-container *ngIf="formGroup">
<div class="flex-auto w-full h-full">
<form [formGroup]="formGroup" class="w-full h-full p-2">
<textarea formControlName="config" placeholder="Paste Config Here" class="w-full h-full pt-1 pl-1"></textarea>
<textarea formControlName="json" placeholder="Paste Config Here" class="w-full h-full pt-1 pl-1"></textarea>
</form>
</div>
<div mat-dialog-actions>
<button mat-button mat-dialog-close>Cancel</button>
<span class="flex-auto"></span>
<button mat-button (click)="importConfig()" [disabled]="!formGroup.valid">Import</button>
<button mat-button (click)="importJson()" [disabled]="!formGroup.valid">Import</button>
</div>
</ng-container>
</div>
59 changes: 59 additions & 0 deletions webui/src/app/components/import-json/import-json.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Component, inject } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { SomeJSONSchema } from 'ajv/dist/types/json-schema';
import { SchemaService } from 'src/app/services/schema.service';

type ImportJSONComponentData = {
schema?: SomeJSONSchema;
title: string;
};

@Component({
selector: 'app-import-json',
templateUrl: './import-json.component.html',
styleUrls: ['./import-json.component.css'],
})
export class ImportJSONComponent {
readonly data = inject<ImportJSONComponentData>(MAT_DIALOG_DATA);

formGroup?: FormGroup;

constructor(
private schemaService: SchemaService,
public dialogRef: MatDialogRef<ImportJSONComponent>
) {
if (this.data.schema !== undefined) {
console.log(this.data.schema);
this.formGroup = new FormGroup({
json: new FormControl(null, [
Validators.required,
this.isJSON,
this.schemaService.jsonValidator(this.data.schema),
]),
});
} else {
this.formGroup = new FormGroup({
json: new FormControl(null, [Validators.required, this.isJSON]),
});
}

this.formGroup.valueChanges.subscribe(console.log);
}

isJSON(control: AbstractControl): ValidationErrors | null {
console.log(control);
try {
JSON.parse(control.value);
return null;
} catch (error) {
return { json: error };
}
}

importJson() {
if (this.formGroup?.valid) {
this.dialogRef.close(JSON.parse(this.formGroup.controls['json'].value));
}
}
}
12 changes: 12 additions & 0 deletions webui/src/app/components/patch-editor/patch-editor.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
(click)="addMIDIPatch()">
Add MIDI Patch
</button>
<button
class="px-8 py-1 my-2 ml-2 text-sm text-gray-300 bg-gray-800 border border-gray-500 border-solid rounded-lg"
(click)="copyMIDIDevices()">
Copy Device List
</button>

<button
*ngIf="settingsService.isDummySite"
class="px-8 py-1 my-2 ml-2 text-sm text-gray-300 bg-gray-800 border border-gray-500 border-solid rounded-lg"
(click)="importMIDIDevices()">
Import Device List
</button>
</div>
<table class="w-full">
<thead>
Expand Down
29 changes: 28 additions & 1 deletion webui/src/app/components/patch-editor/patch-editor.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Clipboard } from '@angular/cdk/clipboard';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MIDIPatch, NetworkPatch } from '@showbridge/types';
import { combineLatest, filter, take } from 'rxjs';
import { MIDIDeviceInfo } from 'src/app/models/events.model';
import { EventService } from 'src/app/services/event.service';
import { SettingsService } from 'src/app/services/settings.service';
import { VarsService } from 'src/app/services/vars.service';
import { ImportJSONComponent } from '../import-json/import-json.component';

@Component({
selector: 'app-patch-editor',
Expand All @@ -24,7 +27,9 @@ export class PatchEditorComponent {
public varsService: VarsService,
private eventService: EventService,
private snackbar: MatSnackBar,
public settingsService: SettingsService
public settingsService: SettingsService,
private clipboard: Clipboard,
private dialog: MatDialog
) {
eventService.protocolStatus$
.pipe(
Expand Down Expand Up @@ -65,6 +70,28 @@ export class PatchEditorComponent {
this.midiPatches.push({ name: '', port: '' });
}

copyMIDIDevices() {
this.clipboard.copy(JSON.stringify(this.midiPorts));
this.snackbar.open('Device list copied....', undefined, { duration: 3000 });
}

importMIDIDevices() {
const dialogRef = this.dialog.open(ImportJSONComponent, {
width: '400px',
height: '400px',
data: {
title: 'Import Device List',
},
});

dialogRef
.afterClosed()
.pipe(filter((result) => !!result && result !== ''))
.subscribe((result) => {
this.midiPorts = result;
});
}

savePatches() {
this.midiPatches = this.midiPatches.filter((patch) => patch.port !== undefined);
this.networkPatches = this.networkPatches.filter((patch) => patch.host !== '');
Expand Down
9 changes: 5 additions & 4 deletions webui/src/app/services/schema.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -617,16 +617,17 @@ export class SchemaService {
}
}

configValidator(validateSchema: JSONSchemaType<ConfigFile>) {
jsonValidator(validateSchema: SomeJSONSchema) {
return (control: AbstractControl): ValidationErrors | null => {
try {
const configObj = JSON.parse(control.value);
if (this.ajv.validate(validateSchema, configObj)) {
const jsonObj = JSON.parse(control.value);
if (this.ajv.validate(validateSchema, jsonObj)) {
return null;
} else {
return { config: this.ajv.errors };
return { json: this.ajv.errors };
}
} catch (error) {
console.error(error);
return { json: true };
}
};
Expand Down

0 comments on commit 6e7f92f

Please sign in to comment.