feat(frontend): basisimplementatie leerobject upload-UI

This commit is contained in:
Gerald Schmittinger 2025-05-12 00:47:37 +02:00
parent 6600441b08
commit be1091544c
11 changed files with 311 additions and 40 deletions

View file

@ -2,7 +2,6 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
import { LearningObject } from '../../entities/content/learning-object.entity.js';
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
import { Language } from '@dwengo-1/common/util/language';
import { Teacher } from '../../entities/users/teacher.entity.js';
export class LearningObjectRepository extends DwengoEntityRepository<LearningObject> {
public async findByIdentifier(identifier: LearningObjectIdentifier): Promise<LearningObject | null> {
@ -35,7 +34,11 @@ export class LearningObjectRepository extends DwengoEntityRepository<LearningObj
public async findAllByAdmin(adminUsername: string): Promise<LearningObject[]> {
return this.find(
{ admins: { $contains: adminUsername } },
{
admins: {
username: adminUsername
}
},
{ populate: ['admins'] } // Make sure to load admin relations
);
}

View file

@ -9,7 +9,6 @@ import {
} from '@dwengo-1/common/interfaces/learning-content';
import {getLearningObjectRepository, getTeacherRepository} from "../../data/repositories";
import {processLearningObjectZip} from "./learning-object-zip-processing-service";
import {BadRequestException} from "../../exceptions/bad-request-exception";
import {LearningObject} from "../../entities/content/learning-object.entity";
function getProvider(id: LearningObjectIdentifierDTO): LearningObjectProvider {
@ -67,7 +66,6 @@ const learningObjectService = {
const learningObjectRepository = getLearningObjectRepository();
const learningObject = await processLearningObjectZip(learningObjectPath);
console.log(learningObject);
if (!learningObject.hruid.startsWith(getEnvVar(envVars.UserContentPrefix))) {
learningObject.hruid = getEnvVar(envVars.UserContentPrefix) + learningObject.hruid;
}
@ -75,10 +73,10 @@ const learningObjectService = {
// Lookup the admin teachers based on their usernames and add them to the admins of the learning object.
const teacherRepo = getTeacherRepository();
const adminTeachers = await Promise.all(
admins.map(it => teacherRepo.findByUsername(it))
admins.map(async it => teacherRepo.findByUsername(it))
);
adminTeachers.forEach(it => {
if (it != null) {
if (it !== null) {
learningObject.admins.add(it);
}
});

View file

@ -4,6 +4,7 @@ import {LearningObject} from "../../entities/content/learning-object.entity";
import {getAttachmentRepository, getLearningObjectRepository} from "../../data/repositories";
import {BadRequestException} from "../../exceptions/bad-request-exception";
import {LearningObjectMetadata} from "@dwengo-1/common/dist/interfaces/learning-content";
import { ReturnValue } from '../../entities/content/return-value.entity';
const METADATA_PATH_REGEX = /.*[/^]metadata\.json$/;
const CONTENT_PATH_REGEX = /.*[/^]content\.[a-zA-Z]*$/;
@ -13,33 +14,38 @@ const CONTENT_PATH_REGEX = /.*[/^]content\.[a-zA-Z]*$/;
* @param filePath Path of the zip file to process.
*/
export async function processLearningObjectZip(filePath: string): Promise<LearningObject> {
const learningObjectRepo = getLearningObjectRepository();
const attachmentRepo = getAttachmentRepository();
let zip: unzipper.CentralDirectory;
try {
zip = await unzipper.Open.file(filePath);
} catch(_: unknown) {
throw new BadRequestException("invalid_zip");
}
const zip = await unzipper.Open.file(filePath);
let metadata: LearningObjectMetadata | undefined = undefined;
const attachments: {name: string, content: Buffer}[] = [];
let content: Buffer | undefined = undefined;
if (zip.files.length == 0) {
if (zip.files.length === 0) {
throw new BadRequestException("empty_zip")
}
for (const file of zip.files) {
if (file.type !== "Directory") {
if (METADATA_PATH_REGEX.test(file.path)) {
metadata = await processMetadataJson(file);
} else if (CONTENT_PATH_REGEX.test(file.path)) {
content = await processFile(file);
} else {
attachments.push({
name: file.path,
content: await processFile(file)
});
await Promise.all(
zip.files.map(async file => {
if (file.type !== "Directory") {
if (METADATA_PATH_REGEX.test(file.path)) {
metadata = await processMetadataJson(file);
} else if (CONTENT_PATH_REGEX.test(file.path)) {
content = await processFile(file);
} else {
attachments.push({
name: file.path,
content: await processFile(file)
});
}
}
}
}
})
);
if (!metadata) {
throw new BadRequestException("missing_metadata");
@ -49,20 +55,30 @@ export async function processLearningObjectZip(filePath: string): Promise<Learni
}
const learningObject = createLearningObject(metadata, content, attachments);
return learningObject;
}
function createLearningObject(
metadata: LearningObjectMetadata, content: Buffer, attachments: { name: string; content: Buffer; }[]
): LearningObject {
const learningObjectRepo = getLearningObjectRepository();
const attachmentRepo = getAttachmentRepository();
const learningObject = learningObjectRepo.create({
admins: [],
available: metadata.available ?? true,
content: content,
contentType: metadata.content_type,
copyright: metadata.copyright,
description: metadata.description,
educationalGoals: metadata.educational_goals,
copyright: metadata.copyright ?? "",
description: metadata.description ?? "",
educationalGoals: metadata.educational_goals ?? [],
hruid: metadata.hruid,
keywords: metadata.keywords,
language: metadata.language,
license: "",
returnValue: metadata.return_value,
skosConcepts: metadata.skos_concepts,
license: metadata.license ?? "",
returnValue: metadata.return_value ?? new ReturnValue(),
skosConcepts: metadata.skos_concepts ?? [],
teacherExclusive: metadata.teacher_exclusive,
title: metadata.title,
version: metadata.version
@ -72,9 +88,8 @@ export async function processLearningObjectZip(filePath: string): Promise<Learni
content: it.content,
mimeType: mime.lookup(it.name) || "text/plain",
learningObject
}))
attachmentEntities.forEach(it => learningObject.attachments.add(it));
}));
attachmentEntities.forEach(it => { learningObject.attachments.add(it); });
return learningObject;
}