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

fix missing saved-for-later titles

parent 6842b782
No related branches found
No related tags found
No related merge requests found
export interface SavedForLaterCourseBase {
id: number | null;
courseId: string;
termCode: string;
topicId: number;
termCode: '0000';
topicId: 0;
subjectCode: string;
title: string;
catalogNumber: string;
courseOrder: number;
courseOrder: 0;
}
export interface SavedForLaterCourse extends SavedForLaterCourseBase {
......
......@@ -43,7 +43,7 @@ export class RemoveCourseConfirmDialogComponent implements OnInit {
console.log(this.course);
const id = this.course.id;
if (typeof id === 'number') {
this.store.dispatch(new RemoveCourseRequest({ id }));
this.store.dispatch(new RemoveCourseRequest({ recordId: id }));
} else {
throw new Error('cannot remove a course that does not have an ID');
}
......
......@@ -4,6 +4,7 @@ import { Store, select } from '@ngrx/store';
import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
import { GlobalState } from '@app/core/state';
import { getSavedForLaterCourses } from '@app/degree-planner/store/selectors';
import { Course } from '@app/core/models/course';
// rsjx / ngrx
import { DegreePlannerState } from '@app/degree-planner/store/state';
......@@ -31,21 +32,29 @@ export class SavedForLaterContainerComponent implements OnInit {
this.courses$ = this.store.pipe(select(getSavedForLaterCourses));
}
drop(event) {
const newContainer = event.container.id;
const previousContainer = event.previousContainer.id;
drop(event: any) {
const newContainerId = event.container.id;
const previousContainerId = event.previousContainer.id;
const fromTerm = previousContainerId.indexOf('term-') === 0;
const fromDifferentContainer = newContainerId !== previousContainerId;
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 to saved for later
if (fromDifferentContainer && fromTerm) {
const course = event.item.data as Course;
const { subjectCode, courseId, id } = event.item.data;
this.store.dispatch(
new AddSavedForLaterRequest({ subjectCode, courseId }),
new AddSavedForLaterRequest({
courseId: course.courseId,
subjectCode: course.subjectCode,
title: course.title,
catalogNumber: course.catalogNumber,
}),
);
this.store.dispatch(
new RemoveCourseRequest({
recordId: course.id as number,
}),
);
this.store.dispatch(new RemoveCourseRequest({ id }));
}
}
}
......@@ -12,7 +12,7 @@ import { ConfigService } from '@app/core/config.service';
// Models
import { Note } from '@app/core/models/note';
import { Term } from '@app/core/models/term';
import { Course, CourseBase, SubjectMapping } from '@app/core/models/course';
import { CourseBase, SubjectMapping } from '@app/core/models/course';
import { DegreePlan } from '@app/core/models/degree-plan';
import { SavedForLaterCourseBase } from '@app/core/models/saved-for-later-course';
......@@ -73,7 +73,7 @@ export class DegreePlannerApiService {
}
public updateCourseTerm(roadmapId, recordId, termCode): Observable<any> {
return this.http.put<Course>(
return this.http.put<CourseBase>(
this.config.apiPlannerUrl +
'/degreePlan/' +
roadmapId +
......@@ -89,7 +89,7 @@ export class DegreePlannerApiService {
const data = {
subjectCode: '104',
termCode: '0000',
matchText: search
matchText: search,
};
return this.http.post('/api/search/v1/autocomplete', data, HTTP_OPTIONS);
......@@ -100,16 +100,16 @@ export class DegreePlannerApiService {
subjectCode: string,
courseId: string,
termCode: string,
): Observable<Course> {
return this.http.post<Course>(
): Observable<CourseBase> {
return this.http.post<CourseBase>(
this.config.apiPlannerUrl + '/degreePlan/' + planId + '/courses',
{ subjectCode, courseId, termCode },
HTTP_OPTIONS,
);
}
public removeCourse(planId: number, recordId: string) {
return this.http.delete(
public removeCourse(planId: number, recordId: number): Observable<void> {
return this.http.delete<void>(
this.config.apiPlannerUrl +
'/degreePlan/' +
planId +
......
......@@ -73,22 +73,36 @@ export class AddCourseResponse implements Action {
export class RemoveCourseRequest implements Action {
public readonly type = PlanActionTypes.RemoveCourseRequest;
constructor(public payload: { id: number }) {}
constructor(public payload: { recordId: number }) {}
}
export class RemoveCourseResponse implements Action {
public readonly type = PlanActionTypes.RemoveCourseResponse;
constructor(public payload: { id: number }) {}
constructor(public payload: { recordId: number }) {}
}
export class AddSavedForLaterRequest implements Action {
public readonly type = PlanActionTypes.AddSavedForLaterReqeust;
constructor(public payload: { subjectCode: string; courseId: string }) {}
constructor(
public payload: {
subjectCode: string;
courseId: string;
title: string;
catalogNumber: string;
},
) {}
}
export class AddSavedForLaterResponse implements Action {
public readonly type = PlanActionTypes.AddSavedForLaterResponse;
constructor(public payload: { subjectCode: string; courseId: string }) {}
constructor(
public payload: {
subjectCode: string;
courseId: string;
title: string;
catalogNumber: string;
},
) {}
}
export class RemoveSavedForLaterRequest implements Action {
......
......@@ -21,12 +21,14 @@ import {
RemoveCourseResponse,
RemoveSavedForLaterResponse,
AddSavedForLaterResponse,
AddCourseRequest,
RemoveCourseRequest,
} from '@app/degree-planner/store/actions/plan.actions';
// Models
import { DegreePlan } from '@app/core/models/degree-plan';
import { PlannedTerm } from '@app/core/models/planned-term';
import { SubjectMapping } from '@app/core/models/course';
import { Course, SubjectMapping, CourseBase } from '@app/core/models/course';
import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
@Injectable()
......@@ -146,7 +148,7 @@ export class DegreePlanEffects {
@Effect()
AddCourse$ = this.actions$.pipe(
ofType<any>(PlanActionTypes.AddCourseRequest),
ofType<AddCourseRequest>(PlanActionTypes.AddCourseRequest),
withLatestFrom(this.store$.select(getDegreePlannerState)),
filter(([_, state]) => state.visibleDegreePlan !== undefined),
......@@ -156,53 +158,48 @@ export class DegreePlanEffects {
// TODO error handle the API calls
const roadmapId = (state.visibleDegreePlan as DegreePlan).roadmapId;
const { subjectCode, termCode, courseId } = action.payload;
return this.api
.addCourse(roadmapId as number, subjectCode, courseId, termCode)
.pipe(
map(response => {
return {
response,
action,
};
}),
);
}),
// Wrap data in an Action for dispatch
map(({ response, action }) => {
// TODO add error handleing
return new AddCourseResponse({ course: response });
const addCourse$ = this.api.addCourse(
roadmapId,
subjectCode,
courseId,
termCode,
);
const courseBaseToCourse$ = addCourse$.pipe(
map<CourseBase, Course>(courseBase => ({
...courseBase,
subject: state.subjects[courseBase.subjectCode],
})),
);
const toSuccessAction$ = courseBaseToCourse$.pipe(
map(course => new AddCourseResponse({ course })),
);
return toSuccessAction$;
}),
);
@Effect()
RemoveCourse$ = this.actions$.pipe(
ofType<any>(PlanActionTypes.RemoveCourseRequest),
ofType<RemoveCourseRequest>(PlanActionTypes.RemoveCourseRequest),
withLatestFrom(this.store$.select(getDegreePlannerState)),
filter(([_, state]) => state.visibleDegreePlan !== undefined),
// Get term data for the degree plan specified by the roadmap ID.
flatMap(([action, state]) => {
// TODO error handle the API calls
const roadmapId = (state.visibleDegreePlan as DegreePlan).roadmapId;
return this.api.removeCourse(roadmapId, action.payload.id).pipe(
map(response => {
return {
response,
action,
};
}),
const recordId = action.payload.recordId;
const removeCourse$ = this.api.removeCourse(roadmapId, recordId);
const toSuccessAction$ = removeCourse$.pipe(
map(() => new RemoveCourseResponse({ recordId })),
);
}),
// Wrap data in an Action for dispatch
map(({ response, action }) => {
if (response === null) {
const { id } = action.payload;
return new RemoveCourseResponse({ id });
}
return;
return toSuccessAction$;
}),
);
......@@ -267,8 +264,7 @@ export class DegreePlanEffects {
// // // Wrap data in an Action for dispatch
map(({ response, action }) => {
if (response === null) {
const { subjectCode, courseId } = action.payload;
return new AddSavedForLaterResponse({ subjectCode, courseId });
return new AddSavedForLaterResponse(action.payload);
}
// return;
return;
......
......@@ -17,6 +17,7 @@ import {
WriteNoteResponse,
DeleteNoteResponse,
} from '@app/degree-planner/store/actions/note.actions';
import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
type SupportedActions =
| InitialPlanLoadResponse
......@@ -169,7 +170,7 @@ export function degreePlannerReducer(
}
case PlanActionTypes.RemoveCourseResponse: {
const { id } = action.payload;
const { recordId: id } = action.payload;
// Create new visibleTerms array
const newVisibleTerms = state.visibleTerms.map(term => {
......@@ -195,22 +196,18 @@ export function degreePlannerReducer(
}
case PlanActionTypes.AddSavedForLaterResponse: {
const { courseId, subjectCode } = action.payload;
// // Create new saved for later array
const newSavedForLater = [
const newSavedForLater: SavedForLaterCourse[] = [
...state.savedForLaterCourses,
// TODO Update this when the API is fixed, the API should be sending a fav course as a response
{
id: null,
courseId,
subjectCode,
subject: state.subjects[subjectCode],
courseId: action.payload.courseId,
termCode: '0000',
topicId: 0,
subjectCode: action.payload.subjectCode,
title: action.payload.title,
catalogNumber: action.payload.catalogNumber,
courseOrder: 0,
catalogNumber: '',
title: '',
termCode: '0000',
subject: state.subjects[action.payload.subjectCode],
},
];
return { ...state, savedForLaterCourses: newSavedForLater };
......
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