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 path: Add discussion section to lecture unit and exercises #9264

Merged
merged 21 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
880d258
add discussion section to learning path items
JohannesWt Sep 1, 2024
58d8a62
import discussion component directly instead of using the router
JohannesWt Sep 1, 2024
fdfbf07
client tests
JohannesWt Sep 2, 2024
8d196d2
fix the problem
JohannesWt Sep 2, 2024
568ff1d
fix discussion-section.component.spec.ts
JohannesWt Sep 2, 2024
a9c0d5d
add client tests to include discussion section
JohannesWt Sep 2, 2024
2992989
add discussion section tests to course-exercise-details.component.spe…
JohannesWt Sep 2, 2024
fe0768c
fix client tests
JohannesWt Sep 2, 2024
c9812df
Merge branch 'develop' into feature/learning-paths/add-discussion-sec…
JohannesWt Sep 2, 2024
54f97f9
code review feedback
JohannesWt Sep 3, 2024
f191c49
Merge branch 'develop' into feature/learning-paths/add-discussion-sec…
JohannesWt Sep 3, 2024
425f2f0
fix merge conflict
JohannesWt Sep 3, 2024
351c416
anirud code review feedback
JohannesWt Sep 3, 2024
57b0873
make discussion-section.component.ts reactive to support changes in l…
JohannesWt Sep 3, 2024
bab16c7
remove unused test of legacy learning-path-lecture-unit-view.componen…
JohannesWt Sep 3, 2024
93296c9
fix client test
JohannesWt Sep 3, 2024
292cd9f
add tests for learning-path-lecture-unit.component.ts
JohannesWt Sep 5, 2024
034f4e5
add tests to course-exercise-details.component.spec.ts
JohannesWt Sep 5, 2024
99e4e91
change private initializer
JohannesWt Sep 5, 2024
5724e89
Update src/test/javascript/spec/component/learning-paths/components/l…
JohannesWt Sep 5, 2024
26b0038
Update src/test/javascript/spec/component/learning-paths/components/l…
JohannesWt Sep 5, 2024
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 @@ -6,21 +6,30 @@
</div>
}
@if (lectureUnit(); as lectureUnit) {
@switch (lectureUnit.type) {
@case (LectureUnitType.VIDEO) {
<jhi-video-unit [lectureUnit]="lectureUnit" (onCompletion)="setLearningObjectCompletion($event)" />
}
@case (LectureUnitType.TEXT) {
<jhi-text-unit [lectureUnit]="lectureUnit" (onCompletion)="setLearningObjectCompletion($event)" />
}
@case (LectureUnitType.ATTACHMENT) {
<jhi-attachment-unit [lectureUnit]="lectureUnit" (onCompletion)="setLearningObjectCompletion($event)" />
}
@case (LectureUnitType.EXERCISE) {
<jhi-exercise-unit [exerciseUnit]="lectureUnit" />
}
@case (LectureUnitType.ONLINE) {
<jhi-online-unit [lectureUnit]="lectureUnit" (onCompletion)="setLearningObjectCompletion($event)" />
<div class="row m-0">
<div class="col p-0">
@switch (lectureUnit.type) {
@case (LectureUnitType.VIDEO) {
<jhi-video-unit [lectureUnit]="lectureUnit" (onCompletion)="setLearningObjectCompletion($event)" />
}
@case (LectureUnitType.TEXT) {
<jhi-text-unit [lectureUnit]="lectureUnit" (onCompletion)="setLearningObjectCompletion($event)" />
}
@case (LectureUnitType.ATTACHMENT) {
<jhi-attachment-unit [lectureUnit]="lectureUnit" (onCompletion)="setLearningObjectCompletion($event)" />
}
@case (LectureUnitType.EXERCISE) {
<jhi-exercise-unit [exerciseUnit]="lectureUnit" />
}
@case (LectureUnitType.ONLINE) {
<jhi-online-unit [lectureUnit]="lectureUnit" (onCompletion)="setLearningObjectCompletion($event)" />
}
}
</div>
@if (isCommunicationEnabled()) {
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
<div class="col-md-auto p-0 ms-2">
<jhi-discussion-section [lecture]="this.lecture()" />
</div>
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
}
}
</div>
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, InputSignal, WritableSignal, effect, inject, input, signal } from '@angular/core';
import { Component, computed, effect, inject, input, signal } from '@angular/core';
import { LectureUnitService } from 'app/lecture/lecture-unit/lecture-unit-management/lectureUnit.service';
import { AlertService } from 'app/core/util/alert.service';
import { LectureUnit, LectureUnitType } from 'app/entities/lecture-unit/lectureUnit.model';
Expand All @@ -11,24 +11,30 @@ import { VideoUnitComponent } from 'app/overview/course-lectures/video-unit/vide
import { TextUnitComponent } from 'app/overview/course-lectures/text-unit/text-unit.component';
import { AttachmentUnitComponent } from 'app/overview/course-lectures/attachment-unit/attachment-unit.component';
import { OnlineUnitComponent } from 'app/overview/course-lectures/online-unit/online-unit.component';
import { isCommunicationEnabled } from 'app/entities/course.model';
import { DiscussionSectionComponent } from 'app/overview/discussion-section/discussion-section.component';

@Component({
selector: 'jhi-learning-path-lecture-unit',
standalone: true,
imports: [ArtemisLectureUnitsModule, ArtemisSharedModule, VideoUnitComponent, TextUnitComponent, AttachmentUnitComponent, OnlineUnitComponent],
imports: [ArtemisLectureUnitsModule, ArtemisSharedModule, VideoUnitComponent, TextUnitComponent, AttachmentUnitComponent, OnlineUnitComponent, DiscussionSectionComponent],
templateUrl: './learning-path-lecture-unit.component.html',
})
export class LearningPathLectureUnitComponent {
protected readonly LectureUnitType = LectureUnitType;

private readonly lectureUnitService: LectureUnitService = inject(LectureUnitService);
private readonly lectureUnitService = inject(LectureUnitService);
private readonly learningPathNavigationService = inject(LearningPathNavigationService);
private readonly alertService: AlertService = inject(AlertService);
private readonly alertService = inject(AlertService);

readonly lectureUnitId: InputSignal<number> = input.required<number>();
readonly isLoading: WritableSignal<boolean> = signal(false);
readonly lectureUnitId = input.required<number>();
readonly isLoading = signal<boolean>(false);
readonly lectureUnit = signal<LectureUnit | undefined>(undefined);

readonly lecture = computed(() => this.lectureUnit()?.lecture);

readonly isCommunicationEnabled = computed(() => isCommunicationEnabled(this.lecture()?.course));

JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
constructor() {
effect(() => this.loadLectureUnit(this.lectureUnitId()), { allowSignalWrites: true });
}
Expand All @@ -46,11 +52,9 @@ export class LearningPathLectureUnitComponent {
}

setLearningObjectCompletion(completionEvent: LectureUnitCompletionEvent): void {
try {
this.lectureUnitService.completeLectureUnit(this.lectureUnit()!.lecture!, completionEvent);
this.lectureUnitService.completeLectureUnit(this.lectureUnit()!.lecture!, completionEvent);
if (this.lectureUnit()?.completed === completionEvent.completed) {
this.learningPathNavigationService.setCurrentLearningObjectCompletion(completionEvent.completed);
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
} catch (error) {
this.alertService.error(error);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,5 @@ export class LearningPathLectureUnitViewComponent {
*/
onChildActivate(instance: DiscussionSectionComponent) {
this.discussionComponent = instance; // save the reference to the component instance
if (this.lecture) {
instance.lecture = this.lecture;
}
}
}
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ const routes: Routes = [
pageTitle: 'overview.learningPath',
},
canActivate: [UserRouteAccessService],
children: [
{
path: '',
pathMatch: 'full',
loadChildren: () => import('app/overview/discussion-section/discussion-section.module').then((m) => m.DiscussionSectionModule),
},
],
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ <h6 class="text-secondary mb-0 lecture-attachment-details">
<!-- LECTURE END -->
<div class="col d-flex flex-grow-1 justify-end" style="max-width: min-content">
@if (lecture && (isCommunicationEnabled(lecture.course) || isMessagingEnabled(lecture.course))) {
<router-outlet class="ms-3" (activate)="onChildActivate($event)" />
<jhi-discussion-section [lecture]="lecture" />
}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { Attachment } from 'app/entities/attachment.model';
import { LectureService } from 'app/lecture/lecture.service';
import { LectureUnit, LectureUnitType } from 'app/entities/lecture-unit/lectureUnit.model';
import { AttachmentUnit } from 'app/entities/lecture-unit/attachmentUnit.model';
import { DiscussionSectionComponent } from 'app/overview/discussion-section/discussion-section.component';
import { onError } from 'app/shared/util/global.utils';
import { finalize, tap } from 'rxjs/operators';
import { AlertService } from 'app/core/util/alert.service';
Expand Down Expand Up @@ -39,7 +38,6 @@ export class CourseLectureDetailsComponent extends AbstractScienceComponent impl
lecture?: Lecture;
isDownloadingLink?: string;
lectureUnits: LectureUnit[] = [];
discussionComponent?: DiscussionSectionComponent;
hasPdfLectureUnit: boolean;

paramsSubscription: Subscription;
Expand Down Expand Up @@ -107,10 +105,6 @@ export class CourseLectureDetailsComponent extends AbstractScienceComponent impl
(unit) => unit.attachment?.link?.split('.').pop()!.toLocaleLowerCase() === 'pdf',
).length > 0;
}
if (this.discussionComponent) {
// We need to manually update the lecture property of the student questions component
this.discussionComponent.lecture = this.lecture;
}
this.endsSameDay = !!this.lecture?.startDate && !!this.lecture.endDate && dayjs(this.lecture.startDate).isSame(this.lecture.endDate, 'day');
},
error: (errorResponse: HttpErrorResponse) => onError(this.alertService, errorResponse),
Expand Down Expand Up @@ -160,18 +154,6 @@ export class CourseLectureDetailsComponent extends AbstractScienceComponent impl
this.lectureUnitService.completeLectureUnit(this.lecture!, event);
}

/**
* This function gets called if the router outlet gets activated. This is
* used only for the DiscussionComponent
* @param instance The component instance
*/
onChildActivate(instance: DiscussionSectionComponent) {
this.discussionComponent = instance; // save the reference to the component instance
if (this.lecture) {
instance.lecture = this.lecture;
}
}

ngOnDestroy() {
this.paramsSubscription?.unsubscribe();
this.profileSubscription?.unsubscribe();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { VideoUnitComponent } from 'app/overview/course-lectures/video-unit/vide
import { TextUnitComponent } from 'app/overview/course-lectures/text-unit/text-unit.component';
import { OnlineUnitComponent } from 'app/overview/course-lectures/online-unit/online-unit.component';
import { AttachmentUnitComponent } from 'app/overview/course-lectures/attachment-unit/attachment-unit.component';
import { DiscussionSectionComponent } from 'app/overview/discussion-section/discussion-section.component';

const routes: Routes = [
{
Expand All @@ -23,13 +24,6 @@ const routes: Routes = [
pageTitle: 'overview.lectures',
},
canActivate: [UserRouteAccessService],
children: [
{
path: '',
pathMatch: 'full',
loadChildren: () => import('../discussion-section/discussion-section.module').then((m) => m.DiscussionSectionModule),
},
],
},
];
@NgModule({
Expand All @@ -45,6 +39,7 @@ const routes: Routes = [
TextUnitComponent,
OnlineUnitComponent,
AttachmentUnitComponent,
DiscussionSectionComponent,
JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
],
declarations: [CourseLectureDetailsComponent],
exports: [CourseLectureDetailsComponent],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { AfterViewInit, Component, ElementRef, OnDestroy, QueryList, ViewChild, ViewChildren, effect, input } from '@angular/core';
import interact from 'interactjs';
import { Exercise } from 'app/entities/exercise.model';
import { Lecture } from 'app/entities/lecture.model';
Expand All @@ -14,17 +14,22 @@ import { CourseDiscussionDirective } from 'app/shared/metis/course-discussion.di
import { FormBuilder } from '@angular/forms';
import { Channel, ChannelDTO } from 'app/entities/metis/conversation/channel.model';
import { ChannelService } from 'app/shared/metis/conversations/channel.service';
import { MetisConversationService } from 'app/shared/metis/metis-conversation.service';
import { ArtemisSharedModule } from 'app/shared/shared.module';
import { ArtemisPlagiarismCasesSharedModule } from 'app/course/plagiarism-cases/shared/plagiarism-cases-shared.module';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';

JohannesWt marked this conversation as resolved.
Show resolved Hide resolved
@Component({
selector: 'jhi-discussion-section',
templateUrl: './discussion-section.component.html',
styleUrls: ['./discussion-section.component.scss'],
imports: [FontAwesomeModule, ArtemisSharedModule, ArtemisPlagiarismCasesSharedModule, InfiniteScrollModule],
standalone: true,
providers: [MetisService],
})
export class DiscussionSectionComponent extends CourseDiscussionDirective implements OnInit, AfterViewInit, OnDestroy {
@Input() exercise?: Exercise;
@Input() lecture?: Lecture;
export class DiscussionSectionComponent extends CourseDiscussionDirective implements AfterViewInit, OnDestroy {
exercise = input<Exercise>();
lecture = input<Lecture>();

@ViewChild(PostCreateEditModalComponent) postCreateEditModal?: PostCreateEditModalComponent;
@ViewChildren('postingThread') messages: QueryList<any>;
Expand Down Expand Up @@ -60,22 +65,18 @@ export class DiscussionSectionComponent extends CourseDiscussionDirective implem
private activatedRoute: ActivatedRoute,
private router: Router,
private formBuilder: FormBuilder,
private metisConversationService: MetisConversationService,
) {
super(metisService);
effect(() => this.loadData(this.exercise(), this.lecture()));
}

/**
* on initialization: initializes the metis service, fetches the posts for the exercise or lecture the discussion section is placed at,
* creates the subscription to posts to stay updated on any changes of posts in this course
*/
ngOnInit(): void {
loadData(exercise?: Exercise, lecture?: Lecture): void {
this.paramSubscription = combineLatest({
params: this.activatedRoute.params,
queryParams: this.activatedRoute.queryParams,
}).subscribe((routeParams: { params: Params; queryParams: Params }) => {
this.currentPostId = +routeParams.queryParams.postId;
this.course = this.exercise?.course ?? this.lecture?.course;
this.course = exercise?.course ?? lecture?.course;
this.metisService.setCourse(this.course);
this.metisService.setPageType(this.PAGE_TYPE);
if (routeParams.params.courseId) {
Expand Down Expand Up @@ -146,14 +147,14 @@ export class DiscussionSectionComponent extends CourseDiscussionDirective implem

// Currently, an additional REST call is made to retrieve the channel associated with the lecture/exercise
// TODO: Add the channel to the response for loading the lecture/exercise
if (this.lecture?.id) {
if (this.lecture()) {
this.channelService
.getChannelOfLecture(courseId, this.lecture.id)
.getChannelOfLecture(courseId, this.lecture()!.id!)
.pipe(map((res: HttpResponse<ChannelDTO>) => res.body))
.subscribe(getChannel());
} else if (this.exercise?.id) {
} else if (this.exercise()) {
this.channelService
.getChannelOfExercise(courseId, this.exercise.id)
.getChannelOfExercise(courseId, this.exercise()!.id!)
.pipe(map((res: HttpResponse<ChannelDTO>) => res.body))
.subscribe(getChannel());
}
Expand Down Expand Up @@ -271,8 +272,8 @@ export class DiscussionSectionComponent extends CourseDiscussionDirective implem
resetFormGroup(): void {
this.formGroup = this.formBuilder.group({
conversationId: this.channel?.id,
exerciseId: this.exercise?.id,
lectureId: this.lecture?.id,
exerciseId: this.exercise()?.id,
lectureId: this.lecture()?.id,
filterToUnresolved: false,
filterToOwn: false,
filterToAnsweredOrReacted: false,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ <h4 class="mt-2">
</div>
<div class="col d-flex flex-grow-1 justify-end" style="max-width: min-content">
@if (exercise.course && (isCommunicationEnabled(exercise.course) || isMessagingEnabled(exercise.course))) {
<router-outlet (activate)="onChildActivate($event)" />
<jhi-discussion-section [exercise]="exercise" />
}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { TeamAssignmentPayload } from 'app/entities/team.model';
import { TeamService } from 'app/exercises/shared/team/team.service';
import { QuizExercise, QuizStatus } from 'app/entities/quiz/quiz-exercise.model';
import { QuizExerciseService } from 'app/exercises/quiz/manage/quiz-exercise.service';
import { DiscussionSectionComponent } from 'app/overview/discussion-section/discussion-section.component';
import { ExerciseCategory } from 'app/entities/exercise-category.model';
import { getFirstResultWithComplaintFromResults } from 'app/entities/submission.model';
import { ComplaintService } from 'app/complaints/complaint.service';
Expand Down Expand Up @@ -86,7 +85,6 @@ export class CourseExerciseDetailsComponent extends AbstractScienceComponent imp
isAfterAssessmentDueDate: boolean;
allowComplaintsForAutomaticAssessments: boolean;
public gradingCriteria: GradingCriterion[];
private discussionComponent?: DiscussionSectionComponent;
baseResource: string;
isExamExercise: boolean;
submissionPolicy?: SubmissionPolicy;
Expand Down Expand Up @@ -224,10 +222,6 @@ export class CourseExerciseDetailsComponent extends AbstractScienceComponent imp
this.subscribeForNewResults();
this.subscribeToTeamAssignmentUpdates();

if (this.discussionComponent && this.exercise) {
// We need to manually update the exercise property of the posts component
this.discussionComponent.exercise = this.exercise;
}
this.baseResource = `/course-management/${this.courseId}/${this.exercise.type}-exercises/${this.exercise.id}/`;
}

Expand Down Expand Up @@ -416,18 +410,6 @@ export class CourseExerciseDetailsComponent extends AbstractScienceComponent imp
return undefined;
}

/**
* This function gets called if the router outlet gets activated. This is
* used only for the DiscussionComponent
* @param instance The component instance
*/
onChildActivate(instance: DiscussionSectionComponent) {
this.discussionComponent = instance; // save the reference to the component instance
if (this.exercise) {
instance.exercise = this.exercise;
}
}

private onError(error: string) {
this.alertService.error(error);
}
Expand Down
Loading
Loading