Skip to content
Snippets Groups Projects
Forked from an inaccessible project.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
api.service.ts 4.09 KiB
// Libraries
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Location } from '@angular/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

// Services
import { ConfigService } from '@app/core/config.service';

// Models
import { Note } from '@app/core/models/note';
import { Term } from '@app/core/models/term';
import { Course } from '@app/core/models/course';
import { DegreePlan } from '@app/core/models/degree-plan';
import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';

const HTTP_OPTIONS = {
	headers: new HttpHeaders({
		'Content-Type': 'application/json'
	})
};

@Injectable({ providedIn: 'root' })
export class DegreePlannerApiService {
	constructor(private http: HttpClient, private config: ConfigService) {}

	public getSavedForLaterCourses(): Observable<SavedForLaterCourse[]> {
		return this.http.get<SavedForLaterCourse[]>(
			`${this.config.apiPlannerUrl}/favorites`
		);
	}

	public getAllDegreePlans(): Observable<DegreePlan[]> {
		return this.http.get<DegreePlan[]>(this.degreePlanEndpoint());
	}

	public getPlan(roadmapId: number): Observable<DegreePlan> {
		return this.http.get<DegreePlan>(this.degreePlanEndpoint(roadmapId));
	}

	public getActiveTerms(): Observable<Term[]> {
		return this.http.get<Term[]>(this.searchEndpoint('terms'));
	}

	public getAllNotes(roadmapId: number): Observable<Note[]> {
		return this.http.get<Note[]>(this.degreePlanEndpoint(roadmapId, 'notes'));
	}

	public getAllCourses(roadmapId: number): Observable<Course[]> {
		return this.http.get<Course[]>(
			this.degreePlanEndpoint(roadmapId, 'courses')
		);
	}

	public updateCourseTerm(roadmapId, recordId, termCode): Observable<any> {
		return this.http.put<Course>(this.config.apiPlannerUrl + '/degreePlan/' +
		roadmapId + '/courses/' + recordId + '?termCode=' + termCode, HTTP_OPTIONS);
	}

	public addCourse(planId: number, subjectCode: string, courseId: string, termCode: string): Observable<Course> {
		return this.http.post<Course>(
			this.config.apiPlannerUrl + '/degreePlan/' + planId + '/courses', {subjectCode, courseId, termCode }, HTTP_OPTIONS);
	}

	public removeCourse(planId: number, recordId: string) {
		return this.http.delete(this.config.apiPlannerUrl + '/degreePlan/' + planId + '/courses/' + recordId, HTTP_OPTIONS);
	}

	public saveForLater(subjectCode: string, courseId: string): Observable<SavedForLaterCourse> {
		return this.http.post<SavedForLaterCourse>(this.config.apiPlannerUrl + '/favorites/' + subjectCode + '/' + courseId, HTTP_OPTIONS);
	}

	public removeSavedForLater(subjectCode: string, courseId: string): Observable<SavedForLaterCourse> {
		return this.http.delete<SavedForLaterCourse>(this.config.apiPlannerUrl + '/favorites/' + subjectCode + '/' + courseId, HTTP_OPTIONS);
	}

	public createNote(
		planId: number,
		termCode: string,
		noteText: string
	): Observable<Note> {
		const payload = {
			termCode: termCode,
			note: noteText
		};

		return this.http.post<Note>(
			this.degreePlanEndpoint(planId, 'notes'),
			payload,
			HTTP_OPTIONS
		);
	}

	public updateNote(
		planId: number,
		termCode: string,
		noteText: string,
		noteId: number
	): Observable<Note> {
		const payload = {
			termCode: termCode,
			note: noteText,
			id: noteId
		};

		return this.http
			.put<null>(
				this.degreePlanEndpoint(planId, 'notes', noteId),
				payload,
				HTTP_OPTIONS
			)
			.pipe(map(() => payload));
	}

	public deleteNote(planId: number, noteId: number): Observable<null> {
		return this.http.delete<null>(
			this.degreePlanEndpoint(planId, 'notes', noteId),
			HTTP_OPTIONS
		);
	}

	/**
	 * Helper function for building API endpoint URLs
	 */
	private degreePlanEndpoint(...parts: any[]): string {
		return ['degreePlan']
			.concat(parts.map(part => part.toString()))
			.reduce((soFar, next) => {
				return Location.joinWithSlash(soFar, next);
			}, this.config.apiPlannerUrl);
	}

	private searchEndpoint(...parts: any[]): string {
		return parts
			.map(part => part.toString())
			.reduce((soFar, next) => {
				return Location.joinWithSlash(soFar, next);
			}, this.config.apiSearchUrl);
	}
}