From dea461d92dd6f098facfc6a70a75d613490eba80 Mon Sep 17 00:00:00 2001
From: Scott Berg <saberg3@wisc.edu>
Date: Wed, 20 Feb 2019 16:21:54 -0600
Subject: [PATCH] ROENROLL-1395

---
 .../degree-planner.component.html             |  5 +-
 .../course-item/course-item.component.html    |  1 -
 .../course-item/course-item.component.ts      |  7 +-
 .../store/actions/course.actions.ts           |  4 +-
 .../store/effects/plan.effects.ts             |  1 +
 src/app/degree-planner/store/reducer.ts       |  8 +-
 .../course-details.component.html             | 18 +++--
 .../course-details.component.ts               | 77 +++++++++++++++++--
 8 files changed, 97 insertions(+), 24 deletions(-)

diff --git a/src/app/degree-planner/degree-planner.component.html b/src/app/degree-planner/degree-planner.component.html
index 7205e64..a30c99e 100644
--- a/src/app/degree-planner/degree-planner.component.html
+++ b/src/app/degree-planner/degree-planner.component.html
@@ -128,7 +128,6 @@
             </ng-container>
           </mat-accordion>
         </div>
-      </mat-sidenav-content>
-    </mat-sidenav-container>
-  </mat-sidenav-content>
+
+    </mat-sidenav-content>
 </mat-sidenav-container>
diff --git a/src/app/degree-planner/shared/course-item/course-item.component.html b/src/app/degree-planner/shared/course-item/course-item.component.html
index ba27d1b..5d97eb9 100644
--- a/src/app/degree-planner/shared/course-item/course-item.component.html
+++ b/src/app/degree-planner/shared/course-item/course-item.component.html
@@ -27,7 +27,6 @@
           <button mat-menu-item (click)="openCourseDetailsDialog(course)">Course Details</button>
           <button mat-menu-item [matMenuTriggerFor]="academicYearsGroup">Move</button>
           <mat-menu #academicYearsGroup="matMenu" class="course-item-submenu">
-            <button mat-menu-item (click)="moveToSavedForLater(course)" *ngIf="type != 'saved'" class="saved-for-later-list">Saved for later</button>
             <button mat-menu-item *ngFor="let term of (droppableTermCodes$ | async)" (click)="onMove(term)">{{ term | getTermDescription }}</button>
           </mat-menu>
           <button mat-menu-item *ngIf="type !== 'saved'" (click)="onSaveForLater()">Save for later</button>
diff --git a/src/app/degree-planner/shared/course-item/course-item.component.ts b/src/app/degree-planner/shared/course-item/course-item.component.ts
index 07e090f..4ae7859 100644
--- a/src/app/degree-planner/shared/course-item/course-item.component.ts
+++ b/src/app/degree-planner/shared/course-item/course-item.component.ts
@@ -205,9 +205,7 @@ export class CourseItemComponent implements OnInit {
 
     const termCode = term;
     const newIndex = 0;
-    this.store.dispatch(
-      new AddCourse({ subjectCode, courseId, termCode, newIndex }),
-    );
+    this.store.dispatch(new AddCourse({ subjectCode, courseId, termCode }));
   }
 
   switchTerm(course, term) {
@@ -223,7 +221,8 @@ export class CourseItemComponent implements OnInit {
       .subscribe(courseDetails => {
         const dialogRef = this.dialog.open(CourseDetailsDialogComponent, {
           maxWidth: '800px',
-          data: { courseDetails: courseDetails },
+          width: '80%',
+          data: { courseDetails: courseDetails, courseType: this.type },
         });
       });
   }
diff --git a/src/app/degree-planner/store/actions/course.actions.ts b/src/app/degree-planner/store/actions/course.actions.ts
index 749984a..5f6f44d 100644
--- a/src/app/degree-planner/store/actions/course.actions.ts
+++ b/src/app/degree-planner/store/actions/course.actions.ts
@@ -52,14 +52,14 @@ export class AddCourse implements Action {
       subjectCode: string;
       courseId: string;
       termCode: string;
-      newIndex: number;
+      newIndex?: number;
     },
   ) {}
 }
 
 export class AddCourseSuccess implements Action {
   public readonly type = CourseActionTypes.AddCourseSuccess;
-  constructor(public payload: { course: Course; newIndex: number }) {}
+  constructor(public payload: { course: Course; newIndex?: number }) {}
 }
 
 export class RemoveCourse implements Action {
diff --git a/src/app/degree-planner/store/effects/plan.effects.ts b/src/app/degree-planner/store/effects/plan.effects.ts
index b6a601d..012d51b 100644
--- a/src/app/degree-planner/store/effects/plan.effects.ts
+++ b/src/app/degree-planner/store/effects/plan.effects.ts
@@ -104,6 +104,7 @@ export class DegreePlanEffects {
           subjects: of(subjects),
           expandedYears: of([] as string[]),
           subjectDescriptions: of(descriptions),
+          search: of({ visible: false, selectedTerm: activeTermCodes[0] }),
         });
       },
     ),
