Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Learning paths: Add explanation view for learning path users #9392

Merged
merged 6 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ public class LearningPath extends DomainObject {
@Column(name = "progress")
private int progress;

/**
* flag indicating if a student started the learning path
*/
@Column(name = "started_by_student")
private boolean startedByStudent = false;
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we move this to the future LearnerProfile, that is stored once per student? Or should they get the explanation in each course?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense for the future. @N0W0RK can you add that point to your backlog?


@ManyToOne
@JoinColumn(name = "user_id")
private User user;
Expand Down Expand Up @@ -89,8 +95,16 @@ public void removeCompetency(CourseCompetency competency) {
this.competencies.remove(competency);
}

public boolean isStartedByStudent() {
return startedByStudent;
}

public void setStartedByStudent(boolean startedByStudent) {
this.startedByStudent = startedByStudent;
}

@Override
public String toString() {
return "LearningPath{" + "id=" + getId() + ", user=" + user + ", course=" + course + ", competencies=" + competencies + '}';
return "LearningPath{" + "id=" + getId() + ", user=" + user + ", course=" + course + ", competencies=" + competencies + ", startedByStudent=" + startedByStudent + "}";
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package de.tum.cit.aet.artemis.atlas.dto;

import com.fasterxml.jackson.annotation.JsonInclude;

import de.tum.cit.aet.artemis.atlas.domain.competency.LearningPath;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public record LearningPathDTO(long id, boolean startedByStudent, int progress) {

public static LearningPathDTO of(LearningPath learningPath) {
return new LearningPathDTO(learningPath.getId(), learningPath.isStartedByStudent(), learningPath.getProgress());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.stream.Collectors;

import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.BadRequestException;
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -25,6 +26,7 @@
import de.tum.cit.aet.artemis.atlas.dto.CompetencyGraphEdgeDTO;
import de.tum.cit.aet.artemis.atlas.dto.CompetencyGraphNodeDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathCompetencyGraphDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathHealthDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathInformationDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathNavigationOverviewDTO;
Expand Down Expand Up @@ -243,6 +245,52 @@ private void updateLearningPathProgress(@NotNull LearningPath learningPath) {
log.debug("Updated LearningPath (id={}) for user (id={})", learningPath.getId(), userId);
}

/**
* Get the learning path for the current user in the given course.
*
* @param courseId the id of the course
* @return the learning path of the current user
*/
public LearningPathDTO getLearningPathForCurrentUser(long courseId) {
final var currentUser = userRepository.getUser();
final var learningPath = learningPathRepository.findByCourseIdAndUserIdElseThrow(courseId, currentUser.getId());
return LearningPathDTO.of(learningPath);
}
Comment on lines +254 to +258
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure User Enrollment Verification Before Accessing Learning Path

In the getLearningPathForCurrentUser method, it's important to verify that the current user is enrolled in the specified course before accessing the learning path. This prevents unauthorized access to learning paths of courses the user is not enrolled in.

Apply this diff to add the enrollment check:

 public LearningPathDTO getLearningPathForCurrentUser(long courseId) {
     final var currentUser = userRepository.getUser();
+    courseRepository.checkIfUserIsEnrolledInCourseElseThrow(currentUser, courseId);
     final var learningPath = learningPathRepository.findByCourseIdAndUserIdElseThrow(courseId, currentUser.getId());
     return LearningPathDTO.of(learningPath);
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public LearningPathDTO getLearningPathForCurrentUser(long courseId) {
final var currentUser = userRepository.getUser();
final var learningPath = learningPathRepository.findByCourseIdAndUserIdElseThrow(courseId, currentUser.getId());
return LearningPathDTO.of(learningPath);
}
public LearningPathDTO getLearningPathForCurrentUser(long courseId) {
final var currentUser = userRepository.getUser();
courseRepository.checkIfUserIsEnrolledInCourseElseThrow(currentUser, courseId);
final var learningPath = learningPathRepository.findByCourseIdAndUserIdElseThrow(courseId, currentUser.getId());
return LearningPathDTO.of(learningPath);
}


/**
* Generate a learning path for the current user in the given course.
*
* @param courseId the id of the course
* @return the generated learning path
*/
public LearningPathDTO generateLearningPathForCurrentUser(long courseId) {
final var currentUser = userRepository.getUser();
final var course = courseRepository.findWithEagerCompetenciesAndPrerequisitesByIdElseThrow(courseId);
if (learningPathRepository.findByCourseIdAndUserId(courseId, currentUser.getId()).isPresent()) {
throw new BadRequestException("Learning path already exists.");
}
final var learningPath = generateLearningPathForUser(course, currentUser);
return LearningPathDTO.of(learningPath);
}

/**
* Start the learning path for the current user in the given course.
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
*
* @param learningPathId the id of the learning path
*/
public void startLearningPathForCurrentUser(long learningPathId) {
final var learningPath = learningPathRepository.findByIdElseThrow(learningPathId);
final var currentUser = userRepository.getUser();
if (!learningPath.getUser().equals(currentUser)) {
throw new AccessForbiddenException("You are not allowed to start this learning path.");
}
else if (learningPath.isStartedByStudent()) {
pzdr7 marked this conversation as resolved.
Show resolved Hide resolved
throw new BadRequestException("Learning path already started.");
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
}
learningPath.setStartedByStudent(true);
learningPathRepository.save(learningPath);
}

/**
* Gets the health status of learning paths for the given course.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.springframework.context.annotation.Profile;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
Expand All @@ -28,6 +29,7 @@
import de.tum.cit.aet.artemis.atlas.dto.CompetencyNameDTO;
import de.tum.cit.aet.artemis.atlas.dto.CompetencyProgressForLearningPathDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathCompetencyGraphDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathHealthDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathInformationDTO;
import de.tum.cit.aet.artemis.atlas.dto.LearningPathNavigationDTO;
Expand Down Expand Up @@ -301,19 +303,31 @@ private ResponseEntity<NgxLearningPathDTO> getLearningPathNgx(@PathVariable long
}

/**
* GET courses/:courseId/learning-path-id : Gets the id of the learning path.
* GET courses/:courseId/learning-path/me : Gets the learning path of the current user in the course.
*
* @param courseId the id of the course from which the learning path id should be fetched
* @return the ResponseEntity with status 200 (OK) and with body the id of the learning path
* @param courseId the id of the course for which the learning path should be fetched
* @return the ResponseEntity with status 200 (OK) and with body the learning path
*/
@GetMapping("courses/{courseId}/learning-path-id")
@GetMapping("courses/{courseId}/learning-path/me")
@EnforceAtLeastStudentInCourse
public ResponseEntity<Long> getLearningPathId(@PathVariable long courseId) {
log.debug("REST request to get learning path id for course with id: {}", courseId);
public ResponseEntity<LearningPathDTO> getLearningPathForCurrentUser(@PathVariable long courseId) {
log.debug("REST request to get learning path of current user for course with id: {}", courseId);
courseService.checkLearningPathsEnabledElseThrow(courseId);
User user = userRepository.getUser();
final var learningPath = learningPathRepository.findByCourseIdAndUserIdElseThrow(courseId, user.getId());
return ResponseEntity.ok(learningPath.getId());
return ResponseEntity.ok(learningPathService.getLearningPathForCurrentUser(courseId));
}
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved

/**
* PATCH learning-path/:learningPathId/start : Starts the learning path for the current user.
*
* @param learningPathId the id of the learning path to start
* @return the ResponseEntity with status 204 (NO_CONTENT)
*/
@PatchMapping("learning-path/{learningPathId}/start")
@EnforceAtLeastStudent
public ResponseEntity<Void> startLearningPathForCurrentUser(@PathVariable long learningPathId) {
log.debug("REST request to start learning path with id: {}", learningPathId);
learningPathService.startLearningPathForCurrentUser(learningPathId);
return ResponseEntity.noContent().build();
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand All @@ -324,20 +338,11 @@ public ResponseEntity<Long> getLearningPathId(@PathVariable long courseId) {
*/
@PostMapping("courses/{courseId}/learning-path")
@EnforceAtLeastStudentInCourse
public ResponseEntity<Long> generateLearningPath(@PathVariable long courseId) throws URISyntaxException {
log.debug("REST request to generate learning path for user in course with id: {}", courseId);
public ResponseEntity<LearningPathDTO> generateLearningPathForCurrentUser(@PathVariable long courseId) throws URISyntaxException {
log.debug("REST request to generate learning path for current user in course with id: {}", courseId);
courseService.checkLearningPathsEnabledElseThrow(courseId);

User user = userRepository.getUser();
final var learningPathOptional = learningPathRepository.findByCourseIdAndUserId(courseId, user.getId());

if (learningPathOptional.isPresent()) {
throw new BadRequestException("Learning path already exists.");
}

final var course = courseRepository.findWithEagerCompetenciesAndPrerequisitesByIdElseThrow(courseId);
final var learningPath = learningPathService.generateLearningPathForUser(course, user);
return ResponseEntity.created(new URI("api/learning-path/" + learningPath.getId())).body(learningPath.getId());
final var learningPathDTO = learningPathService.generateLearningPathForCurrentUser(courseId);
return ResponseEntity.created(new URI("api/learning-path/" + learningPathDTO.id())).body(learningPathDTO);
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet id="20240924125742" author="johannes_wt">
<addColumn tableName="learning_path">
<column name="started_by_student" defaultValueBoolean="false" type="boolean">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
</databaseChangeLog>
2 changes: 1 addition & 1 deletion src/main/resources/config/liquibase/master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<include file="classpath:config/liquibase/changelog/20240708144500_changelog.xml" relativeToChangelogFile="false"/>
<include file="classpath:config/liquibase/changelog/20240802091201_changelog.xml" relativeToChangelogFile="false"/>
<include file="classpath:config/liquibase/changelog/20240804144500_changelog.xml" relativeToChangelogFile="false"/>

<include file="classpath:config/liquibase/changelog/20240924125742_changelog.xml" relativeToChangelogFile="false"/>
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
<!-- NOTE: please use the format "YYYYMMDDhhmmss_changelog.xml", i.e. year month day hour minutes seconds and not something else! -->
<!-- we should also stay in a chronological order! -->
<!-- you can use the command 'date '+%Y%m%d%H%M%S'' to get the current date and time in the correct format -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<div class="col learning-path-student-page">
@if (isLearningPathIdLoading()) {
@if (isLearningPathLoading()) {
<div class="row justify-content-center align-items-center h-100">
<div class="spinner-border text-primary" role="status">
<span class="sr-only" jhiTranslate="loading"></span>
</div>
</div>
} @else if (learningPathId()) {
<jhi-learning-path-student-nav [learningPathId]="learningPathId()!" />
} @else if (learningPath() && learningPath()!.startedByStudent) {
<jhi-learning-path-student-nav [learningPathId]="learningPath()!.id" />
<div class="learning-path-student-content">
@if (currentLearningObject()?.type === LearningObjectType.LECTURE) {
<jhi-learning-path-lecture-unit [lectureUnitId]="currentLearningObject()!.id" />
Expand All @@ -27,10 +27,10 @@ <h3 class="mb-3" jhiTranslate="artemisApp.learningPath.completion.title"></h3>
<h3 class="mb-3" jhiTranslate="artemisApp.learningPath.generation.title"></h3>
<div jhiTranslate="artemisApp.learningPath.generation.description"></div>
<button
(click)="generateLearningPath(this.courseId())"
(click)="startLearningPath()"
type="button"
class="mt-4 btn btn-primary"
id="generate-learning-path-button"
id="start-learning-path-button"
jhiTranslate="artemisApp.learningPath.generation.generateButton"
></button>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, effect, inject, signal } from '@angular/core';
import { LearningObjectType } from 'app/entities/competency/learning-path.model';
import { LearningObjectType, LearningPathDTO } from 'app/entities/competency/learning-path.model';
import { map } from 'rxjs';
import { toSignal } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common';
Expand Down Expand Up @@ -32,45 +32,49 @@ import { ArtemisSharedModule } from 'app/shared/shared.module';
export class LearningPathStudentPageComponent {
protected readonly LearningObjectType = LearningObjectType;

private readonly learningApiService: LearningPathApiService = inject(LearningPathApiService);
private readonly learningApiService = inject(LearningPathApiService);
private readonly learningPathNavigationService = inject(LearningPathNavigationService);
private readonly alertService: AlertService = inject(AlertService);
private readonly activatedRoute: ActivatedRoute = inject(ActivatedRoute);
private readonly alertService = inject(AlertService);
private readonly activatedRoute = inject(ActivatedRoute);

readonly isLearningPathIdLoading = signal(false);
readonly learningPathId = signal<number | undefined>(undefined);
readonly isLearningPathLoading = signal(false);
readonly learningPath = signal<LearningPathDTO | undefined>(undefined);
readonly courseId = toSignal(this.activatedRoute.parent!.parent!.params.pipe(map((params) => Number(params.courseId))), { requireSync: true });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid using non-null assertion operators (!).

The use of non-null assertions on this.activatedRoute.parent!.parent! can lead to runtime errors if parent is null or undefined. It's safer to use optional chaining or add null checks to ensure robustness.

Consider updating the code as follows:

readonly courseId = toSignal(
    this.activatedRoute.parent?.parent?.params.pipe(map((params) => Number(params.courseId))),
    { requireSync: true }
);
🧰 Tools
🪛 Biome

[error] 42-42: Forbidden non-null assertion.

Unsafe fix: Replace with optional chain operator ?. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator

(lint/style/noNonNullAssertion)


[error] 42-42: Forbidden non-null assertion.

Unsafe fix: Replace with optional chain operator ?. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator

(lint/style/noNonNullAssertion)

readonly currentLearningObject = this.learningPathNavigationService.currentLearningObject;
readonly isLearningPathNavigationLoading = this.learningPathNavigationService.isLoading;

constructor() {
effect(async () => await this.loadLearningPathId(this.courseId()), { allowSignalWrites: true });
effect(() => this.loadLearningPathId(this.courseId()), { allowSignalWrites: true });
}

private async loadLearningPathId(courseId: number): Promise<void> {
try {
this.isLearningPathIdLoading.set(true);
const learningPathId = await this.learningApiService.getLearningPathId(courseId);
this.learningPathId.set(learningPathId);
this.isLearningPathLoading.set(true);
const learningPath = await this.learningApiService.getLearningPathForCurrentUser(courseId);
this.learningPath.set(learningPath);
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
} catch (error) {
// If learning path does not exist (404) ignore the error
if (!(error instanceof EntityNotFoundError)) {
this.alertService.error(error);
}
} finally {
this.isLearningPathIdLoading.set(false);
this.isLearningPathLoading.set(false);
}
}

async generateLearningPath(courseId: number): Promise<void> {
async startLearningPath(): Promise<void> {
try {
this.isLearningPathIdLoading.set(true);
const learningPathId = await this.learningApiService.generateLearningPath(courseId);
this.learningPathId.set(learningPathId);
this.isLearningPathLoading.set(true);
if (!this.learningPath()) {
const learningPath = await this.learningApiService.generateLearningPathForCurrentUser(this.courseId());
this.learningPath.set(learningPath);
}
await this.learningApiService.startLearningPathForCurrentUser(this.learningPath()!.id);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle potential undefined for this.learningPath().

Using this.learningPath()! assumes that learningPath is not undefined, which might not always be the case. This could result in runtime errors if learningPath is undefined.

Modify the code to include a null check:

const learningPath = this.learningPath();
if (learningPath) {
    await this.learningApiService.startLearningPathForCurrentUser(learningPath.id);
}
🧰 Tools
🪛 Biome

[error] 72-72: Forbidden non-null assertion.

Unsafe fix: Replace with optional chain operator ?. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator

(lint/style/noNonNullAssertion)

this.learningPath.update((learningPath) => ({ ...learningPath!, startedByStudent: true }));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure safe usage of learningPath in the update function.

Inside the update function, using learningPath! assumes that learningPath is not undefined. To prevent potential runtime errors, handle the possibility of learningPath being undefined.

Update the code as follows:

this.learningPath.update((learningPath) =>
    learningPath ? { ...learningPath, startedByStudent: true } : learningPath
);
🧰 Tools
🪛 Biome

[error] 73-73: Forbidden non-null assertion.

(lint/style/noNonNullAssertion)

} catch (error) {
this.alertService.error(error);
} finally {
this.isLearningPathIdLoading.set(false);
this.isLearningPathLoading.set(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,34 @@
): Promise<T> {
return await this.request<T>(HttpMethod.Post, url, { body: body, ...options });
}

/**
* Constructs a `PUT` request that interprets the body as JSON and
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
* returns a Promise of an object of type `T`.
*
* @param url The endpoint URL excluding the base server url (/api).
* @param body The content to include in the body of the request.
* @param options The HTTP options to send with the request.
* @protected
*
* @return An `Promise` of type `Object` (T),
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
*/
protected async patch<T>(
url: string,
body?: any,
options?: {
headers?:
| HttpHeaders
| {
[header: string]: string | string[];
};
params?:
| HttpParams
| {
[param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>;
};
},
): Promise<T> {
return await this.request<T>(HttpMethod.Patch, url, { body: body, ...options });

Check failure on line 153 in src/main/webapp/app/course/learning-paths/services/base-api-http.service.ts

View workflow job for this annotation

GitHub Actions / client-tests

Property 'Patch' does not exist on type 'typeof HttpMethod'.

Check failure on line 153 in src/main/webapp/app/course/learning-paths/services/base-api-http.service.ts

View workflow job for this annotation

GitHub Actions / client-tests-selected

Property 'Patch' does not exist on type 'typeof HttpMethod'.

Check failure on line 153 in src/main/webapp/app/course/learning-paths/services/base-api-http.service.ts

View workflow job for this annotation

GitHub Actions / client-compilation

Property 'Patch' does not exist on type 'typeof HttpMethod'.
}
pzdr7 marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
CompetencyGraphDTO,
LearningObjectType,
LearningPathCompetencyDTO,
LearningPathDTO,
LearningPathNavigationDTO,
LearningPathNavigationObjectDTO,
LearningPathNavigationOverviewDTO,
Expand All @@ -14,8 +15,12 @@ import { BaseApiHttpService } from 'app/course/learning-paths/services/base-api-
providedIn: 'root',
})
export class LearningPathApiService extends BaseApiHttpService {
async getLearningPathId(courseId: number): Promise<number> {
return await this.get<number>(`courses/${courseId}/learning-path-id`);
async getLearningPathForCurrentUser(courseId: number): Promise<LearningPathDTO> {
return await this.get<LearningPathDTO>(`courses/${courseId}/learning-path/me`);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Redundant await in return await statement

In an async function, using return await is redundant because the function automatically returns a Promise. Removing await makes the code more concise without affecting functionality.

You can simplify the code by removing await:

-        return await this.get<LearningPathDTO>(`courses/${courseId}/learning-path/me`);
+        return this.get<LearningPathDTO>(`courses/${courseId}/learning-path/me`);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return await this.get<LearningPathDTO>(`courses/${courseId}/learning-path/me`);
return this.get<LearningPathDTO>(`courses/${courseId}/learning-path/me`);

}

async startLearningPathForCurrentUser(learningPathId: number): Promise<void> {
return await this.patch<void>(`learning-path/${learningPathId}/start`);
pzdr7 marked this conversation as resolved.
Show resolved Hide resolved
}

async getLearningPathNavigation(learningPathId: number): Promise<LearningPathNavigationDTO> {
Expand All @@ -35,8 +40,8 @@ export class LearningPathApiService extends BaseApiHttpService {
return await this.get<LearningPathNavigationDTO>(`learning-path/${learningPathId}/relative-navigation`, { params: params });
}

async generateLearningPath(courseId: number): Promise<number> {
return await this.post<number>(`courses/${courseId}/learning-path`);
async generateLearningPathForCurrentUser(courseId: number): Promise<LearningPathDTO> {
return await this.post<LearningPathDTO>(`courses/${courseId}/learning-path`);
pzdr7 marked this conversation as resolved.
Show resolved Hide resolved
}

async getLearningPathNavigationOverview(learningPathId: number): Promise<LearningPathNavigationOverviewDTO> {
Expand Down
Loading
Loading