Skip to content

Commit

Permalink
N21-1506 extended logic for sharing course across diff. schools
Browse files Browse the repository at this point in the history
  • Loading branch information
GordonNicholasCap committed Nov 22, 2024
1 parent 32aef24 commit 3e4d3ea
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 10 deletions.
2 changes: 2 additions & 0 deletions apps/server/src/modules/board/board.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CollaborativeTextEditorModule } from '@modules/collaborative-text-edito
import { CopyHelperModule } from '@modules/copy-helper';
import { FilesStorageClientModule } from '@modules/files-storage-client';
import { TldrawClientModule } from '@modules/tldraw-client';
import { SchoolExternalToolModule } from '@modules/tool/school-external-tool';
import { ContextExternalToolModule } from '@modules/tool/context-external-tool';
import { UserModule } from '@modules/user';
import { HttpModule } from '@nestjs/axios';
Expand Down Expand Up @@ -41,6 +42,7 @@ import {
LoggerModule,
UserModule,
ContextExternalToolModule,
SchoolExternalToolModule,
HttpModule,
TldrawClientModule,
CqrsModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ export type BoardNodeCopyContextProps = {
sourceStorageLocation: StorageLocation;
targetStorageLocation: StorageLocation;
filesStorageClientAdapterService: FilesStorageClientAdapterService;
targetSchoolId: EntityId;
};

export class BoardNodeCopyContext implements CopyContext {
constructor(private readonly props: BoardNodeCopyContextProps) {}
targetSchoolId: EntityId;

constructor(private readonly props: BoardNodeCopyContextProps) {
this.targetSchoolId = props.targetSchoolId;
}

copyFilesOfParent(sourceParentId: EntityId, targetParentId: EntityId): Promise<CopyFileDto[]> {
return this.props.filesStorageClientAdapterService.copyFilesOfParent({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { ObjectId } from '@mikro-orm/mongodb';
import { CopyElementType, CopyHelperService, CopyStatus, CopyStatusEnum } from '@modules/copy-helper';
import { CopyFileDto } from '@modules/files-storage-client/dto';
import { SchoolExternalToolService } from '@modules/tool/school-external-tool';
import { ContextExternalToolService } from '@modules/tool/context-external-tool';
import { SchoolExternalTool } from '@modules/tool/school-external-tool/domain';
import { ContextExternalTool } from '@modules/tool/context-external-tool/domain';
import { ToolConfig } from '@modules/tool/tool-config';
import { Injectable } from '@nestjs/common';
Expand All @@ -14,6 +16,7 @@ import {
CollaborativeTextEditorElement,
Column,
ColumnBoard,
ContentElementType,
DeletedElement,
DrawingElement,
ExternalToolElement,
Expand All @@ -25,11 +28,13 @@ import {
MediaExternalToolElement,
MediaLine,
RichTextElement,
ROOT_PATH,
SubmissionContainerElement,
SubmissionItem,
} from '../../domain';

export interface CopyContext {
targetSchoolId: EntityId;
copyFilesOfParent(sourceParentId: EntityId, targetParentId: EntityId): Promise<CopyFileDto[]>;
}

Expand All @@ -38,7 +43,8 @@ export class BoardNodeCopyService {
constructor(
private readonly configService: ConfigService<ToolConfig, true>,
private readonly contextExternalToolService: ContextExternalToolService,
private readonly copyHelperService: CopyHelperService
private readonly copyHelperService: CopyHelperService,
private readonly schoolExternalToolService: SchoolExternalToolService
) {}

async copy(boardNode: AnyBoardNode, context: CopyContext): Promise<CopyStatus> {
Expand Down Expand Up @@ -283,9 +289,9 @@ export class BoardNodeCopyService {
return Promise.resolve(result);
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
async copyExternalToolElement(original: ExternalToolElement, context: CopyContext): Promise<CopyStatus> {
const copy = new ExternalToolElement({
let copy: ExternalToolElement | DeletedElement;
copy = new ExternalToolElement({
...original.getProps(),
...this.buildSpecificProps([]),
});
Expand All @@ -295,10 +301,41 @@ export class BoardNodeCopyService {
const linkedTool = await this.contextExternalToolService.findById(original.contextExternalToolId);

if (linkedTool) {
const contextExternalToolCopy: ContextExternalTool =
await this.contextExternalToolService.copyContextExternalTool(linkedTool, copy.id);
const schoolExternalTool: SchoolExternalTool = await this.schoolExternalToolService.findById(
linkedTool.schoolToolRef.schoolToolId
);

if (schoolExternalTool.schoolId !== context.targetSchoolId) {
const correctSchoolExternalTools: SchoolExternalTool[] =
await this.schoolExternalToolService.findSchoolExternalTools({
toolId: schoolExternalTool.toolId,
schoolId: context.targetSchoolId,
});

if (correctSchoolExternalTools.length) {
linkedTool.schoolToolRef.schoolToolId = correctSchoolExternalTools[0].id;
linkedTool.schoolToolRef.schoolId = correctSchoolExternalTools[0].schoolId;
} else {
copy = new DeletedElement({
id: new ObjectId().toHexString(),
path: ROOT_PATH,
level: 0,
position: 0,
children: [],
createdAt: new Date(),
updatedAt: new Date(),
deletedElementType: ContentElementType.EXTERNAL_TOOL,
title: linkedTool.displayName ?? schoolExternalTool.name ?? 'External Tool',
});
}
}

if (copy instanceof ExternalToolElement) {
const contextExternalToolCopy: ContextExternalTool =
await this.contextExternalToolService.copyContextExternalTool(linkedTool, copy.id);

copy.contextExternalToolId = contextExternalToolCopy.id;
copy.contextExternalToolId = contextExternalToolCopy.id;
}

status = CopyStatusEnum.SUCCESS;
} else {
Expand All @@ -310,7 +347,8 @@ export class BoardNodeCopyService {

const result: CopyStatus = {
copyEntity: copy,
type: CopyElementType.EXTERNAL_TOOL_ELEMENT,
type:
copy instanceof ExternalToolElement ? CopyElementType.EXTERNAL_TOOL_ELEMENT : CopyElementType.DELETED_ELEMENT,
status,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export class ColumnBoardCopyService {
targetStorageLocation: StorageLocation.SCHOOL,
userId: props.userId,
filesStorageClientAdapterService: this.filesStorageClientAdapterService,
targetSchoolId: user.schoolId,
});

const copyStatus = await this.boardNodeCopyService.copy(originalBoard, copyContext);
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/modules/learnroom/learnroom.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { RoleModule } from '@modules/role';
import { SchoolModule } from '@modules/school';
import { TaskModule } from '@modules/task';
import { ContextExternalToolModule } from '@modules/tool/context-external-tool';
import { SchoolExternalToolModule } from '@modules/tool/school-external-tool';
import { UserModule } from '@modules/user';
import { forwardRef, Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';
Expand Down Expand Up @@ -50,6 +51,7 @@ import { CommonCartridgeFileValidatorPipe } from './utils';
forwardRef(() => BoardModule),
CopyHelperModule,
ContextExternalToolModule,
SchoolExternalToolModule,
LessonModule,
LoggerModule,
TaskModule,
Expand Down
28 changes: 26 additions & 2 deletions apps/server/src/modules/learnroom/service/course-copy.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { CopyElementType, CopyHelperService, CopyStatus, CopyStatusEnum } from '@modules/copy-helper';
import { ToolContextType } from '@modules/tool/common/enum';
import { SchoolExternalTool } from '@modules/tool/school-external-tool/domain';
import { ContextExternalTool, ContextRef } from '@modules/tool/context-external-tool/domain';
import { SchoolExternalToolService } from '@modules/tool/school-external-tool';
import { ContextExternalToolService } from '@modules/tool/context-external-tool/service';
import { ToolConfig } from '@modules/tool/tool-config';
import { Injectable } from '@nestjs/common';
Expand All @@ -27,7 +29,8 @@ export class CourseCopyService {
private readonly boardCopyService: BoardCopyService,
private readonly copyHelperService: CopyHelperService,
private readonly userRepo: UserRepo,
private readonly contextExternalToolService: ContextExternalToolService
private readonly contextExternalToolService: ContextExternalToolService,
private readonly schoolExternalToolService: SchoolExternalToolService
) {}

async copyCourse({
Expand Down Expand Up @@ -59,7 +62,28 @@ export class CourseCopyService {
await this.contextExternalToolService.findAllByContext(contextRef);

await Promise.all(
contextExternalToolsInContext.map(async (tool: ContextExternalTool): Promise<ContextExternalTool> => {
contextExternalToolsInContext.map(async (tool: ContextExternalTool): Promise<ContextExternalTool | null> => {
const schoolTool = await this.schoolExternalToolService.findById(tool.schoolToolRef.schoolToolId);

if (user.school.id !== schoolTool.schoolId) {
const schoolExternalTool: SchoolExternalTool = await this.schoolExternalToolService.findById(
tool.schoolToolRef.schoolToolId
);

const correctSchoolExternalTools: SchoolExternalTool[] =
await this.schoolExternalToolService.findSchoolExternalTools({
toolId: schoolExternalTool.toolId,
schoolId: user.school.id,
});

if (correctSchoolExternalTools.length) {
tool.schoolToolRef.schoolToolId = correctSchoolExternalTools[0].id;
tool.schoolToolRef.schoolId = correctSchoolExternalTools[0].schoolId;
} else {
return null;
}
}

const copiedTool: ContextExternalTool = await this.contextExternalToolService.copyContextExternalTool(
tool,
courseCopy.id
Expand Down

0 comments on commit 3e4d3ea

Please sign in to comment.