-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: MP parser frontend scaffolding + API calls #84
Changes from 1 commit
6b69280
0927ca6
d886440
7db4393
d746f1d
5c73086
6db8503
04bc766
4aacd2f
a4815a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.control-wrapper { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
gap: 1rem; | ||
} | ||
|
||
.control { | ||
width: 100%; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,52 @@ | ||
import { Component } from "@angular/core"; | ||
import { Component, DestroyRef, OnInit } from "@angular/core"; | ||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; | ||
import { FormControl, FormGroup, Validators } from "@angular/forms"; | ||
import { map } from "rxjs"; | ||
import { MpApiService } from "src/app/shared/services/mp-api.service"; | ||
import { StatusService } from "src/app/shared/services/status.service"; | ||
|
||
@Component({ | ||
selector: "pp-minimalist-parser-input", | ||
templateUrl: "./minimalist-parser-input.component.html", | ||
styleUrl: "./minimalist-parser-input.component.scss", | ||
}) | ||
export class MinimalistParserInputComponent {} | ||
export class MinimalistParserInputComponent implements OnInit { | ||
public form = new FormGroup({ | ||
mpInput: new FormControl<string>("", { | ||
validators: [Validators.required], | ||
}), | ||
}); | ||
|
||
public loading$ = this.apiService.loading$; | ||
|
||
public statusOk$ = this.statusService | ||
.getStatus$() | ||
.pipe(map((status) => status.mp && status.vulcan)); | ||
|
||
constructor( | ||
private destroyRef: DestroyRef, | ||
private apiService: MpApiService, | ||
private statusService: StatusService, | ||
) {} | ||
|
||
ngOnInit(): void { | ||
this.apiService.output$ | ||
.pipe(takeUntilDestroyed(this.destroyRef)) | ||
.subscribe((response) => { | ||
if (!response) { | ||
return; | ||
} | ||
// Do something with the response. | ||
}); | ||
} | ||
|
||
public parse(): void { | ||
this.form.controls.mpInput.markAsTouched(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, considering the public parse(): void {
this.form.controls.mpInput.markAsTouched();
this.form.controls.mpInput.updateValueAndValidity();
const input = this.form.controls.mpInput.value;
if (this.form.invalid || !input) {
return;
}
this.apiService.input$.next(input);
} These functions are very similar: could we think of a good way to make them generalizable / put them in a service? Is that even worthwhile, do you think? I'm happy to let this rest since it's not really priority but I was wondering all the same. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I definitely there is room to DRY this code a bit more. I've created a new issue for it: #93 . |
||
this.form.controls.mpInput.updateValueAndValidity(); | ||
const input = this.form.controls.mpInput.value; | ||
if (this.form.invalid || !input) { | ||
return; | ||
} | ||
this.apiService.input$.next(input); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { TestBed } from "@angular/core/testing"; | ||
|
||
import { MpApiService } from "./mp-api.service"; | ||
|
||
describe("MpApiService", () => { | ||
let service: MpApiService; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({}); | ||
service = TestBed.inject(MpApiService); | ||
}); | ||
|
||
it("should be created", () => { | ||
expect(service).toBeTruthy(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { Injectable } from "@angular/core"; | ||
import { ParsePortDataService } from "./ParsePortDataService"; | ||
import { | ||
catchError, | ||
distinctUntilChanged, | ||
map, | ||
merge, | ||
of, | ||
share, | ||
Subject, | ||
switchMap, | ||
throttleTime, | ||
} from "rxjs"; | ||
import { HttpClient, HttpHeaders } from "@angular/common/http"; | ||
import { environment } from "src/environments/environment"; | ||
import { ErrorHandlerService } from "./error-handler.service"; | ||
|
||
type MPInput = string; | ||
type MPOutput = string; | ||
type MPLoading = boolean; | ||
|
||
@Injectable({ | ||
providedIn: "root", | ||
}) | ||
export class MpApiService | ||
implements ParsePortDataService<MPInput, MPOutput, MPLoading> | ||
{ | ||
public input$ = new Subject<string>(); | ||
|
||
public throttledInput$ = this.input$.pipe( | ||
distinctUntilChanged(), | ||
throttleTime(300), | ||
); | ||
|
||
public output$ = this.throttledInput$.pipe( | ||
switchMap((input) => | ||
this.http | ||
.post<MPOutput | null>( | ||
`${environment.apiUrl}mp/parse`, | ||
{ input }, | ||
{ | ||
headers: new HttpHeaders({ | ||
"Content-Type": "application/json", | ||
}), | ||
}, | ||
) | ||
.pipe( | ||
catchError((error) => { | ||
this.errorHandler.handleHttpError( | ||
error, | ||
$localize`An error occurred while handling your input.`, | ||
); | ||
return of(null); | ||
}), | ||
), | ||
), | ||
share(), | ||
); | ||
|
||
public loading$ = merge( | ||
this.throttledInput$.pipe(map(() => true)), | ||
this.output$.pipe(map(() => false)), | ||
); | ||
|
||
constructor( | ||
private http: HttpClient, | ||
private errorHandler: ErrorHandlerService, | ||
) {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love the 'temporarily'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's important to give your users hope and prospects of a better future ;)