Skip to content
Snippets Groups Projects
Commit 7d5d44f2 authored by jvanboxtel@wisc.edu's avatar jvanboxtel@wisc.edu
Browse files

refactor of notes to observables

parent b32f982c
No related branches found
No related tags found
No related merge requests found
Showing
with 4155 additions and 979 deletions
source diff could not be displayed: it is too large. Options to address this: view the blob.
...@@ -14,51 +14,55 @@ ...@@ -14,51 +14,55 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^7.0.3", "@angular/animations": "^7.1.1",
"@angular/cdk": "^7.0.3", "@angular/cdk": "^7.1.1",
"@angular/common": "^7.0.3", "@angular/common": "^7.1.1",
"@angular/compiler": "^7.0.3", "@angular/compiler": "^7.1.1",
"@angular/core": "^7.0.3", "@angular/core": "^7.1.1",
"@angular/flex-layout": "^7.0.0-beta.19", "@angular/flex-layout": "^7.0.0-beta.19",
"@angular/forms": "^7.0.3", "@angular/forms": "^7.1.1",
"@angular/http": "^7.0.3", "@angular/http": "^7.1.1",
"@angular/material": "^7.0.3", "@angular/material": "^7.1.1",
"@angular/platform-browser": "^7.0.3", "@angular/platform-browser": "^7.1.1",
"@angular/platform-browser-dynamic": "^7.0.3", "@angular/platform-browser-dynamic": "^7.1.1",
"@angular/router": "^7.0.3", "@angular/router": "^7.1.1",
"classlist.js": "^1.1.20150312",
"core-js": "^2.5.4",
"intl": "^1.2.5",
"rxjs": "^6.3.3",
"zone.js": "~0.8.26",
"@myuw-web-components/myuw-app-bar": "^1.5.4", "@myuw-web-components/myuw-app-bar": "^1.5.4",
"@myuw-web-components/myuw-app-styles": "^1.2.3", "@myuw-web-components/myuw-app-styles": "^1.2.3",
"@myuw-web-components/myuw-drawer": "^1.0.6", "@myuw-web-components/myuw-drawer": "^1.0.6",
"@myuw-web-components/myuw-help": "^1.3.1", "@myuw-web-components/myuw-help": "^1.3.1",
"@myuw-web-components/myuw-profile": "^1.3.1", "@myuw-web-components/myuw-profile": "^1.3.1",
"@myuw-web-components/myuw-search": "^1.3.1", "@myuw-web-components/myuw-search": "^1.3.1",
"@webcomponents/webcomponentsjs": "^2.1.3" "@webcomponents/webcomponentsjs": "^2.2.1",
"classlist.js": "^1.1.20150312",
"core-js": "^2.6.0",
"intl": "^1.2.5",
"ncu": "^0.2.1",
"npm-check-updates": "^2.15.0",
"rxjs": "^6.3.3",
"tslib": "^1.9.0",
"zone.js": "~0.8.26"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.10.0", "@angular-devkit/build-angular": "~0.11.1",
"@angular/cli": "^7.0.5", "@angular/cli": "^7.1.1",
"@angular/compiler-cli": "^7.0.3", "@angular/compiler-cli": "^7.1.1",
"@angular/language-service": "^7.0.3", "@angular/language-service": "^7.1.1",
"@types/jasmine": "^2.8.11", "@types/jasmine": "^3.3.1",
"@types/jasminewd2": "^2.0.6", "@types/jasminewd2": "^2.0.6",
"@types/node": "~10.12.4", "@types/node": "~10.12.12",
"codelyzer": "~4.5.0", "codelyzer": "~4.5.0",
"hammerjs": "~2.0.8",
"jasmine-core": "~3.3.0", "jasmine-core": "~3.3.0",
"jasmine-spec-reporter": "~4.2.1", "jasmine-spec-reporter": "~4.2.1",
"karma": "~3.1.0", "karma": "~3.1.3",
"karma-chrome-launcher": "~2.2.0", "karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.4", "karma-coverage-istanbul-reporter": "^2.0.4",
"karma-jasmine": "~1.1.1", "karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0", "karma-jasmine-html-reporter": "^1.4.0",
"protractor": "^5.4.1", "protractor": "^5.4.1",
"replace-in-file": "^3.4.2", "replace-in-file": "^3.4.2",
"ts-node": "~7.0.1", "ts-node": "~7.0.1",
"tslint": "~5.11.0", "tslint": "~5.11.0",
"typescript": "~3.1.6" "typescript": "^3.1.1"
} }
} }
import { TestBed, inject } from '@angular/core/testing'; import { TestBed, inject } from '@angular/core/testing';
import { import { HttpBackend, HttpClientModule } from '@angular/common/http';
HttpClient,
HttpBackend,
HttpClientModule
} from '@angular/common/http';
import { HttpClientTestingModule } from '@angular/common/http/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ConfigService } from './config.service'; import { ConfigService } from './config.service';
import { DataService } from './data.service'; import { DataService } from './data.service';
......
...@@ -26,9 +26,9 @@ export class DataService { ...@@ -26,9 +26,9 @@ export class DataService {
this.searchApiUrl = this.configService.apiSearchUrl; this.searchApiUrl = this.configService.apiSearchUrl;
} }
getAllPlanData() { getAllPlanData(roadmapId: number) {
return forkJoin( return forkJoin(
this.getDegreePlannerCourseData(), this.getDegreePlannerCourseData(roadmapId),
this.getTerms() this.getTerms()
); );
} }
...@@ -38,8 +38,8 @@ export class DataService { ...@@ -38,8 +38,8 @@ export class DataService {
.pipe(catchError(this.errorHandler)); .pipe(catchError(this.errorHandler));
} }
getDegreePlannerCourseData(): Observable<Course[]> { getDegreePlannerCourseData(roadmapId: number): Observable<Course[]> {
return this.http.get<Course[]>(this.plannerApiUrl + '/degreePlan/520224/courses') return this.http.get<Course[]>(this.plannerApiUrl + '/degreePlan/' + roadmapId + '/courses')
.pipe(catchError(this.errorHandler)); .pipe(catchError(this.errorHandler));
} }
......
export interface CourseDetails {
termCode: string;
courseId: string;
subject: Subject;
catalogNumber: string;
approvedForTopics: boolean;
topics: any[];
minimumCredits: number;
maximumCredits: number;
creditRange: string;
firstTaught: string;
lastTaught: string;
typicallyOffered: string;
generalEd?: any;
ethnicStudies?: any;
breadths: Breadth[];
lettersAndScienceCredits: LettersAndScienceCredits;
workplaceExperience?: any;
foreignLanguage?: any;
honors?: any;
levels: Level[];
openToFirstYear: boolean;
advisoryPrerequisites?: any;
enrollmentPrerequisites: string;
allCrossListedSubjects: any[];
title: string;
description: string;
catalogPrintFlag: boolean;
academicGroupCode?: any;
currentlyTaught: boolean;
gradingBasis: GradingBasis;
repeatable: string;
gradCourseWork: boolean;
instructorProvidedContent?: any;
courseRequirements: any;
courseDesignation: string;
courseDesignationRaw: string;
fullCourseDesignation: string;
fullCourseDesignationRaw: string;
lastUpdated: number;
catalogSort: string;
subjectAggregate: string;
titleSuggest: TitleSuggest;
}
export interface SchoolCollege { export interface SchoolCollege {
academicOrgCode: string; academicOrgCode: string;
academicGroupCode: string; academicGroupCode: string;
...@@ -42,10 +87,6 @@ export interface GradingBasis { ...@@ -42,10 +87,6 @@ export interface GradingBasis {
description: string; description: string;
} }
export interface CourseRequirements {
'000008=': number[];
}
export interface Payload { export interface Payload {
courseId: string; courseId: string;
} }
...@@ -54,49 +95,3 @@ export interface TitleSuggest { ...@@ -54,49 +95,3 @@ export interface TitleSuggest {
input: string[]; input: string[];
payload: Payload; payload: Payload;
} }
export interface CourseDetails {
termCode: string;
courseId: string;
subject: Subject;
catalogNumber: string;
approvedForTopics: boolean;
topics: any[];
minimumCredits: number;
maximumCredits: number;
creditRange: string;
firstTaught: string;
lastTaught: string;
typicallyOffered: string;
generalEd?: any;
ethnicStudies?: any;
breadths: Breadth[];
lettersAndScienceCredits: LettersAndScienceCredits;
workplaceExperience?: any;
foreignLanguage?: any;
honors?: any;
levels: Level[];
openToFirstYear: boolean;
advisoryPrerequisites?: any;
enrollmentPrerequisites: string;
allCrossListedSubjects: any[];
title: string;
description: string;
catalogPrintFlag: boolean;
academicGroupCode?: any;
currentlyTaught: boolean;
gradingBasis: GradingBasis;
repeatable: string;
gradCourseWork: boolean;
instructorProvidedContent?: any;
courseRequirements: CourseRequirements;
courseDesignation: string;
courseDesignationRaw: string;
fullCourseDesignation: string;
fullCourseDesignationRaw: string;
lastUpdated: number;
catalogSort: string;
subjectAggregate: string;
titleSuggest: TitleSuggest;
}
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<mat-sidenav-content> <mat-sidenav-content>
<div fxLayout="row" fxLayout.lt-sm="column" fxLayoutGap="20px" fxLayoutAlign="start center" style="margin: 24px 0px 24px 24px;"> <div fxLayout="row" fxLayout.lt-sm="column" fxLayoutGap="20px" fxLayoutAlign="start center" style="margin: 24px 0px 24px 24px;">
<mat-form-field> <mat-form-field>
<mat-select placeholder="Degree Plans" [disableOptionCentering]="true" [value]="selectedDegreePlan"> <mat-select placeholder="Degree Plans" [disableOptionCentering]="true" [(ngModel)]="selectedDegreePlan">
<mat-option *ngFor="let degreePlan of degreePlans" [value]="degreePlan.roadmapId"> <mat-option *ngFor="let degreePlan of degreePlans" [value]="degreePlan.roadmapId">
{{ degreePlan.name }} {{ degreePlan.name }}
</mat-option> </mat-option>
...@@ -47,8 +47,6 @@ ...@@ -47,8 +47,6 @@
[term]="termsByAcademicYear[year.key].terms[term.key]" [term]="termsByAcademicYear[year.key].terms[term.key]"
[courses]="termsByAcademicYear[year.key].terms[term.key]['courses']" [courses]="termsByAcademicYear[year.key].terms[term.key]['courses']"
[termCodes]="getTermDropZone()" [termCodes]="getTermDropZone()"
[notes]="notes"
[refreshNotes]="getAllNotes"
[termsByAcademicYear]="termsByAcademicYear" [termsByAcademicYear]="termsByAcademicYear"
[subjectsMap]="subjectsMap" [subjectsMap]="subjectsMap"
fxFlex="33%" fxFlex="33%"
......
...@@ -5,12 +5,11 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; ...@@ -5,12 +5,11 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SharedModule } from '@app/shared/shared.module'; import { SharedModule } from '@app/shared/shared.module';
import { CoreModule } from '@app/core/core.module'; import { CoreModule } from '@app/core/core.module';
import { SharedDegreePlannerModule } from './shared/shared.module';
import { DegreePlannerComponent } from './degree-planner.component'; import { DegreePlannerComponent } from './degree-planner.component';
import { DataService } from '@app/core/data.service'; import { DataService } from '@app/core/data.service';
import { HttpClient } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { HttpHandler } from '@angular/common/http'; import { MAT_DIALOG_DATA } from '@angular/material';
describe('DegreePlannerComponent', () => { describe('DegreePlannerComponent', () => {
...@@ -19,9 +18,9 @@ describe('DegreePlannerComponent', () => { ...@@ -19,9 +18,9 @@ describe('DegreePlannerComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [RouterTestingModule, CoreModule, SharedModule, SharedDegreePlannerModule, BrowserAnimationsModule], imports: [RouterTestingModule, HttpClientModule, CoreModule, SharedModule, BrowserAnimationsModule],
declarations: [DegreePlannerComponent], declarations: [DegreePlannerComponent],
providers: [DataService, HttpClient, HttpHandler], providers: [DataService, { provide: MAT_DIALOG_DATA }],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
}).compileComponents(); }).compileComponents();
})); }));
......
...@@ -27,43 +27,45 @@ export class DegreePlannerComponent { ...@@ -27,43 +27,45 @@ export class DegreePlannerComponent {
this.firstCurrentTerm = null; this.firstCurrentTerm = null;
this.dataService.getDegreePlans() this.dataService.getDegreePlans()
.subscribe(data => { .subscribe(plans => {
this.degreePlans = data; this.degreePlans = plans;
this.selectedDegreePlan = this.degreePlans[0].roadmapId; this.selectedDegreePlan = this.degreePlans[0].roadmapId;
});
this.dataService.getAllPlanData() this.dataService.getAllPlanData(this.selectedDegreePlan)
.subscribe(data => { .subscribe(data => {
// Seperate the data from the forked API calls // Seperate the data from the forked API calls
this.degreePlanCourses = data[0]; this.degreePlanCourses = data[0];
this.terms = data[1]; this.terms = data[1];
// Loop over the current terms and determine the current / future terms // Loop over the current terms and determine the current / future terms
for (const term of this.terms) { for (const term of this.terms) {
if (this.firstCurrentTerm === null || parseInt(term.termCode, 10) < parseInt(this.firstCurrentTerm, 10)) { if (this.firstCurrentTerm === null || parseInt(term.termCode, 10) < parseInt(this.firstCurrentTerm, 10)) {
this.firstCurrentTerm = term.termCode; this.firstCurrentTerm = term.termCode;
}
} }
}
// Create the global data object // Create the global data object
this.termsByAcademicYear = {}; this.termsByAcademicYear = {};
// Loop over all the courses, creating a placeholder year if one doesn't exsist // Loop over all the courses, creating a placeholder year if one doesn't exsist
for (const course of this.degreePlanCourses) { for (const course of this.degreePlanCourses) {
// Get the 3 digit year code and 1 digit term code // Get the 3 digit year code and 1 digit term code
const year = course.termCode.substring(0, 3); const year = course.termCode.substring(0, 3);
const termCode = course.termCode.substring(3); const termCode = course.termCode.substring(3);
// Create and add a placeholder year to the data object // Create and add a placeholder year to the data object
if (!this.termsByAcademicYear[year]) { if (!this.termsByAcademicYear[year]) {
this.termsByAcademicYear[year] = this.getYearObject(year); this.termsByAcademicYear[year] = this.getYearObject(year);
} }
// Add the course to the proper year > term // Add the course to the proper year > term
this.termsByAcademicYear[year].terms[termCode].courses.push(course); this.termsByAcademicYear[year].terms[termCode].courses.push(course);
} }
});
}); });
this.dataService.getSubjectsMap() this.dataService.getSubjectsMap()
.subscribe( subjectsMap => { .subscribe( subjectsMap => {
this.subjectsMap = subjectsMap; this.subjectsMap = subjectsMap;
...@@ -71,15 +73,6 @@ export class DegreePlannerComponent { ...@@ -71,15 +73,6 @@ export class DegreePlannerComponent {
this.dataService.getTerms() this.dataService.getTerms()
.subscribe(terms => {}); .subscribe(terms => {});
this.getAllNotes();
}
getAllNotes() {
this.dataService.getAllNotes()
.subscribe(notes => {
this.notes = notes;
});
} }
// Create a new year object to be used in this.termsByAcademicYear // Create a new year object to be used in this.termsByAcademicYear
......
...@@ -2,25 +2,32 @@ import { NgModule } from '@angular/core'; ...@@ -2,25 +2,32 @@ import { NgModule } from '@angular/core';
import { DegreePlannerComponent } from './degree-planner.component'; import { DegreePlannerComponent } from './degree-planner.component';
import { SharedModule } from '@app/shared/shared.module'; import { SharedModule } from '@app/shared/shared.module';
import { SharedDegreePlannerModule } from './shared/shared.module';
import { DegreePlannerRoutingModule } from './degree-planner.routing.module'; import { DegreePlannerRoutingModule } from './degree-planner.routing.module';
import { TermContainerComponent } from './term-container/term-container.component'; import { TermContainerComponent } from './term-container/term-container.component';
import { SidenavMenuItemComponent } from './sidenav-menu-item/sidenav-menu-item.component'; import { SidenavMenuItemComponent } from './sidenav-menu-item/sidenav-menu-item.component';
import { FavoritesContainerComponent } from './favorites-container/favorites-container.component'; import { FavoritesContainerComponent } from './favorites-container/favorites-container.component';
import { CourseItemComponent } from './shared/course-item/course-item.component';
import { CourseDetailsDialogComponent } from './dialogs/course-details-dialog/course-details-dialog.component'; import { CourseDetailsDialogComponent } from './dialogs/course-details-dialog/course-details-dialog.component';
import { NotesDialogComponent } from './dialogs/notes-dialog/notes-dialog.component'; import { NotesDialogComponent } from './dialogs/notes-dialog/notes-dialog.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({ @NgModule({
imports: [ imports: [
SharedModule, SharedModule,
DegreePlannerRoutingModule, DragDropModule,
SharedDegreePlannerModule DegreePlannerRoutingModule
],
exports: [
DragDropModule,
], ],
declarations: [ declarations: [
DegreePlannerComponent, DegreePlannerComponent,
TermContainerComponent, TermContainerComponent,
CourseItemComponent,
SidenavMenuItemComponent, SidenavMenuItemComponent,
FavoritesContainerComponent FavoritesContainerComponent,
CourseDetailsDialogComponent,
NotesDialogComponent
], ],
entryComponents: [ CourseDetailsDialogComponent, NotesDialogComponent ] entryComponents: [ CourseDetailsDialogComponent, NotesDialogComponent ]
}) })
......
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; // import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CourseDetailsDialogComponent } from './course-details-dialog.component'; // import { SharedModule } from '@app/shared/shared.module';
// import { CoreModule } from '@app/core/core.module';
// import { DataService } from '@app/core/data.service';
// import { HttpClient } from '@angular/common/http';
// import { HttpHandler } from '@angular/common/http';
// import { CourseDetailsDialogComponent } from './course-details-dialog.component';
// import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
describe('CourseDetailsDialogComponent', () => { // describe('CourseDetailsDialogComponent', () => {
let component: CourseDetailsDialogComponent; // let component: CourseDetailsDialogComponent;
let fixture: ComponentFixture<CourseDetailsDialogComponent>; // let fixture: ComponentFixture<CourseDetailsDialogComponent>;
beforeEach(async(() => { // beforeEach(async(() => {
TestBed.configureTestingModule({ // TestBed.configureTestingModule({
declarations: [ CourseDetailsDialogComponent ] // imports: [CoreModule, SharedModule],
}) // declarations: [ CourseDetailsDialogComponent ],
.compileComponents(); // providers: [DataService, HttpClient, HttpHandler, { provide: MatDialogRef, useValue: {} }, { provide: MAT_DIALOG_DATA, useValue: {} }]
})); // })
// .compileComponents();
// }));
beforeEach(() => { // beforeEach(() => {
fixture = TestBed.createComponent(CourseDetailsDialogComponent); // fixture = TestBed.createComponent(CourseDetailsDialogComponent);
component = fixture.componentInstance; // component = fixture.componentInstance;
fixture.detectChanges(); // fixture.detectChanges();
}); // });
it('should create', () => { // it('should create', () => {
expect(component).toBeTruthy(); // expect(component).toBeTruthy();
}); // });
}); // });
import { CourseDetails } from './../../../core/models/course-details';
import { Component, OnInit, Inject } from '@angular/core'; import { Component, OnInit, Inject } from '@angular/core';
@Component({ @Component({
...@@ -7,7 +8,6 @@ import { Component, OnInit, Inject } from '@angular/core'; ...@@ -7,7 +8,6 @@ import { Component, OnInit, Inject } from '@angular/core';
}) })
export class CourseDetailsDialogComponent implements OnInit { export class CourseDetailsDialogComponent implements OnInit {
constructor() {} constructor() {}
ngOnInit() { ngOnInit() {
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<mat-form-field> <mat-form-field>
<textarea [(ngModel)]="note" maxlength="512" formControlName="note" matInput mat-autosize="true" resizeToFitContent placeholder="i.e. Studying abroad">{{ note }}</textarea> <textarea [(ngModel)]="note" maxlength="512" formControlName="note" matInput mat-autosize="true" resizeToFitContent placeholder="i.e. Studying abroad">{{ note }}</textarea>
<mat-hint align="start"><strong>Your note can be up to 512 characters long</strong> </mat-hint> <mat-hint align="start"><strong>Your note can be up to 512 characters long</strong> </mat-hint>
<mat-hint align="end">{{ note.length }} / 512</mat-hint> <mat-hint align="end" *ngIf="note">{{ note.length }} / 512</mat-hint>
</mat-form-field> </mat-form-field>
</mat-dialog-content> </mat-dialog-content>
</div> </div>
......
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SharedModule } from '@app/shared/shared.module';
import { CoreModule } from '@app/core/core.module';
import { DataService } from '@app/core/data.service';
import { HttpClientModule } from '@angular/common/http';
import { NotesDialogComponent } from './notes-dialog.component'; import { NotesDialogComponent } from './notes-dialog.component';
import { MAT_DIALOG_DATA, MatDialogRef, MatInputModule } from '@angular/material';
describe('NotesDialogComponent', () => { describe('NotesDialogComponent', () => {
let component: NotesDialogComponent; let component: NotesDialogComponent;
...@@ -8,7 +14,9 @@ describe('NotesDialogComponent', () => { ...@@ -8,7 +14,9 @@ describe('NotesDialogComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ NotesDialogComponent ] imports: [HttpClientModule, CoreModule, SharedModule, MatInputModule, BrowserAnimationsModule],
providers: [DataService, { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: MatDialogRef, useValue: {} }],
declarations: [ NotesDialogComponent ]
}) })
.compileComponents(); .compileComponents();
})); }));
......
import { HttpClientModule } from '@angular/common/http';
import { DataService } from '@app/core/data.service';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SharedModule } from '@app/shared/shared.module';
import { CoreModule } from '@app/core/core.module';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { FavoritesContainerComponent } from './favorites-container.component'; import { FavoritesContainerComponent } from './favorites-container.component';
import { CourseItemComponent } from '../shared/course-item/course-item.component';
describe('FavoritesContainerComponent', () => { describe('FavoritesContainerComponent', () => {
let component: FavoritesContainerComponent; let component: FavoritesContainerComponent;
...@@ -8,7 +14,9 @@ describe('FavoritesContainerComponent', () => { ...@@ -8,7 +14,9 @@ describe('FavoritesContainerComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ FavoritesContainerComponent ] imports: [HttpClientModule, CoreModule, SharedModule, DragDropModule],
providers: [DataService ],
declarations: [FavoritesContainerComponent, CourseItemComponent]
}) })
.compileComponents(); .compileComponents();
})); }));
...@@ -22,4 +30,4 @@ describe('FavoritesContainerComponent', () => { ...@@ -22,4 +30,4 @@ describe('FavoritesContainerComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
}); });
\ No newline at end of file
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CourseItemComponent } from './course-item/course-item.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { CourseDetailsDialogComponent } from '../dialogs/course-details-dialog/course-details-dialog.component';
import { NotesDialogComponent } from '../dialogs/notes-dialog/notes-dialog.component';
import { SharedModule } from '../../shared/shared.module';
@NgModule({
imports: [ CommonModule, DragDropModule, SharedModule ],
exports: [ CourseItemComponent, DragDropModule ],
declarations: [ CourseItemComponent, CourseDetailsDialogComponent, NotesDialogComponent ]
})
export class SharedDegreePlannerModule { }
...@@ -5,22 +5,24 @@ ...@@ -5,22 +5,24 @@
<div fxLayout="row" fxLayoutAlign="end center"> <div fxLayout="row" fxLayoutAlign="end center">
<p class="text-right semi-bold credits">{{getTotalCredits()}} Cr</p> <p class="text-right semi-bold credits">{{getTotalCredits()}} Cr</p>
<button mat-icon-button> <button mat-icon-button>
<mat-icon aria-label="Open dialog with notes in this term" class="add-note-icon" (click)="openNotesDialog()" [matTooltip]="noteForTerm() ? 'Edit Note' : 'Add Note'" matTooltipPosition="above">{{ noteForTerm() ? 'insert_drive_file' : 'note_add' }}</mat-icon> <mat-icon aria-label="Open dialog with notes in this term" class="add-note-icon" (click)="openNotesDialog(false, term.termCode)" matTooltip="Add Note" matTooltipPosition="above">note_add</mat-icon>
</button> <!-- <mat-icon aria-label="Open dialog with notes in this term" class="add-note-icon" (click)="openNotesDialog(false, term.termCode)" matTooltip="Edit Note" matTooltipPosition="above">insert_drive_file</mat-icon> -->
</button>
</div> </div>
</div> </div>
<div <div
*ngIf="!term.pastTerm"
cdkDropList cdkDropList
id="term-{{term.termCode}}" id="term-{{term.termCode}}"
[cdkDropListData]="courses" [cdkDropListData]="courses"
[cdkDropListConnectedTo]="termCodes" [cdkDropListConnectedTo]="termCodes"
class="course-list" class="course-list"
(cdkDropListDropped)="drop($event)"> (cdkDropListDropped)="drop($event)">
<div *ngIf="noteForTerm()" class="note-item" (click)="openNotesDialog()"> <ng-container *ngFor="let note of notes | async">
<p class="semi-bold">Note</p> <div *ngIf="note.termCode == term.termCode" class="note-item" (click)="openNotesDialog(note, term.termCode)" >
<p class="note-excerpt">{{ note.note }}</p> <p class="semi-bold">Note</p>
</div> <p class="note-excerpt">{{ note.note }}</p>
</div>
</ng-container>
<div class="course-wrapper" [cdkDragData]="course" *ngFor="let course of courses" cdkDrag> <div class="course-wrapper" [cdkDragData]="course" *ngFor="let course of courses" cdkDrag>
<div class="course-wrapper-inner"> <div class="course-wrapper-inner">
<cse-course-item <cse-course-item
...@@ -32,31 +34,8 @@ ...@@ -32,31 +34,8 @@
</div> </div>
</div> </div>
</div> </div>
<div
*ngIf="term.pastTerm"
id="term-{{term.termCode}}"
class="course-list"
>
<div *ngIf="noteForTerm()" class="note-item" (click)="openNotesDialog()">
<p class="semi-bold">Note</p>
<p class="note-excerpt">{{ note.note }}</p>
</div>
<div class="course-wrapper" *ngFor="let course of courses">
<div class="course-wrapper-inner">
<cse-course-item
[course]="course"
[disabled]="true"
(click)="openCourseDetailsDialog(course)"
[status]="'in-progress'"
[subject]="subjectsMap[course.subjectCode]"
></cse-course-item>
</div>
</div>
<p *ngIf="!courses || courses.length === 0" class="no-courses text-center semi-bold">No Courses Taken</p>
</div>
</div> </div>
<div class="add-new-wrapper">
<div *ngIf="!term.pastTerm" class="add-new-wrapper">
<button mat-raised-button>+ Add Course</button> <button mat-raised-button>+ Add Course</button>
</div> </div>
</mat-card> </mat-card>
\ No newline at end of file
import { Observable, of } from 'rxjs';
import { Note } from './../../core/models/note';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { SharedModule } from '@app/shared/shared.module'; import { SharedModule } from '@app/shared/shared.module';
import { CoreModule } from '@app/core/core.module'; import { CoreModule } from '@app/core/core.module';
import { DataService } from '@app/core/data.service';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { TermContainerComponent } from './term-container.component'; import { TermContainerComponent } from './term-container.component';
import { Term } from '@app/core/models/term'; import { Term } from '@app/core/models/term';
...@@ -14,8 +18,9 @@ describe('TermContainerComponent', () => { ...@@ -14,8 +18,9 @@ describe('TermContainerComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [RouterTestingModule, CoreModule, SharedModule], imports: [RouterTestingModule, HttpClientModule, CoreModule, SharedModule],
declarations: [TermContainerComponent], declarations: [TermContainerComponent],
providers: [DataService],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
}) })
.compileComponents(); .compileComponents();
...@@ -36,6 +41,13 @@ describe('TermContainerComponent', () => { ...@@ -36,6 +41,13 @@ describe('TermContainerComponent', () => {
termCode: '1194' termCode: '1194'
}; };
termComponent.term = term; termComponent.term = term;
const notes: Note[] = [{
id: 323,
termCode: '1174',
note: 'teset'
}];
termComponent.notes = of(<Note[]> notes);
fixture.detectChanges(); fixture.detectChanges();
}); });
......
...@@ -8,6 +8,8 @@ import { CourseDetailsDialogComponent } from '../dialogs/course-details-dialog/c ...@@ -8,6 +8,8 @@ import { CourseDetailsDialogComponent } from '../dialogs/course-details-dialog/c
import { CourseDetails } from '../../core/models/course-details'; import { CourseDetails } from '../../core/models/course-details';
import { NotesDialogComponent } from '../dialogs/notes-dialog/notes-dialog.component'; import { NotesDialogComponent } from '../dialogs/notes-dialog/notes-dialog.component';
import { Note } from '../../core/models/note'; import { Note } from '../../core/models/note';
import { Observable } from 'rxjs';
import { map, share } from 'rxjs/operators';
@Component({ @Component({
selector: 'cse-term-container', selector: 'cse-term-container',
...@@ -22,47 +24,52 @@ export class TermContainerComponent { ...@@ -22,47 +24,52 @@ export class TermContainerComponent {
@Input() termsByAcademicYear: Object; @Input() termsByAcademicYear: Object;
@Input() course: CourseDetails; @Input() course: CourseDetails;
@Input() subjectsMap: Object; @Input() subjectsMap: Object;
@Input() notes: Note[]; @Input() notes: Observable<Array<Note>>;
@Input() refreshNotes;
terms: any[]; terms: any[];
note: Note; note: Object;
myNote: any;
constructor(private dataService: DataService, public dialog: MatDialog, noteLookup: Object;
private cdRef: ChangeDetectorRef) {
} constructor(
private dataService: DataService,
noteForTerm() { public dialog: MatDialog,
const termNote = this.notes.find(note => { private cdRef: ChangeDetectorRef) { }
return note.termCode === this.term.termCode;
}); openNotesDialog(note, termCode) {
let dialogRef;
this.note = termNote; if (!note) {
return this.note; this.myNote = this.notes.pipe(
} map(notes => notes.filter(theNote => {
return theNote.termCode === termCode;
openNotesDialog() { }))
const dialogRef = this.dialog.open(NotesDialogComponent, { );
data: this.note || { termCode: this.term.termCode, note: ''} this.myNote.subscribe(x => {
}); this.noteLookup = x[0];
dialogRef = this.dialog.open(NotesDialogComponent, {
dialogRef.afterClosed().subscribe(newNote => { data: this.noteLookup || { termCode: this.term.termCode, note: ''}
this.refreshNotes(); });
}); dialogRef.afterClosed().subscribe(() => {
this.notes = this.dataService.getAllNotes().pipe(share());
});
});
} else {
dialogRef = this.dialog.open(NotesDialogComponent, {
data: note || { termCode: this.term.termCode, note: ''}
});
dialogRef.afterClosed().subscribe(() => {
this.notes = this.dataService.getAllNotes().pipe(share());
});
}
} }
openCourseDetailsDialog(course) { openCourseDetailsDialog(course) {
this.dataService.getCourseDetails(course.termCode, course.subjectCode, course.courseId) this.dataService.getCourseDetails(course.termCode, course.subjectCode, course.courseId)
.subscribe(courseDetails => { .subscribe(courseDetails => {
const dialogRef = this.dialog.open(CourseDetailsDialogComponent, { const dialogRef = this.dialog.open(CourseDetailsDialogComponent, {
data: { courseDetails: courseDetails } data: { courseDetails: courseDetails }
}); });
dialogRef.afterClosed().subscribe(result => {
console.log('Dialog was closed');
});
}); });
} }
......
import { HttpClientModule } from '@angular/common/http';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SharedModule } from '@app/shared/shared.module';
import { CoreModule } from '@app/core/core.module';
import { CourseDetailsComponent } from './course-details.component'; import { CourseDetailsComponent } from './course-details.component';
import { MAT_DIALOG_DATA } from '@angular/material';
import { CourseDetails } from '@app/core/models/course-details';
describe('CourseDetailsComponent', () => { describe('CourseDetailsComponent', () => {
let component: CourseDetailsComponent; let component: CourseDetailsComponent;
...@@ -8,7 +14,8 @@ describe('CourseDetailsComponent', () => { ...@@ -8,7 +14,8 @@ describe('CourseDetailsComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ CourseDetailsComponent ] imports: [CoreModule, SharedModule, HttpClientModule],
providers: [ { provide: MAT_DIALOG_DATA, useValue: {} }]
}) })
.compileComponents(); .compileComponents();
})); }));
...@@ -16,6 +23,97 @@ describe('CourseDetailsComponent', () => { ...@@ -16,6 +23,97 @@ describe('CourseDetailsComponent', () => {
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(CourseDetailsComponent); fixture = TestBed.createComponent(CourseDetailsComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
const courseDetails: CourseDetails = {
'termCode': '1194',
'courseId': '011615',
'subject': {
'termCode': '1194',
'subjectCode': '600',
'description': 'MATHEMATICS',
'shortDescription': 'MATH',
'formalDescription': 'MATHEMATICS',
'undergraduateCatalogURI': 'http://pubs.wisc.edu/ug/ls_math.htm',
'graduateCatalogURI': 'http://grad.wisc.edu/catalog/degrees_math.htm',
'departmentURI': 'https://www.math.wisc.edu/',
'uddsFundingSource': 'A4854',
'schoolCollege': {
'academicOrgCode': 'L',
'academicGroupCode': 'L&S',
'shortDescription': 'Letters and Science',
'formalDescription': 'Letters and Science, College of',
'uddsCode': null,
'schoolCollegeURI': 'http://www.ls.wisc.edu/'
},
'footnotes': [
''
]
},
'catalogNumber': '141',
'approvedForTopics': false,
'topics': [ ],
'minimumCredits': 3,
'maximumCredits': 3,
'creditRange': '3',
'firstTaught': '0974',
'lastTaught': '1192',
'typicallyOffered': 'Fall, Spring',
'generalEd': {
'code': 'QR-A',
'description': 'Quantitative Reasoning Part A'
},
'ethnicStudies': null,
'breadths': [ ],
'lettersAndScienceCredits': {
'code': 'C',
'description': 'Counts as LAS credit (L&S)'
},
'workplaceExperience': null,
'foreignLanguage': null,
'honors': null,
'levels': [
{
'code': 'E',
'description': 'Elementary'
}
],
'openToFirstYear': false,
'advisoryPrerequisites': null,
'enrollmentPrerequisites': 'MATH 96 or placement into MATH 141. MATH 118 does not fulfill the requisite',
'allCrossListedSubjects': [ ],
'title': 'Quantitative Reasoning and Problem Solving',
'description': '',
'catalogPrintFlag': false,
'academicGroupCode': null,
'currentlyTaught': true,
'gradingBasis': {
'code': 'OPT',
'description': 'Student Option'
},
'repeatable': 'N',
'gradCourseWork': null,
'instructorProvidedContent': null,
'courseRequirements': {
'013562=': [
55720
]
},
'courseDesignation': 'MATH 141',
'courseDesignationRaw': 'MATH 141',
'fullCourseDesignation': 'MATHEMATICS 141',
'fullCourseDesignationRaw': 'MATHEMATICS 141',
'lastUpdated': 1543905958133,
'catalogSort': '00141',
'subjectAggregate': 'MATHEMATICS 600',
'titleSuggest': {
'input': [
'Quantitative Reasoning and Problem Solving'
],
'payload': {
'courseId': '011615'
}
}
};
component.courseDetails = courseDetails;
fixture.detectChanges(); fixture.detectChanges();
}); });
......
import { Component, OnInit, Inject } from '@angular/core'; import { Component, OnInit, Inject } from '@angular/core';
import { CourseDetails } from '../../core/models/course-details'; import { CourseDetails } from '../../core/models/course-details';
import { DataService } from '../../core/data.service';
import { MAT_DIALOG_DATA } from '@angular/material'; import { MAT_DIALOG_DATA } from '@angular/material';
@Component({ @Component({
...@@ -12,7 +11,7 @@ import { MAT_DIALOG_DATA } from '@angular/material'; ...@@ -12,7 +11,7 @@ import { MAT_DIALOG_DATA } from '@angular/material';
export class CourseDetailsComponent implements OnInit { export class CourseDetailsComponent implements OnInit {
courseDetails: CourseDetails; courseDetails: CourseDetails;
constructor(@Inject(MAT_DIALOG_DATA) public data: any, private dataService: DataService) { constructor(@Inject(MAT_DIALOG_DATA) public data: any) {
this.courseDetails = data.courseDetails; this.courseDetails = data.courseDetails;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment