Skip to content
Snippets Groups Projects
Commit fa4e6871 authored by pnogal's avatar pnogal
Browse files

Create course details dialog

parent 017ac528
No related branches found
No related tags found
No related merge requests found
Showing
with 367 additions and 13 deletions
...@@ -7,6 +7,7 @@ import { Course } from './models/course'; ...@@ -7,6 +7,7 @@ import { Course } from './models/course';
import { DegreePlan } from './models/degree-plan'; import { DegreePlan } from './models/degree-plan';
import { Term } from './models/term'; import { Term } from './models/term';
import { FavoriteCourse } from './models/favorite-course'; import { FavoriteCourse } from './models/favorite-course';
import { CourseDetails } from './models/course-details';
const httpOptions = { const httpOptions = {
headers: new HttpHeaders({ headers: new HttpHeaders({
...@@ -39,6 +40,11 @@ export class DataService { ...@@ -39,6 +40,11 @@ export class DataService {
.pipe(catchError(this.errorHandler)); .pipe(catchError(this.errorHandler));
} }
getCourseDetails(termCode: string, subjectCode: string, courseId: string): Observable<CourseDetails[]> {
return this.http.get<CourseDetails[]>(this.searchApiUrl + 'course/' + termCode + '/' + subjectCode + '/' + courseId, httpOptions)
.pipe(catchError(this.errorHandler));
}
getFavoriteCourses(): Observable<FavoriteCourse[]> { getFavoriteCourses(): Observable<FavoriteCourse[]> {
return this.http.get<FavoriteCourse[]>(this.plannerApiUrl + '/favorites') return this.http.get<FavoriteCourse[]>(this.plannerApiUrl + '/favorites')
.pipe(catchError(this.errorHandler)); .pipe(catchError(this.errorHandler));
......
export interface SchoolCollege {
academicOrgCode: string;
academicGroupCode: string;
shortDescription: string;
formalDescription: string;
uddsCode?: any;
schoolCollegeURI: string;
}
export interface Subject {
termCode: string;
subjectCode: string;
description: string;
shortDescription: string;
formalDescription: string;
undergraduateCatalogURI: string;
graduateCatalogURI: string;
departmentURI: string;
uddsFundingSource: string;
schoolCollege: SchoolCollege;
footnotes: string[];
}
export interface Breadth {
code: string;
description: string;
}
export interface LettersAndScienceCredits {
code: string;
description: string;
}
export interface Level {
code: string;
description: string;
}
export interface GradingBasis {
code: string;
description: string;
}
export interface CourseRequirements {
"000008=": number[];
}
export interface Payload {
courseId: string;
}
export interface TitleSuggest {
input: string[];
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;
}
...@@ -2,11 +2,12 @@ import { NgModule } from '@angular/core'; ...@@ -2,11 +2,12 @@ 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 { 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 { CourseDetailsDialogComponent } from './dialogs/course-details-dialog/course-details-dialog.component';
@NgModule({ @NgModule({
imports: [ imports: [
...@@ -19,6 +20,7 @@ import { FavoritesContainerComponent } from './favorites-container/favorites-con ...@@ -19,6 +20,7 @@ import { FavoritesContainerComponent } from './favorites-container/favorites-con
TermContainerComponent, TermContainerComponent,
SidenavMenuItemComponent, SidenavMenuItemComponent,
FavoritesContainerComponent FavoritesContainerComponent
] ],
entryComponents: [ CourseDetailsDialogComponent ]
}) })
export class DegreePlannerModule { } export class DegreePlannerModule { }
<mat-toolbar color="primary" class="dialog-toolbar">
<span class="dialog-toolbar-title">Course Details</span>
<button mat-button mat-dialog-close class="close-btn"><i class="material-icons">clear</i></button>
</mat-toolbar>
<mat-dialog-content id="course-details-content" class="mat-typography dialog-with-toolbar ">
<div fxLayout="row">
<div fxLayout="row" fxFlex="100" fxLayoutGap="10px" class="course-details-header">
<div fxFlex="50" class="course-detail-title" fxLayoutAlign="start center">
<h3>{{ courseDetails.fullCourseDesignation | capitalize }}<span class="course-detail-subtitle">{{ courseDetails.title }}</span></h3>
</div>
<div fxFlex="50" fxLayout="row" fxLayoutAlign="end start" >
<mat-dialog-actions>
<button mat-button class="btn-secondary" mat-dialog-close>Delete</button>
<button mat-raised-button class="btn-primary mat-button">See Sections</button>
</mat-dialog-actions>
</div>
</div>
</div>
<div fxLayout="column" fxLayoutAlign="space-around start" fxLayoutGap="10px" class="course-details-content">
<p>{{ courseDetails.description }}</p>
<p *ngIf="courseDetails.advisoryPrerequisites && courseDetails.advisoryPrerequisites.length > 0"><span class="semi-bold">Requisites:</span>{{ courseDetails.advisoryPrerequisites }}</p>
<ul>
<li *ngIf="courseDetails.creditRange"><span class="semi-bold">Credits:</span> {{ courseDetails.creditRange }}</li>
<li *ngIf="courseDetails.levels && courseDetails.levels.length > 0"><span class="semi-bold">Level:</span>
{{ courseDetails.levels | valuesToString:'description' }}
</li>
<li *ngIf="courseDetails.breadths && courseDetails.breadths.length > 0"><span class="semi-bold">Breadth:</span>
{{ courseDetails.breadths | valuesToString:'description' }}
</li>
<li *ngIf="courseDetails.lettersAndScienceCredits"><span class="semi-bold">L&amp;S Credit Type:</span>
{{ courseDetails.lettersAndScienceCredits.description }}
</li>
</ul>
<ul>
<li *ngIf="courseDetails.lastTaught"><span class="semi-bold">Last Taught:</span> {{ courseDetails.lastTaught | getTermDescription }}</li>
<li *ngIf="(courseDetails.gradCourseWork || courseDetails.workplaceExperience || courseDetails.foreignLanguage)" ><span class="semi-bold">Course Options:</span>
<ul>
<li>
<span *ngIf="courseDetails.gradCourseWork">50% Graduate Coursework Requirement</span>
<span *ngIf="courseDetails.workplaceExperience">{{ courseDetails.workplaceExperience.description }}</span>
<span *ngIf="courseDetails.foreignLanguage">{{ courseDetails.foreignLanguage.description }}</span>
</li>
</ul>
</li>
</ul>
<p class="semi-bold">Subject Notes:</p>
<p>{{ courseDetails.subject.footnotes }}</p>
</div>
<div class="course-details-footer">
<p class="semi-bold">{{ courseDetails.fullCourseDesignation | capitalize }} Information:</p>
<div fxLayout="row">
<div fxLayout="row" fxFlex="100" fxLayoutGap="10px">
<div fxFlex="100" class="course-detail-title" fxLayoutAlign="start center">
<a class="md-primary btn-link mat-button" href="{{ courseDetails.subject.departmentURI }}">Website</a>
<a class="md-primary btn-link mat-button" href="{{ courseDetails.subject.undergraduateCatalogURI }}">Undergraduate Info</a>
<a class="md-primary btn-link mat-button" href="{{ courseDetails.subject.graduateCatalogURI }}">Graduate Info</a>
</div>
</div>
</div>
</div>
</mat-dialog-content>
\ No newline at end of file
@import 'assets/material-theme.scss';
#course-details-content {
ul {
margin-bottom: 20px;
list-style: none;
padding-inline-start: 0px;
}
.course-detail-title {
h3 {
line-height: 1.2;
color: #333;
font-size: 16px;
font-weight: 500;
padding-top: 5px;
}
.course-detail-subtitle {
font-weight: 300;
display: block;
}
}
.mat-dialog-actions {
padding-top: 0px;
}
.course-details-header {
padding: 12px 0px;
}
.btn-link {
color: map-get($uw-primary, 500);
}
.course-details-footer {
margin-top: 5px;
.mat-dialog-actions {
margin-bottom: 0px;
padding-bottom: 0px;
}
}
}
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CourseDetailsDialogComponent } from './course-details-dialog.component';
describe('CourseDetailsDialogComponent', () => {
let component: CourseDetailsDialogComponent;
let fixture: ComponentFixture<CourseDetailsDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CourseDetailsDialogComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CourseDetailsDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Inject } from '@angular/core';
import { CourseDetails, Level, Breadth } from '../../../core/models/course-details';
import { DataService } from '../../../core/data.service';
import { MAT_DIALOG_DATA } from '@angular/material';
@Component({
selector: 'cse-course-details-dialog',
templateUrl: './course-details-dialog.component.html',
styleUrls: ['./course-details-dialog.component.scss']
})
export class CourseDetailsDialogComponent implements OnInit {
courseDetails: CourseDetails;
constructor(@Inject(MAT_DIALOG_DATA) public data: any, private dataService: DataService) {
this.courseDetails = data.courseDetails;
}
ngOnInit() {
}
}
...@@ -2,11 +2,13 @@ import { NgModule } from '@angular/core'; ...@@ -2,11 +2,13 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CourseItemComponent } from './course-item/course-item.component'; import { CourseItemComponent } from './course-item/course-item.component';
import { DragDropModule } from '@angular/cdk/drag-drop'; import { DragDropModule } from '@angular/cdk/drag-drop';
import { CourseDetailsDialogComponent } from '../dialogs/course-details-dialog/course-details-dialog.component';
import { SharedModule } from '../../shared/shared.module';
@NgModule({ @NgModule({
imports: [ CommonModule, DragDropModule ], imports: [ CommonModule, DragDropModule, SharedModule ],
exports: [ CourseItemComponent, DragDropModule ], exports: [ CourseItemComponent, DragDropModule ],
declarations: [ CourseItemComponent ] declarations: [ CourseItemComponent, CourseDetailsDialogComponent ]
}) })
export class SharedDegreePlannerModule { } export class SharedDegreePlannerModule { }
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
(cdkDropListDropped)="drop($event)"> (cdkDropListDropped)="drop($event)">
<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 [course]="course" [status]="'in-progress'"></cse-course-item> <cse-course-item [course]="course" [status]="'in-progress'" (click)="openCourseDetailsDialog(course)"></cse-course-item>
</div> </div>
</div> </div>
<p *ngIf="!courses || courses.length === 0" class="no-courses text-center semi-bold">No Courses Taken</p> <p *ngIf="!courses || courses.length === 0" class="no-courses text-center semi-bold">No Courses Taken</p>
......
...@@ -3,6 +3,9 @@ import { Term } from '../../core/models/term'; ...@@ -3,6 +3,9 @@ import { Term } from '../../core/models/term';
import { Course } from '../../core/models/course'; import { Course } from '../../core/models/course';
import { DataService } from '../../core/data.service'; import { DataService } from '../../core/data.service';
import { CdkDragDrop, transferArrayItem } from '@angular/cdk/drag-drop'; import { CdkDragDrop, transferArrayItem } from '@angular/cdk/drag-drop';
import { MatDialog } from '@angular/material';
import { CourseDetailsDialogComponent } from '../dialogs/course-details-dialog/course-details-dialog.component';
import { CourseDetails } from '../../core/models/course-details';
@Component({ @Component({
selector: 'cse-term-container', selector: 'cse-term-container',
...@@ -15,8 +18,27 @@ export class TermContainerComponent { ...@@ -15,8 +18,27 @@ export class TermContainerComponent {
@Input() courses: Course[]; @Input() courses: Course[];
@Input() termCodes: String[]; @Input() termCodes: String[];
@Input() termsByAcademicYear: Object; @Input() termsByAcademicYear: Object;
@Input() course: CourseDetails;
constructor(private dataService: DataService) {} terms: any[];
favoriteCourse: FavoriteCourse;
constructor(private dataService: DataService, public dialog: MatDialog) {
}
openCourseDetailsDialog(course) {
this.dataService.getCourseDetails(course.termCode, course.subjectCode, course.courseId)
.subscribe(courseDetails => {
const dialogRef = this.dialog.open(CourseDetailsDialogComponent, {
data: { courseDetails: courseDetails }
});
dialogRef.afterClosed().subscribe(result => {
console.log('Dialog was closed');
});
});
}
getTotalCredits() { getTotalCredits() {
if (!this.courses) { if (!this.courses) {
......
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'capitalize'
})
export class CapitalizePipe implements PipeTransform {
transform(word: string, args?: any): any {
return word.toLowerCase()
.split(' ')
.map((char) => char.charAt(0).toUpperCase() + char.substring(1))
.join(' ');
}
}
...@@ -11,9 +11,13 @@ import { MatCardModule } from '@angular/material/card'; ...@@ -11,9 +11,13 @@ import { MatCardModule } from '@angular/material/card';
import { MatSelectModule } from '@angular/material/select'; import { MatSelectModule } from '@angular/material/select';
import { MatSidenavModule } from '@angular/material/sidenav'; import { MatSidenavModule } from '@angular/material/sidenav';
import { MatExpansionModule } from '@angular/material/expansion'; import { MatExpansionModule } from '@angular/material/expansion';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatDialogModule } from '@angular/material/dialog';
import { GetTermDescriptionPipe } from './get-term-description.pipe'; import { GetTermDescriptionPipe } from './get-term-description.pipe';
import { AcademicYearStatePipe } from './academic-year-state.pipe'; import { AcademicYearStatePipe } from './academic-year-state.pipe';
import { CapitalizePipe } from './capitalize.pipe';
import { ValuesToStringPipe } from './values-to-string.pipe';
const modules = [ const modules = [
CommonModule, CommonModule,
...@@ -27,12 +31,15 @@ const modules = [ ...@@ -27,12 +31,15 @@ const modules = [
MatCardModule, MatCardModule,
MatSelectModule, MatSelectModule,
FlexLayoutModule, FlexLayoutModule,
MatSidenavModule MatSidenavModule,
MatToolbarModule,
MatDialogModule
]; ];
@NgModule({ @NgModule({
imports: [ modules ], imports: [ modules ],
exports: [ modules, GetTermDescriptionPipe, AcademicYearStatePipe ], exports: [ modules, GetTermDescriptionPipe, AcademicYearStatePipe, CapitalizePipe, ValuesToStringPipe ],
declarations: [ GetTermDescriptionPipe, AcademicYearStatePipe ] declarations: [ GetTermDescriptionPipe, AcademicYearStatePipe, CapitalizePipe, ValuesToStringPipe ]
}) })
export class SharedModule { } export class SharedModule { }
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'valuesToString'
})
export class ValuesToStringPipe implements PipeTransform {
transform(array: [], key: any): any {
return array.map(element => element[key]).join(', ');
}
}
...@@ -22,9 +22,16 @@ body { ...@@ -22,9 +22,16 @@ body {
} }
.btn-primary { .btn-primary {
background-color: map-get($uw-primary, 500); background-color: #0479a8 !important;
color: #fff; color: white !important;
font-weight: 400; font-weight: 400 !important;
font-size: 14px;
}
.btn-secondary {
color: map-get($uw-primary, 500) !important;
border: 1px solid #b7b7b7 !important;
border-radius: 4px !important;
} }
.complete-icon{ .complete-icon{
...@@ -109,4 +116,29 @@ body { ...@@ -109,4 +116,29 @@ body {
.term-container-wrapper { .term-container-wrapper {
display: flex !important; display: flex !important;
} }
} }
\ No newline at end of file
// Dialogs styles
.mat-dialog-container {
min-width: 700px;
padding: 0px !important;
.dialog-with-toolbar {
padding: 0 45px 10px 45px;
}
}
.dialog-toolbar {
height: 54px !important;
padding-right: 0px !important;
.dialog-toolbar-title {
flex: 1 1 auto;
font-weight: 400;
}
.close-btn {
width: 6px;
min-width: 60px;
padding: 1px 0px;
min-height: 60px;
}
}
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