From 3e832a8f1e8a1354ad32146504e50c912a2464ff Mon Sep 17 00:00:00 2001 From: Paulina Nogal <pnogal@wisc.edu> Date: Thu, 13 Jun 2019 19:00:04 +0000 Subject: [PATCH] Get termcourses data --- .../dars/dars-view/dars-view.component.html | 9 +- src/app/dars/dars-view/dars-view.component.ts | 6 +- .../new-audit-options.component.html | 99 ++++++++++--------- .../new-audit-options.component.scss | 7 ++ .../new-audit-options.component.ts | 61 ++++++++++-- src/app/dars/services/api.service.ts | 22 +++-- src/assets/sass/general.scss | 16 ++- 7 files changed, 155 insertions(+), 65 deletions(-) diff --git a/src/app/dars/dars-view/dars-view.component.html b/src/app/dars/dars-view/dars-view.component.html index 4116a84..d08c670 100644 --- a/src/app/dars/dars-view/dars-view.component.html +++ b/src/app/dars/dars-view/dars-view.component.html @@ -39,9 +39,9 @@ aria-label="Run new degree audit" color="primary" [disabled]="(metadataStatus$ | async) != 'Loaded'" - (click)="openNewAuditOptionsDialog()"> - Run new degree audit - </button> + (click)="openNewAuditOptionsDialog('degree')"> + Run new degree audit + </button> </div> </div> @@ -70,7 +70,8 @@ mat-raised-button aria-label="Run new degree audit" [disabled]="(metadataStatus$ | async) != 'Loaded'" - color="primary"> + color="primary" + (click)="openNewAuditOptionsDialog('whatif')"> Run new ‘what if’ audit </button> </div> diff --git a/src/app/dars/dars-view/dars-view.component.ts b/src/app/dars/dars-view/dars-view.component.ts index 597f524..bba02f9 100644 --- a/src/app/dars/dars-view/dars-view.component.ts +++ b/src/app/dars/dars-view/dars-view.component.ts @@ -46,8 +46,10 @@ export class DARSViewComponent implements OnInit { this.store.dispatch(new darsActions.DismissAlert({ key })); } - public openNewAuditOptionsDialog() { - this.dialog.open(NewAuditOptionsComponent, {}); + public openNewAuditOptionsDialog(selectedAuditType) { + this.dialog.open(NewAuditOptionsComponent, { + data: { selectedAuditType: selectedAuditType }, + }); } public openAudit(metadata: AuditMetadata) { diff --git a/src/app/dars/new-audit-options/new-audit-options.component.html b/src/app/dars/new-audit-options/new-audit-options.component.html index 33dd556..8b39b82 100644 --- a/src/app/dars/new-audit-options/new-audit-options.component.html +++ b/src/app/dars/new-audit-options/new-audit-options.component.html @@ -25,12 +25,12 @@ <mat-step class="audit-step" formGroupName="0" [stepControl]="formArray?.get([0])"> <ng-template matStepLabel>Choose audit type</ng-template> <mat-radio-group class="audit-radio-group" formControlName="auditType"> - <mat-radio-button checked="true" class="audit-radio-button" name="declared-audit-type" id="declared-audit-type" value="declaredMajorAudit" aria-label="Select run a degree audit with declared major"> + <mat-radio-button [checked]="selectedAuditType === 'degree'" class="audit-radio-button" name="declared-audit-type" id="declared-audit-type" value="declaredMajorAudit" aria-label="Select run a degree audit with declared major"> <p>Run a degree audit with declared major <br /> <span class="sub-line">See the progress towards your current program of study.</span></p> </mat-radio-button> - <mat-radio-button class="audit-radio-button" name="what-if-audit-type" id="what-if-audit-type" value="whatIfAudit" aria-label="Select run a what-if degree audit"> + <mat-radio-button [checked]="selectedAuditType === 'whatif'" class="audit-radio-button" name="what-if-audit-type" id="what-if-audit-type" value="whatIfAudit" aria-label="Select run a what-if degree audit"> <p>Run a what-if degree audit <br /> <span class="sub-line">See the progress towards a new program of study and degree plans.</span></p> </mat-radio-button> @@ -42,9 +42,8 @@ <mat-step class="audit-step" formGroupName="1" [stepControl]="formArray?.get([1])"> <ng-template matStepLabel>Select program of study</ng-template> - <mat-radio-group *ngIf="newAuditForm.value.formArray[0].auditType === 'declaredMajorAudit'" class="audit-radio-group" formControlName="darsDegreeProgram"> - <mat-radio-button *ngFor="let program of DARSprograms" class="audit-radio-button" name="{{ program.darsDegreeProgramCode }}" id="{{ program.darsDegreeProgramCode }}" value="{{ program.darsDegreeProgramCode }}" aria-label="{{ program.darsDegreeProgramCode }}"> + <mat-radio-button *ngFor="let program of studentDegreeProgram; let i = index" [value]="i" [checked]="i === 0" class="audit-radio-button" name="darsDegreeProgramCode" id="{{ program.darsDegreeProgramCode }}" aria-label="{{ program.darsDegreeProgramCode }}"> {{ program.darsDegreeProgramCode }} </mat-radio-button> </mat-radio-group> @@ -52,20 +51,20 @@ <!-- If what-if audit was selected in #1 --> <mat-form-field *ngIf="newAuditForm.value.formArray[0].auditType === 'whatIfAudit'" class="audit-program"> <mat-select formControlName="darsInstitution" placeholder="School, College or Population" aria-label="Select School, College or Population" [disableOptionCentering]="true"> - <mat-option value="{{ programOfStudy }}">{{ programOfStudy}}</mat-option> + <mat-option value="{{ programOfStudy }}">{{ programOfStudy }}</mat-option> </mat-select> </mat-form-field> <!-- Show after School, College or Population was selected --> <mat-form-field *ngIf="(newAuditForm.value.formArray[0].auditType === 'whatIfAudit') && (newAuditForm.value.formArray[1].darsInstitution)" class="audit-program"> <mat-select formControlName="darsInstitutionProgram" placeholder="Academic Plan Program" aria-label="Academic Plan Program" [disableOptionCentering]="true"> - <mat-option *ngFor="let program of DARSprograms" value="{{ program.darsDegreeProgramDescription }}">{{ program.darsDegreeProgramDescription }}</mat-option> + <mat-option class="mat-option-long" *ngFor="let program of DARSprograms" value="{{ program.darsDegreeProgramDescription }}">{{ program.darsDegreeProgramDescription | titlecase }}</mat-option> </mat-select> </mat-form-field> <div class="step-buttons-group"> <button mat-button matStepperPrevious color="primary">Back</button> - <button mat-button matStepperNext mat-stroked-button color="primary">Next</button> + <button mat-button matStepperNext mat-stroked-button color="primary" (click)="getPlansList()">Next</button> </div> </mat-step> @@ -74,54 +73,64 @@ <mat-form-field class="audit-settings-option"> <mat-label>Honors Degree Options</mat-label> <mat-select formControlName="honors" placeholder="Honors Degree Option" aria-label="Honors Degree Options" [disableOptionCentering]="true"> - <mat-option *ngFor="let honor of honorsOptions" value="">{{ honor.darsHonorsOptionDescription }}</mat-option> + <mat-option *ngFor="let honor of honorsOptions" value="{{ honor.darsHonorsOptionDescription }}">{{ honor.darsHonorsOptionDescription }}</mat-option> </mat-select> </mat-form-field> <mat-form-field class="audit-settings-option"> - <mat-label>Include Courses From</mat-label> - <mat-select formControlName="includeCoursesFrom" placeholder="Include Courses From" aria-label="Include Courses From" [disableOptionCentering]="true"> - <mat-option value="">Previous, current, future, and planned terms</mat-option> - </mat-select> - </mat-form-field> - - <p style="margin-top: 12px;"><strong>Run against which degree plan?</strong></p> - <mat-form-field class="audit-settings-option"> - <mat-label>Degree Plan</mat-label> - <mat-select formControlName="runAgainst" placeholder="Degree Plan" aria-label="Degree Plan" [disableOptionCentering]="true"> - <mat-option value="">Engineering</mat-option> - </mat-select> - </mat-form-field> + <mat-label>Include Courses From</mat-label> + <mat-select formControlName="includeCoursesFrom" placeholder="Include Courses From" aria-label="Include Courses From" [disableOptionCentering]="true"> + <mat-option value="future">Previous, current, future, and planned terms</mat-option> + <mat-option value="future">Previous, current, future</mat-option> + <mat-option value="current">Previous, current</mat-option> + <mat-option value="previous">Previous</mat-option> + </mat-select> + </mat-form-field> - <div class="step-buttons-group"> - <button mat-button matStepperPrevious color="primary">Back</button> - <button mat-button matStepperNext mat-stroked-button color="primary">Next</button> - </div> + <p style="margin-top: 12px;"><strong>Run against which degree plan?</strong></p> + <mat-form-field class="audit-settings-option"> + <mat-label>Degree Plan</mat-label> + <mat-select formControlName="runAgainst" placeholder="Degree Plan" aria-label="Degree Plan" [disableOptionCentering]="true"> + <mat-option *ngFor="let degreePlan of (degreePlans$ | async)" value="{{ degreePlan.roadmapId }}">{{ degreePlan.name }}</mat-option> + </mat-select> + </mat-form-field> + <div class="step-buttons-group"> + <button mat-button matStepperPrevious color="primary">Back</button> + <button mat-button matStepperNext mat-stroked-button color="primary" (click)="getCoursesList(newAuditForm.value.formArray[2].runAgainst)">Next</button> + </div> </mat-step> <mat-step class="audit-step" formGroupName="3" [stepControl]="formArray?.get([3])"> <ng-template matStepLabel>Select credits</ng-template> <p>To provide more accurate audit, specify the number of credits you planto make in the following course(s):</p> - <!-- If no variable credits were found, show the message --> - <!-- <p>No variable credits found.The audit is ready to be run.</p> --> - <div fxLayout="row" fxFlex="100" style="margin-top: 18px;"> - <div fxLayoutAlign="start center" fxFlex="80"> - <span>Spring 2020: BIO 151 <br /> Introductory biology</span> - </div> - <div fxLayoutAlign="end center" fxFlex="20"> - <mat-form-field id="audit-credits-selector"> - <mat-select formControlName="credits" placeholder="" aria-label="Number of credits" [disableOptionCentering]="true"> - <mat-option value=""></mat-option> - </mat-select> - </mat-form-field> - </div> + + <p *ngIf="!hasVariableCredits && isLoaded"><strong>No variable credits found.The audit is ready to be run.</strong></p> + <div class="course-items-loading"> + <mat-progress-spinner *ngIf="!isLoaded" + mode="indeterminate" + diameter="24"> + </mat-progress-spinner> </div> - <div class="step-buttons-group"> - <button mat-button matStepperPrevious color="primary">Back</button> - <button mat-button mat-raised-button color="primary" (click)="runDARSAudit();">Run Audit</button> - <!-- <button mat-button (click)="stepper.reset()" mat-stroked-button color="primary">Reset</button> --> + + <div *ngFor="let course of courses"> + <div *ngIf="hasVariableCredits" fxLayout="row" fxFlex="100" style="margin-top: 18px;"> + <div fxLayoutAlign="start center" fxFlex="80"> + <span>{{ course.termCode | getTermDescription }}: {{ course.subjectDescription }} {{ course.catalogNumber }} <br /> {{ course.title }}</span> + </div> + <div fxLayoutAlign="end center" fxFlex="20"> + <mat-form-field id="audit-credits-selector"> + <mat-select formControlName="credits" placeholder="" aria-label="Number of credits" [disableOptionCentering]="true"> + <mat-option class="mat-option-center" *ngFor="let credit of course.creditsRange" value="{{ credit }}">{{ credit }}</mat-option> + </mat-select> + </mat-form-field> + </div> </div> - </mat-step> - </mat-vertical-stepper> - </form> + </div> + <div class="step-buttons-group"> + <button mat-button matStepperPrevious color="primary">Back</button> + <button mat-button mat-raised-button color="primary" (click)="runDARSAudit();">Run Audit</button> + </div> + </mat-step> + </mat-vertical-stepper> + </form> </div> </mat-dialog-content> diff --git a/src/app/dars/new-audit-options/new-audit-options.component.scss b/src/app/dars/new-audit-options/new-audit-options.component.scss index 8f6ce71..00bc18b 100644 --- a/src/app/dars/new-audit-options/new-audit-options.component.scss +++ b/src/app/dars/new-audit-options/new-audit-options.component.scss @@ -30,3 +30,10 @@ text-transform: uppercase; } } + +.course-items-loading { + mat-progress-spinner { + position: relative; + top: 8px; + } +} diff --git a/src/app/dars/new-audit-options/new-audit-options.component.ts b/src/app/dars/new-audit-options/new-audit-options.component.ts index 50890d9..72f74fd 100644 --- a/src/app/dars/new-audit-options/new-audit-options.component.ts +++ b/src/app/dars/new-audit-options/new-audit-options.component.ts @@ -1,8 +1,14 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Inject } from '@angular/core'; import { MatDialogRef, MatSnackBar } from '@angular/material'; import { DarsApiService } from '../services/api.service'; import { DegreeProgram } from '../models/degree-program'; import { StudentDegreeProgram } from '../models/student-degree-program'; +import { Observable } from 'rxjs'; +import { Store, select } from '@ngrx/store'; +import { GlobalState } from '@app/core/state'; +import * as selectors from '../store/selectors'; +import { DARSState } from '../store/state'; +import { MAT_DIALOG_DATA } from '@angular/material'; import { FormBuilder, FormGroup, @@ -25,7 +31,13 @@ export class NewAuditOptionsComponent implements OnInit { public studentDegreeProgram: StudentDegreeProgram[]; public DARSprograms: any; public honorsOptions: any; - + public courses: any; + public variableCreditCourses: any; + public degreePlans$: Observable<DARSState['degreePlans']>; + public hasVariableCredits: boolean; + public creditsRange: any[]; + public isLoaded: boolean; + public selectedAuditType: string; get formArray(): AbstractControl | null { return this.newAuditForm.get('formArray'); } @@ -35,9 +47,21 @@ export class NewAuditOptionsComponent implements OnInit { private dialogRef: MatDialogRef<NewAuditOptionsComponent>, private snackBar: MatSnackBar, private api: DarsApiService, - ) {} + private store: Store<GlobalState>, + @Inject(MAT_DIALOG_DATA) + data: { + selectedAuditType: string; + }, + ) { + this.selectedAuditType = data.selectedAuditType; + } ngOnInit() { + // Get student degree programs + this.api.getStudentDegreePrograms().subscribe(studentDegreeProgram => { + this.studentDegreeProgram = studentDegreeProgram; + }); + this.api.getStaticData().subscribe(degreePrograms => { this.degreePrograms = degreePrograms; this.honorsOptions = []; @@ -61,7 +85,7 @@ export class NewAuditOptionsComponent implements OnInit { this.newAuditForm = this.fb.group({ formArray: this.fb.array([ this.fb.group({ - auditType: new FormControl('declaredMajorAudit'), + auditType: new FormControl(''), }), this.fb.group({ darsDegreeProgram: new FormControl(''), @@ -69,8 +93,8 @@ export class NewAuditOptionsComponent implements OnInit { darsInstitutionProgram: new FormControl(''), }), this.fb.group({ - honors: new FormControl(''), - includeCoursesFrom: new FormControl(''), + honors: new FormControl('Keep current status'), + includeCoursesFrom: new FormControl('future'), runAgainst: new FormControl(''), }), this.fb.group({ @@ -80,6 +104,31 @@ export class NewAuditOptionsComponent implements OnInit { }); } + public getPlansList() { + this.degreePlans$ = this.store.pipe(select(selectors.degreePlans)); + } + + public getCoursesList(roadmapId) { + this.isLoaded = false; + + this.api.getAllCourses(roadmapId).subscribe(courses => { + this.courses = courses; + this.creditsRange = []; + this.courses ? (this.isLoaded = true) : (this.isLoaded = false); + this.courses.forEach(function(course) { + course.creditMin === course.creditMax + ? (this.hasVariableCredits = false) + : (this.hasVariableCredits = true); + + // Build creditsRange array + course.creditsRange = []; + for (let i = course.creditMin; i <= course.creditMax; i++) { + course.creditsRange.push(i); + } + }, this); + }); + } + public runDARSAudit() { const { auditType, diff --git a/src/app/dars/services/api.service.ts b/src/app/dars/services/api.service.ts index 719e1eb..bcacb62 100644 --- a/src/app/dars/services/api.service.ts +++ b/src/app/dars/services/api.service.ts @@ -6,8 +6,7 @@ import { AuditMetadata } from '../models/audit-metadata'; import { StudentDegreeProgram } from '../models/student-degree-program'; import { environment } from './../../../environments/environment'; import { Audit } from '../models/audit/audit'; -import { map } from 'rxjs/operators'; - +import { CourseBase } from '@app/core/models/course'; const auditResponse: any = require('../../../assets/mock-data/audit-response.json'); const degreeProgramsResponse: any = require('../../../assets/mock-data/degreeprograms-response.json'); @@ -24,11 +23,7 @@ export class DarsApiService { /** * Get all degree programs, honors, and institution data. * - * All the data for institutions, honors, and degree programs is static. - * The backend is going to cache all this data in S3 and create a single - * endpoint for us to hit and get all of it! */ - public getStaticData(): Observable<DegreeProgram[]> { // Prevents errors locally if (environment.production) { @@ -41,7 +36,20 @@ export class DarsApiService { } /** - * Get a students degree programs. + * + * Get courses + */ + public getAllCourses( + roadmapId: number, + ): Observable<{ termCode: string; courses: CourseBase[] }[]> { + return this.http.get<{ termCode: string; courses: CourseBase[] }[]>( + `${environment.apiPlannerUrl}/degreePlan/${roadmapId}/courses`, + HTTP_OPTIONS, + ); + } + + /** + * Get students degree programs. */ public getStudentDegreePrograms(): Observable<StudentDegreeProgram[]> { const url = `${environment.apiDarsUrl}/studentplans`; diff --git a/src/assets/sass/general.scss b/src/assets/sass/general.scss index 6a2a640..146bf04 100644 --- a/src/assets/sass/general.scss +++ b/src/assets/sass/general.scss @@ -298,7 +298,7 @@ body { overflow: hidden; } -// Form styles +// Form fields styles .audit-radio-button { .mat-radio-label { @@ -324,6 +324,20 @@ body { } } +.mat-option-long { + overflow-x: scroll !important; + .mat-option-text { + overflow: visible; + padding-right: 18px; + } +} + +.mat-option-center { + .mat-option-text { + text-align: center; + } +} + .mat-radio-outer-circle { border-color: #0479a8 !important; } -- GitLab