diff --git a/src/app/degree-planner/store/reducer.ts b/src/app/degree-planner/store/reducer.ts
index 162fe78..2f8e88b 100644
--- a/src/app/degree-planner/store/reducer.ts
+++ b/src/app/degree-planner/store/reducer.ts
@@ -319,11 +319,11 @@ export function degreePlannerReducer(
         const toYear = createYearWithCourse(
           toTermCode,
           course,
-          newIndex,
           state.activeTermCodes,
           fromYearCode === toYearCode
             ? fromYear
             : state.visibleYears[toYearCode],
+          newIndex,
         );
 
         const visibleYears = {
@@ -346,9 +346,9 @@ export function degreePlannerReducer(
       const year: Year = createYearWithCourse(
         termCode,
         course,
-        newIndex,
         state.activeTermCodes,
         state.visibleYears[yearCode],
+        newIndex,
       );
 
       const visibleYears = {
@@ -570,14 +570,14 @@ const findCourse = (years: YearMapping, termCode: string, recordId: number) => {
 const createYearWithCourse = (
   termCode: string,
   course: Course,
-  newIndex: number,
   activeTermCodes: string[],
   year = generateYearForTermCode(termCode, activeTermCodes),
+  newIndex?: number,
 ): Year => {
   const { termName } = parseTermCode(termCode);
   const term = year[termName];
   const courses = term.courses.slice();
-  courses.splice(newIndex, 0, course);
+  courses.splice(newIndex !== undefined ? newIndex : courses.length, 0, course);
   return { ...year, [termName]: { ...term, courses } };
 };
 
diff --git a/src/app/shared/components/course-details/course-details.component.html b/src/app/shared/components/course-details/course-details.component.html
index cf07238..0362a9d 100644
--- a/src/app/shared/components/course-details/course-details.component.html
+++ b/src/app/shared/components/course-details/course-details.component.html
@@ -4,11 +4,19 @@
 			<div fxFlex="50" class="course-detail-title" fxLayoutAlign="start center">
 				<h3>{{ courseDetails.fullCourseDesignation | titlecase }}<span class="course-detail-subtitle">{{ courseDetails.title }}</span></h3>
 			</div>
-			<!-- <div fxFlex="50" fxLayout="row" fxLayoutAlign="end start" >
-				<mat-dialog-actions>
-					<button mat-raised-button class="btn-primary mat-button">See Sections</button>
-				</mat-dialog-actions>
-			</div> -->
+			<div *ngIf="type === 'search' || type === 'saved'" fxFlex="50" fxLayout="row" fxLayoutAlign="end start" >
+					<div style="margin-top: 10px;">
+							<form [formGroup]='termSelector' (ngSubmit)="addCourseToPlan($event)">
+								<mat-form-field style="margin-right:20px;">
+										<mat-select placeholder="Term" aria-label="Term" matInput formControlName="term">
+												<mat-option *ngFor="let term of (droppableTermCodes$ | async)" [value]="term">{{term | getTermDescription}}</mat-option>
+										</mat-select>
+									</mat-form-field>
+
+								<button mat-raised-button color="primary" mat-dialog-close (click)="addCourseToPlan($event)">Add to plan</button>
+							</form>
+					</div>
+			</div>
 		</div>
 	</div>
 
diff --git a/src/app/shared/components/course-details/course-details.component.ts b/src/app/shared/components/course-details/course-details.component.ts
index bec3f7b..47fa4a8 100644
--- a/src/app/shared/components/course-details/course-details.component.ts
+++ b/src/app/shared/components/course-details/course-details.component.ts
@@ -1,18 +1,85 @@
-import { Component, OnInit, Inject } from '@angular/core';
+import { Observable, Subscription } from 'rxjs';
+import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
 import { CourseDetails } from '../../../core/models/course-details';
 import { MAT_DIALOG_DATA } from '@angular/material';
+import * as selectors from '@app/degree-planner/store/selectors';
+import * as utils from '@app/degree-planner/shared/utils';
+import { GlobalState } from '@app/core/state';
+import { Store, select } from '@ngrx/store';
+import { distinctUntilChanged } from 'rxjs/operators';
+import { FormBuilder, FormGroup } from '@angular/forms';
+
+import {
+  AddCourse,
+  RemoveSaveForLater,
+} from '@app/degree-planner/store/actions/course.actions';
 
 @Component({
   selector: 'cse-course-details',
   templateUrl: './course-details.component.html',
   styleUrls: ['./course-details.component.scss'],
 })
-export class CourseDetailsComponent implements OnInit {
-  courseDetails: CourseDetails;
+export class CourseDetailsComponent implements OnInit, OnDestroy {
+  public courseDetails: CourseDetails;
+  public type: 'course' | 'search' | 'saved';
+  public selectedSearchTerm: string;
+
+  public termSelector: FormGroup;
 
-  constructor(@Inject(MAT_DIALOG_DATA) public data: any) {
+  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,
+  ) {
     this.courseDetails = data.courseDetails;
+    this.type = data.courseType;
   }
 
-  ngOnInit() {}
+  ngOnInit() {
+    this.selectedSearchTerm$ = this.store.pipe(
+      select(selectors.getSelectedSearchTerm),
+    );
+
+    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 = this.termSelector.value.term;
+    const subjectCode = this.courseDetails.subject.subjectCode;
+    const courseId = this.courseDetails.courseId;
+
+    switch (this.type) {
+      case 'search':
+        this.store.dispatch(new AddCourse({ subjectCode, courseId, termCode }));
+        break;
+
+      case 'saved':
+        this.store.dispatch(new AddCourse({ subjectCode, courseId, termCode }));
+        this.store.dispatch(new RemoveSaveForLater({ subjectCode, courseId }));
+        break;
+    }
+  }
 }
-- 
GitLab