All checks were successful
Build, test and publish / verify (push) Successful in 7m31s
134 lines
4.4 KiB
TypeScript
134 lines
4.4 KiB
TypeScript
import { SchedulingRun } from './scheduling-status';
|
|
import { inject, Injectable } from '@angular/core';
|
|
import { HttpClient } from '@angular/common/http';
|
|
import { Observable, tap } from 'rxjs';
|
|
import {
|
|
Coach,
|
|
DanceGroup,
|
|
Dancer,
|
|
DancerRequest,
|
|
GroupRequest,
|
|
ResourceKind,
|
|
School,
|
|
SchoolData,
|
|
SchoolRequest,
|
|
Show,
|
|
ShowRequest,
|
|
} from './api-models';
|
|
|
|
@Injectable({ providedIn: 'root' })
|
|
export class SchoolApi {
|
|
private readonly http = inject(HttpClient);
|
|
private readonly base = '/api/dance-schools';
|
|
private readonly revisions = new Map<number, number>();
|
|
|
|
schools(): Observable<School[]> {
|
|
return this.http.get<School[]>(this.base).pipe(
|
|
tap((schools) => {
|
|
for (const school of schools) this.revisions.set(school.id, school.revision);
|
|
}),
|
|
);
|
|
}
|
|
schoolData(schoolId: number): Observable<SchoolData> {
|
|
return this.http
|
|
.get<SchoolData>(`${this.base}/${schoolId}/data`)
|
|
.pipe(tap((data) => this.revisions.set(schoolId, data.school.revision)));
|
|
}
|
|
private options(schoolId: number, expected?: number): { headers: Record<string, string> } {
|
|
const revision = expected ?? this.revisions.get(schoolId);
|
|
return { headers: revision === undefined ? {} : { 'X-School-Revision': String(revision) } };
|
|
}
|
|
saveSchool(body: SchoolRequest, id?: number, revision?: number): Observable<School> {
|
|
return id === undefined
|
|
? this.http.post<School>(this.base, body)
|
|
: this.http.put<School>(`${this.base}/${id}`, body, this.options(id, revision));
|
|
}
|
|
saveDancer(
|
|
schoolId: number,
|
|
body: DancerRequest,
|
|
id?: number,
|
|
revision?: number,
|
|
): Observable<Dancer> {
|
|
return this.save(`${this.base}/${schoolId}/dancers`, body, schoolId, id, revision);
|
|
}
|
|
saveGroup(
|
|
schoolId: number,
|
|
body: GroupRequest,
|
|
id?: number,
|
|
revision?: number,
|
|
): Observable<DanceGroup> {
|
|
return this.save(`${this.base}/${schoolId}/dance-groups`, body, schoolId, id, revision);
|
|
}
|
|
saveShow(schoolId: number, body: ShowRequest, id?: number, revision?: number): Observable<Show> {
|
|
return this.save(`${this.base}/${schoolId}/shows`, body, schoolId, id, revision);
|
|
}
|
|
schedule(schoolId: number, showId: number): Observable<SchedulingRun> {
|
|
return this.http.post<SchedulingRun>(
|
|
`${this.base}/${schoolId}/shows/${showId}/schedule`,
|
|
null,
|
|
this.options(schoolId),
|
|
);
|
|
}
|
|
saveAssignments(
|
|
schoolId: number,
|
|
showId: number,
|
|
assignments: number[][],
|
|
revision?: number,
|
|
): Observable<Show> {
|
|
return this.http.put<Show>(
|
|
`${this.base}/${schoolId}/shows/${showId}/assignments`,
|
|
{
|
|
assignments,
|
|
},
|
|
this.options(schoolId, revision),
|
|
);
|
|
}
|
|
finalize(schoolId: number, showId: number, revision?: number): Observable<Show> {
|
|
return this.http.post<Show>(
|
|
`${this.base}/${schoolId}/shows/${showId}/finalize`,
|
|
null,
|
|
this.options(schoolId, revision),
|
|
);
|
|
}
|
|
linkCoach(schoolId: number, dancerId: number, coachId?: number): Observable<Coach> {
|
|
return this.save<Coach>(`${this.base}/${schoolId}/coaches`, { dancerId }, schoolId, coachId);
|
|
}
|
|
unlinkCoach(schoolId: number, coachId: number): Observable<void> {
|
|
return this.http.delete<void>(
|
|
`${this.base}/${schoolId}/coaches/${coachId}/dancer`,
|
|
this.options(schoolId),
|
|
);
|
|
}
|
|
delete(kind: ResourceKind, schoolId: number, id: number, revision?: number): Observable<void> {
|
|
const collection = { school: '', dancer: '/dancers', group: '/dance-groups', show: '/shows' }[
|
|
kind
|
|
];
|
|
const url =
|
|
kind === 'school' ? `${this.base}/${id}` : `${this.base}/${schoolId}${collection}/${id}`;
|
|
return this.http.delete<void>(url, this.options(schoolId, revision));
|
|
}
|
|
membership(
|
|
schoolId: number,
|
|
groupId: number,
|
|
dancerId: number,
|
|
add: boolean,
|
|
revision?: number,
|
|
): Observable<void> {
|
|
const url = `${this.base}/${schoolId}/dance-groups/${groupId}/dancers/${dancerId}`;
|
|
return add
|
|
? this.http.put<void>(url, null, this.options(schoolId, revision))
|
|
: this.http.delete<void>(url, this.options(schoolId, revision));
|
|
}
|
|
private save<T>(
|
|
url: string,
|
|
body: unknown,
|
|
schoolId: number,
|
|
id?: number,
|
|
revision?: number,
|
|
): Observable<T> {
|
|
return id === undefined
|
|
? this.http.post<T>(url, body, this.options(schoolId, revision))
|
|
: this.http.put<T>(`${url}/${id}`, body, this.options(schoolId, revision));
|
|
}
|
|
}
|