diff --git a/backend/src/services/learning-paths/database-learning-path-provider.ts b/backend/src/services/learning-paths/database-learning-path-provider.ts index fe05dda1..eb980fa1 100644 --- a/backend/src/services/learning-paths/database-learning-path-provider.ts +++ b/backend/src/services/learning-paths/database-learning-path-provider.ts @@ -4,7 +4,7 @@ import { getLearningPathRepository } from '../../data/repositories.js'; import learningObjectService from '../learning-objects/learning-object-service.js'; import { LearningPathNode } from '../../entities/content/learning-path-node.entity.js'; import { LearningPathTransition } from '../../entities/content/learning-path-transition.entity.js'; -import { getLastSubmissionForGroup, isTransitionPossible } from './learning-path-personalization-util.js'; +import { getLastSubmissionForGroup, idFromLearningPathNode, isTransitionPossible } from './learning-path-personalization-util.js'; import { FilteredLearningObject, LearningObjectNode, @@ -95,7 +95,7 @@ async function convertNode( personalizedFor: Group | undefined, nodesToLearningObjects: Map ): Promise { - const lastSubmission = personalizedFor ? await getLastSubmissionForGroup(node, personalizedFor) : null; + const lastSubmission = personalizedFor ? await getLastSubmissionForGroup(idFromLearningPathNode(node), personalizedFor) : null; const transitions = node.transitions .filter( (trans) => diff --git a/backend/src/services/learning-paths/dwengo-api-learning-path-provider.ts b/backend/src/services/learning-paths/dwengo-api-learning-path-provider.ts index 110cd570..461ba7e8 100644 --- a/backend/src/services/learning-paths/dwengo-api-learning-path-provider.ts +++ b/backend/src/services/learning-paths/dwengo-api-learning-path-provider.ts @@ -3,11 +3,33 @@ import { DWENGO_API_BASE } from '../../config.js'; import { LearningPathProvider } from './learning-path-provider.js'; import { getLogger, Logger } from '../../logging/initalize.js'; import { LearningPath, LearningPathResponse } from '@dwengo-1/common/interfaces/learning-content'; +import { Group } from '../../entities/assignments/group.entity.js'; +import { getLastSubmissionForGroup, idFromLearningObjectNode } from './learning-path-personalization-util.js'; const logger: Logger = getLogger(); +/** + * Adds progress information to the learning path. Modifies the learning path in-place. + * @param learningPath The learning path to add progress to. + * @param personalizedFor The group whose progress should be shown. + * @returns the modified learning path. + */ +async function addProgressToLearningPath(learningPath: LearningPath, personalizedFor: Group): Promise { + await Promise.all( + learningPath.nodes.map(async node => { + const lastSubmission = personalizedFor ? await getLastSubmissionForGroup(idFromLearningObjectNode(node), personalizedFor) : null + node.done = Boolean(lastSubmission); + }) + ); + + learningPath.num_nodes = learningPath.nodes.length; + learningPath.num_nodes_left = learningPath.nodes.filter(it => !it.done).length; + + return learningPath; +} + const dwengoApiLearningPathProvider: LearningPathProvider = { - async fetchLearningPaths(hruids: string[], language: string, source: string): Promise { + async fetchLearningPaths(hruids: string[], language: string, source: string, personalizedFor: Group): Promise { if (hruids.length === 0) { return { success: false, @@ -32,17 +54,29 @@ const dwengoApiLearningPathProvider: LearningPathProvider = { }; } + await Promise.all( + learningPaths?.map(async it => addProgressToLearningPath(it, personalizedFor)) + ); + return { success: true, source, data: learningPaths, }; }, - async searchLearningPaths(query: string, language: string): Promise { + async searchLearningPaths(query: string, language: string, personalizedFor: Group): Promise { const apiUrl = `${DWENGO_API_BASE}/learningPath/search`; const params = { all: query, language }; const searchResults = await fetchWithLogging(apiUrl, `Search learning paths with query "${query}"`, { params }); + + if (searchResults) { + await Promise.all( + searchResults?.map(async it => addProgressToLearningPath(it, personalizedFor)) + ); + } + + return searchResults ?? []; }, }; diff --git a/backend/src/services/learning-paths/learning-path-personalization-util.ts b/backend/src/services/learning-paths/learning-path-personalization-util.ts index a10d5ead..ab1f26bf 100644 --- a/backend/src/services/learning-paths/learning-path-personalization-util.ts +++ b/backend/src/services/learning-paths/learning-path-personalization-util.ts @@ -5,18 +5,36 @@ import { getSubmissionRepository } from '../../data/repositories.js'; import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js'; import { LearningPathTransition } from '../../entities/content/learning-path-transition.entity.js'; import { JSONPath } from 'jsonpath-plus'; +import { LearningObjectNode } from '@dwengo-1/common/interfaces/learning-content'; /** * Returns the last submission for the learning object associated with the given node and for the group */ -export async function getLastSubmissionForGroup(node: LearningPathNode, pathFor: Group): Promise { +export async function getLastSubmissionForGroup(learningObjectId: LearningObjectIdentifier, pathFor: Group): Promise { const submissionRepo = getSubmissionRepository(); - const learningObjectId: LearningObjectIdentifier = { + return await submissionRepo.findMostRecentSubmissionForGroup(learningObjectId, pathFor); +} + +/** + * Creates a LearningObjectIdentifier describing the specified node. + */ +export function idFromLearningObjectNode(node: LearningObjectNode): LearningObjectIdentifier { + return { + hruid: node.learningobject_hruid, + language: node.language, + version: node.version + } +} + +/** + * Creates a LearningObjectIdentifier describing the specified node. + */ +export function idFromLearningPathNode(node: LearningPathNode): LearningObjectIdentifier { + return { hruid: node.learningObjectHruid, language: node.language, - version: node.version, - }; - return await submissionRepo.findMostRecentSubmissionForGroup(learningObjectId, pathFor); + version: node.version + } } /**