Newer
Older

Scott Berg
committed
// Libraries
import { CdkDragDrop } from '@angular/cdk/drag-drop';

Scott Berg
committed
import { Observable } from 'rxjs';
import { filter, map, distinctUntilChanged } from 'rxjs/operators';

Scott Berg
committed
import { Store, select } from '@ngrx/store';
import { DegreePlannerState } from '@app/degree-planner/store/state';

Scott Berg
committed
import {
MoveCourseBetweenTerms,
AddCourse,
RemoveSaveForLater,
} from '@app/degree-planner/store/actions/course.actions';

Scott Berg
committed
import {
ToggleCourseSearch,
OpenCourseSearch,
CloseCourseSearch,
} from '@app/degree-planner/store/actions/ui.actions';

Scott Berg
committed
// Services
import { SidenavService } from './../../core/service/sidenav.service';
import * as actions from '@app/degree-planner/store/actions/course.actions';
import * as selectors from '@app/degree-planner/store/selectors';
import { PlannedTerm } from '@app/core/models/planned-term';
import { Note } from '@app/core/models/note';
import { Course } from '@app/core/models/course';
} from '@app/degree-planner/dialogs/notes-dialog/notes-dialog.component';
import * as utils from '@app/degree-planner/shared/utils';
const isntUndefined = <T>(thing: T | undefined): thing is T => {
return thing !== undefined;
};
const sumCredits = (courses: Course[]): number => {
return courses.reduce((sum, course) => {
return sum + course.credits;
}, 0);
};
pnogal
committed
@Component({
selector: 'cse-term-container',
templateUrl: './term-container.component.html',
styleUrls: ['./term-container.component.scss'],
pnogal
committed
})

Scott Berg
committed
export class TermContainerComponent implements OnInit {
@Input() yearCode: string;
@Input() termName: 'fall' | 'spring' | 'summer';
public termCode: string;
public term$: Observable<PlannedTerm>;
public note$: Observable<Note | undefined>;
public courses$: Observable<Course[]>;
public credits$: Observable<number>;
public isPastTerm$: Observable<boolean>;
public dropZoneIds$: Observable<string[]>;
public isCurrentTerm$: Observable<boolean>;
constructor(
public dialog: MatDialog,
private store: Store<{ degreePlanner: DegreePlannerState }>,
) {}
public ngOnInit() {
const termOffset = { fall: 2, spring: 4, summer: 6 };
this.termCode = `${this.yearCode}${termOffset[this.termName]}`;
this.term$ = this.store.pipe(
select(selectors.selectVisibleTerm, { termCode: this.termCode }),
filter(isntUndefined),
distinctUntilChanged(),
this.note$ = this.term$.pipe(
map(term => term.note),
distinctUntilChanged(),
);
this.courses$ = this.term$.pipe(
map(term => term.courses),
distinctUntilChanged(),
);
this.credits$ = this.courses$.pipe(
map(sumCredits),
distinctUntilChanged(),
);
this.isPastTerm$ = this.term$.pipe(
map(term => term.era === 'past'),
distinctUntilChanged(),
);
this.dropZoneIds$ = this.store.pipe(
select(selectors.selectAllVisibleYears),
utils.yearsToDropZoneIds(),
distinctUntilChanged(utils.compareStringArrays),
);
this.isPastTerm$ = this.store.pipe(
select(selectors.isPastTerm(this.termCode)),
);
this.isCurrentTerm$ = this.store.pipe(
select(selectors.isCurrentTerm(this.termCode)),
);
openNotesDialog(note?: Note) {
const termCode = this.termCode;
const data: NotesDialogData = note
? { termCode, hasExistingNote: true, initialText: note.note }
: { termCode, hasExistingNote: false };
this.dialog.open(NotesDialogComponent, { data });
toggleCourseSearch() {
this.store.dispatch(new ToggleCourseSearch());
}
drop(event: CdkDragDrop<string[]>) {
const newContainer = event.container.id;
const previousContainer = event.previousContainer.id;
if (newContainer === previousContainer) {
// If the user dropped a course into the same container do nothing
return;
} else if (previousContainer.indexOf('term-') === 0) {
// If moving from term to term
// Get the pervious and new term code, and the record ID
const to = newContainer.substr(5);
const { termCode: from, id } = event.item.data;
// Dispatch a new change request
this.store.dispatch(new actions.MoveCourseBetweenTerms({ to, from, id }));
} else if (previousContainer === 'saved-courses') {
// If moving from saved courses to term
// Get the term code from the new term dropzone's ID
const termCode = newContainer.substr(5);
// Pull the course data from the moved item
const { subjectCode, courseId } = event.item.data;
this.store.dispatch(
new actions.AddCourse({
subjectCode,
courseId,
termCode,
}),
);
this.store.dispatch(
new actions.RemoveSaveForLater({ subjectCode, courseId }),
);
} else if (
previousContainer === 'queried-courses-list' &&
newContainer.indexOf('term-') === 0
) {
const termCode = newContainer.substr(5);
const { subjectCode, courseId } = event.item.data;
this.store.dispatch(
new actions.AddCourse({ subjectCode, courseId, termCode }),
);