Skip to content
Snippets Groups Projects
Commit 235171e1 authored by Isaac Evavold's avatar Isaac Evavold
Browse files

ROENROLL-1388

parent 415a9154
No related branches found
No related tags found
No related merge requests found
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
<mat-menu #degreePlanMenu="matMenu"> <mat-menu #degreePlanMenu="matMenu">
<button mat-menu-item (click)="onCreatePlanClick()">Create new plan</button> <button mat-menu-item (click)="onCreatePlanClick()">Create new plan</button>
<button mat-menu-item (click)="onRenamePlanClick(degreePlan)">Rename plan</button> <button mat-menu-item (click)="onRenamePlanClick(degreePlan)">Rename plan</button>
<button mat-menu-item (click)="onDeletePlanClick(degreePlan)">Delete plan</button> <button mat-menu-item (click)="onDeletePlanClick(degreePlan)" [disabled]="degreePlan.primary">Delete plan</button>
<button mat-menu-item (click)="onMakePrimayClick(degreePlan)">Make primary</button> <button mat-menu-item (click)="onMakePrimayClick(degreePlan)" [disabled]="degreePlan.primary">Make primary</button>
<hr> <hr>
<button mat-menu-item (click)="onPrintPlanClick(degreePlan)">Print plan</button> <button mat-menu-item (click)="onPrintPlanClick(degreePlan)">Print plan</button>
<button mat-menu-item (click)="onSharePlanClick(degreePlan)">Share plan</button> <button mat-menu-item (click)="onSharePlanClick(degreePlan)">Share plan</button>
......
import { tap } from 'rxjs/operators'; import { tap, withLatestFrom } from 'rxjs/operators';
// Libraries // Libraries
import { OnInit } from '@angular/core'; import { OnInit } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
...@@ -13,6 +13,7 @@ import { MatDialog } from '@angular/material'; ...@@ -13,6 +13,7 @@ import { MatDialog } from '@angular/material';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { MediaMatcher } from '@angular/cdk/layout'; import { MediaMatcher } from '@angular/cdk/layout';
import { filter } from 'rxjs/operators'; import { filter } from 'rxjs/operators';
import { MatSnackBar } from '@angular/material';
// Models // Models
import { GlobalState } from '@app/core/state'; import { GlobalState } from '@app/core/state';
...@@ -34,6 +35,7 @@ import { ...@@ -34,6 +35,7 @@ import {
MakePlanPrimary, MakePlanPrimary,
CreatePlan, CreatePlan,
ChangePlanName, ChangePlanName,
DeletePlan,
} from '@app/degree-planner/store/actions/plan.actions'; } from '@app/degree-planner/store/actions/plan.actions';
import { import {
...@@ -62,6 +64,7 @@ export class DegreePlannerComponent implements OnInit { ...@@ -62,6 +64,7 @@ export class DegreePlannerComponent implements OnInit {
private store: Store<GlobalState>, private store: Store<GlobalState>,
public mediaMatcher: MediaMatcher, public mediaMatcher: MediaMatcher,
public dialog: MatDialog, public dialog: MatDialog,
private snackBar: MatSnackBar,
) { ) {
this.mobileView = mediaMatcher.matchMedia('(max-width: 900px)'); this.mobileView = mediaMatcher.matchMedia('(max-width: 900px)');
} }
...@@ -118,15 +121,44 @@ export class DegreePlannerComponent implements OnInit { ...@@ -118,15 +121,44 @@ export class DegreePlannerComponent implements OnInit {
}); });
} }
public onMakePrimayClick(currentPlan: DegreePlan) { public onMakePrimayClick(_currentPlan: DegreePlan) {
// TODO const data: DialogMode = { mode: 'makePrimary' };
console.warn('onMakePrimayClick'); this.dialog
.open(ModifyPlanDialogComponent, { data })
.afterClosed()
.subscribe((result: { areYouSure: true } | undefined) => {
if (result !== undefined && result.areYouSure === true) {
const action = new MakePlanPrimary();
this.store.dispatch(action);
}
});
} }
public onDeletePlanClick() { public onDeletePlanClick(currentPlan: DegreePlan) {
// TODO if (currentPlan.primary) {
// open confirm dialog this.snackBar.open('The primary degree plan cannot be deleted');
console.log('onDeletePlanClick'); return;
}
const data: DialogMode = { mode: 'delete', name: currentPlan.name };
this.dialog
.open(ModifyPlanDialogComponent, { data })
.afterClosed()
.pipe(withLatestFrom(this.store))
.subscribe(([result, state]) => {
if (typeof result === 'object' && result.areYouSure === true) {
const { roadmapId } = currentPlan;
const deleteAction = new DeletePlan({ roadmapId });
this.store.dispatch(deleteAction);
const primaryPlan = state.degreePlanner.allDegreePlans.find(plan => {
return plan.primary;
}) as DegreePlan;
const newVisibleRoadmapId = primaryPlan.roadmapId;
const switchPlanAction = new SwitchPlan({ newVisibleRoadmapId });
this.store.dispatch(switchPlanAction);
}
});
} }
public onPrintPlanClick() { public onPrintPlanClick() {
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
<mat-toolbar color="primary" class="dialog-toolbar"> <mat-toolbar color="primary" class="dialog-toolbar">
<span class="dialog-toolbar-title" [ngSwitch]="data.mode"> <span class="dialog-toolbar-title" [ngSwitch]="data.mode">
<span *ngSwitchCase="'makePrimary'">Set as the primary plan</span>
<span *ngSwitchCase="'delete'">Delete plan</span>
<span *ngSwitchCase="'rename'">Rename plan</span> <span *ngSwitchCase="'rename'">Rename plan</span>
<span *ngSwitchCase="'create'">Create plan</span> <span *ngSwitchCase="'create'">Create plan</span>
</span> </span>
...@@ -17,6 +19,12 @@ ...@@ -17,6 +19,12 @@
<mat-dialog-content class="mat-typography dialog-with-toolbar"> <mat-dialog-content class="mat-typography dialog-with-toolbar">
<ng-container [ngSwitch]="data.mode"> <ng-container [ngSwitch]="data.mode">
<div class="delete-plan-content" *ngSwitchCase="'delete'">
<mat-dialog-content>
<p>Are you sure you want to delete the degree plan named <strong>{{data.name}}</strong>?</p>
</mat-dialog-content>
</div>
<div class="rename-plan-content" *ngSwitchCase="'rename'"> <div class="rename-plan-content" *ngSwitchCase="'rename'">
<mat-dialog-content [formGroup]="form"> <mat-dialog-content [formGroup]="form">
<mat-form-field class="form-field-stretch"> <mat-form-field class="form-field-stretch">
...@@ -41,6 +49,8 @@ ...@@ -41,6 +49,8 @@
<button mat-rasied-button class="btn-primary mat-button" [disabled]="form.invalid" (click)="onSubmit()"> <button mat-rasied-button class="btn-primary mat-button" [disabled]="form.invalid" (click)="onSubmit()">
<ng-container [ngSwitch]="data.mode"> <ng-container [ngSwitch]="data.mode">
<span *ngSwitchCase="'makePrimary'">Set as the primary plan</span>
<span *ngSwitchCase="'delete'">Delete this plan</span>
<span *ngSwitchCase="'rename'">Rename plan</span> <span *ngSwitchCase="'rename'">Rename plan</span>
<span *ngSwitchCase="'create'">Create plan</span> <span *ngSwitchCase="'create'">Create plan</span>
</ng-container> </ng-container>
......
...@@ -3,6 +3,8 @@ import { Component, Input, Inject } from '@angular/core'; ...@@ -3,6 +3,8 @@ import { Component, Input, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
export type DialogMode = export type DialogMode =
| { mode: 'makePrimary' }
| { mode: 'delete'; name: string }
| { mode: 'rename'; oldName: string } | { mode: 'rename'; oldName: string }
| { mode: 'create' }; | { mode: 'create' };
...@@ -18,19 +20,28 @@ export class ModifyPlanDialogComponent { ...@@ -18,19 +20,28 @@ export class ModifyPlanDialogComponent {
@Inject(MAT_DIALOG_DATA) public data: DialogMode, @Inject(MAT_DIALOG_DATA) public data: DialogMode,
) { ) {
const initialName = this.data.mode === 'rename' ? this.data.oldName : ''; const initialName = this.data.mode === 'rename' ? this.data.oldName : '';
this.form = new FormGroup({ if (this.data.mode === 'rename' || this.data.mode === 'create') {
planName: new FormControl(initialName, Validators.required), this.form = new FormGroup({
}); planName: new FormControl(initialName, Validators.required),
});
} else {
this.form = new FormGroup({});
}
} }
onSubmit() { onSubmit() {
switch (this.data.mode) { switch (this.data.mode) {
case 'rename': case 'makePrimary':
this.dialogRef.close({ name: `${this.form.value.planName}` }); case 'delete': {
this.dialogRef.close({ areYouSure: true });
break; break;
case 'create': }
this.dialogRef.close({ name: `${this.form.value.planName}` }); case 'rename':
case 'create': {
const name = `${this.form.value.planName}`;
this.dialogRef.close({ name });
break; break;
}
default: default:
this.dialogRef.close(); this.dialogRef.close();
} }
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
<div> <div>
<button mat-button class="sidenav-link-btn"><i class="material-icons">print</i>Print</button> <button mat-button class="sidenav-link-btn"><i class="material-icons">print</i>Print</button>
<button mat-button class="sidenav-link-btn"><i class="material-icons">email</i> Share Plan</button> <button mat-button class="sidenav-link-btn"><i class="material-icons">email</i> Share Plan</button>
<button mat-button class="sidenav-link-btn"><i class="material-icons">add_box</i> Add Degree Plan</button> <button mat-button class="sidenav-link-btn" (click)="addDegreePlan()"><i class="material-icons">add_box</i> Add Degree Plan</button>
<button mat-button class="sidenav-link-btn" (click)="addAcademicYear()"><i class="material-icons">add_box</i> Add Academic Year</button> <button mat-button class="sidenav-link-btn" (click)="addAcademicYear()"><i class="material-icons">add_box</i> Add Academic Year</button>
</div> </div>
</mat-expansion-panel> </mat-expansion-panel>
</div> </div>
\ No newline at end of file
// Libraries // Libraries
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { MatDialog } from '@angular/material';
// State management // State management
import { GlobalState } from '@app/core/state'; import { GlobalState } from '@app/core/state';
import { AddAcademicYearRequest } from '@app/degree-planner/store/actions/addAcademicYear.actions'; import { AddAcademicYearRequest } from '@app/degree-planner/store/actions/addAcademicYear.actions';
import {
ModifyPlanDialogComponent,
DialogMode,
} from '@app/degree-planner/dialogs/modify-plan-dialog/modify-plan-dialog.component';
import { CreatePlan } from '@app/degree-planner/store/actions/plan.actions';
@Component({ @Component({
selector: 'cse-sidenav-menu-item', selector: 'cse-sidenav-menu-item',
templateUrl: './sidenav-menu-item.component.html', templateUrl: './sidenav-menu-item.component.html',
styleUrls: ['./sidenav-menu-item.component.scss'], styleUrls: ['./sidenav-menu-item.component.scss'],
}) })
export class SidenavMenuItemComponent { export class SidenavMenuItemComponent {
constructor(private store: Store<GlobalState>) {} constructor(private store: Store<GlobalState>, public dialog: MatDialog) {}
public addAcademicYear() { public addAcademicYear() {
this.store.dispatch(new AddAcademicYearRequest()); this.store.dispatch(new AddAcademicYearRequest());
} }
public addDegreePlan() {
const data: DialogMode = { mode: 'create' };
this.dialog
.open(ModifyPlanDialogComponent, { data })
.afterClosed()
.subscribe((result: { name: string } | undefined) => {
if (result !== undefined && typeof result.name === 'string') {
const name = result.name;
const action = new CreatePlan({ name, primary: false });
this.store.dispatch(action);
}
});
}
} }
...@@ -12,8 +12,8 @@ import { ...@@ -12,8 +12,8 @@ import {
MakePlanPrimaryFailure, MakePlanPrimaryFailure,
ChangePlanNameSuccess, ChangePlanNameSuccess,
ChangePlanNameFailure, ChangePlanNameFailure,
CreatePlan,
CreatePlanSuccess, CreatePlanSuccess,
DeletePlanSuccess,
} from '@app/degree-planner/store/actions/plan.actions'; } from '@app/degree-planner/store/actions/plan.actions';
import { import {
CourseActionTypes, CourseActionTypes,
...@@ -53,6 +53,7 @@ type SupportedActions = ...@@ -53,6 +53,7 @@ type SupportedActions =
| MakePlanPrimaryFailure | MakePlanPrimaryFailure
| ChangePlanNameSuccess | ChangePlanNameSuccess
| ChangePlanNameFailure | ChangePlanNameFailure
| DeletePlanSuccess
| ToggleAcademicYear; | ToggleAcademicYear;
export function degreePlannerReducer( export function degreePlannerReducer(
...@@ -347,6 +348,13 @@ export function degreePlannerReducer( ...@@ -347,6 +348,13 @@ export function degreePlannerReducer(
}; };
} }
case PlanActionTypes.DeletePlanSuccess: {
const allDegreePlans = state.allDegreePlans.filter(plan => {
return plan.roadmapId !== action.payload.roadmapId;
});
return { ...state, allDegreePlans };
}
/** /**
* It's okay if the action didn't match any of the cases above. If that's * It's okay if the action didn't match any of the cases above. If that's
* the case, just return the existing state object. * the case, just return the existing state object.
......
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