Skip to content
Snippets Groups Projects
course-details.component.ts 2.81 KiB
Newer Older
Scott Berg's avatar
Scott Berg committed
import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Observable, Subscription } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { Store, select } from '@ngrx/store';

import { CourseDetails } from '@app/core/models/course-details';
Scott Berg's avatar
Scott Berg committed
import * as selectors from '@app/degree-planner/store/selectors';
import * as utils from '@app/degree-planner/shared/utils';
import { TermCode } from '@app/core/models/termcode';
Scott Berg's avatar
Scott Berg committed
import { GlobalState } from '@app/core/state';

import {
  AddCourse,
  RemoveSaveForLater,
} from '@app/degree-planner/store/actions/course.actions';
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
  selector: 'cse-course-details',
  templateUrl: './course-details.component.html',
  styleUrls: ['./course-details.component.scss'],
Scott Berg's avatar
Scott Berg committed
export class CourseDetailsComponent implements OnInit, OnDestroy {
  public courseDetails: CourseDetails;
  public type: 'course' | 'search' | 'saved';
  public selectedSearchTerm: string;

  public termSelector: FormGroup;
Scott Berg's avatar
Scott Berg committed
  public selectedSearchTerm$: Observable<string>;
  public droppableTermCodes$: Observable<string[]>;
  public searchTermSubscription: Subscription;

  constructor(
    @Inject(MAT_DIALOG_DATA) public data: any,
    private store: Store<GlobalState>,
    private fb: FormBuilder,
  ) {
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
    this.courseDetails = data.courseDetails;
Scott Berg's avatar
Scott Berg committed
    this.type = data.courseType;
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
  }
Scott Berg's avatar
Scott Berg committed
  ngOnInit() {
    this.selectedSearchTerm$ = this.store.pipe(
      select(selectors.getSelectedSearchTerm),
Isaac Evavold's avatar
Isaac Evavold committed
      map(termCode => (termCode ? termCode.toString() : '0000')),
Scott Berg's avatar
Scott Berg committed
    );

    this.droppableTermCodes$ = this.store.pipe(
      select(selectors.selectAllVisibleYears),
      utils.yearsToDroppableTermCodes(),
      distinctUntilChanged(utils.compareStringArrays),
    );

    this.searchTermSubscription = this.selectedSearchTerm$.subscribe(
      termCode => {
        this.selectedSearchTerm = termCode;
      },
    );

    this.termSelector = this.fb.group({
      term: this.selectedSearchTerm,
    });
  }

  ngOnDestroy() {
    this.searchTermSubscription.unsubscribe();
  }

  addCourseToPlan($event) {
    $event.preventDefault();
    const termCode = new TermCode(this.termSelector.value.term);
Scott Berg's avatar
Scott Berg committed
    const subjectCode = this.courseDetails.subject.subjectCode;
    const courseId = this.courseDetails.courseId;
Isaac Evavold's avatar
Isaac Evavold committed
    const payload = {
      courseId,
      termCode,
      subjectCode,
      title: this.courseDetails.title,
      catalogNumber: this.courseDetails.catalogNumber,
    };
Scott Berg's avatar
Scott Berg committed

    switch (this.type) {
      case 'search':
Isaac Evavold's avatar
Isaac Evavold committed
        this.store.dispatch(new AddCourse(payload));
Scott Berg's avatar
Scott Berg committed
        break;

      case 'saved':
Isaac Evavold's avatar
Isaac Evavold committed
        this.store.dispatch(new AddCourse(payload));
Scott Berg's avatar
Scott Berg committed
        this.store.dispatch(new RemoveSaveForLater({ subjectCode, courseId }));
        break;
    }
  }