From a3ca26b9bc3855b4563d55c0338eb06a7420bbd4 Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 14:16:35 +0800 Subject: [PATCH 01/17] Remove course archive from instructor-home-page --- .../instructor-home-page.component.html | 5 --- .../instructor-home-page.component.spec.ts | 33 +--------------- .../instructor-home-page.component.ts | 38 ------------------- 3 files changed, 1 insertion(+), 75 deletions(-) diff --git a/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.html b/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.html index a673dcb19a8c..2cd8e2519506 100644 --- a/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.html +++ b/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.html @@ -76,11 +76,6 @@

Home

- Archive - View / Edit diff --git a/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.spec.ts b/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.spec.ts index 3b2f6bfb9495..f1f34edeaf80 100644 --- a/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.spec.ts +++ b/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.spec.ts @@ -10,7 +10,7 @@ import { FeedbackSessionsService } from '../../../services/feedback-sessions.ser import { SimpleModalService } from '../../../services/simple-modal.service'; import { createMockNgbModalRef } from '../../../test-helpers/mock-ngb-modal-ref'; import { - Course, CourseArchive, Courses, + Course, Courses, FeedbackSession, FeedbackSessionPublishStatus, FeedbackSessions, @@ -182,37 +182,6 @@ describe('InstructorHomePageComponent', () => { expect(component.courseTabModels[0].isTabExpanded).toBeTruthy(); }); - it('should archive the entire course from the instructor', () => { - const courseArchive: CourseArchive = { - courseId: 'CS1231', - isArchived: true, - }; - - component.courseTabModels = activeCourseTabModels; - component.hasCoursesLoaded = true; - fixture.detectChanges(); - - expect(component.courseTabModels.length).toEqual(2); - expect(component.courseTabModels[0].course.courseId).toEqual('CS1231'); - expect(component.courseTabModels[0].course.courseName).toEqual('Discrete Structures'); - - jest.spyOn(simpleModalService, 'openConfirmationModal').mockImplementation( - () => createMockNgbModalRef({ - header: 'mock header', content: 'mock content', type: SimpleModalType.INFO, - }), - ); - jest.spyOn(courseService, 'changeArchiveStatus').mockReturnValue(of(courseArchive)); - - const courseButton: any = fixture.debugElement.nativeElement.querySelector('.btn-course'); - courseButton.click(); - const archiveButton: any = document.querySelector('body > div > div > .btn-archive-course'); - archiveButton.click(); - - expect(component.courseTabModels.length).toEqual(1); - expect(component.courseTabModels[0].course.courseId).toEqual('CS3281'); - expect(component.courseTabModels[0].course.courseName).toEqual('Thematic Systems I'); - }); - it('should delete the entire course from the instructor', () => { const courseToDelete: Course = testCourse1; diff --git a/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.ts b/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.ts index 06b979547b7d..3564a960713b 100644 --- a/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.ts +++ b/src/web/app/pages-instructor/instructor-home-page/instructor-home-page.component.ts @@ -24,7 +24,6 @@ import { TableComparatorService } from '../../../services/table-comparator.servi import { TimezoneService } from '../../../services/timezone.service'; import { Course, - CourseArchive, Courses, FeedbackSession, FeedbackSessions, @@ -279,34 +278,6 @@ export class InstructorHomePageComponent extends InstructorSessionModalPageCompo }); } - /** - * Archives the entire course from the instructor - */ - archiveCourse(courseId: string): void { - const modalContent: string = - 'This action can be reverted by going to the "Courses" tab and unarchiving the desired course(s).'; - - const modalRef: NgbModalRef = - this.simpleModalService.openConfirmationModal( - `Archive course ${courseId}?`, SimpleModalType.INFO, modalContent); - modalRef.result.then(() => { - this.courseService.changeArchiveStatus(courseId, { - archiveStatus: true, - }).subscribe({ - next: (courseArchive: CourseArchive) => { - this.courseTabModels = this.courseTabModels.filter((model: CourseTabModel) => { - return model.course.courseId !== courseId; - }); - this.statusMessageService.showSuccessToast(`The course ${courseArchive.courseId} has been archived. ` - + 'You can retrieve it from the Courses page.'); - }, - error: (resp: ErrorMessageOutput) => { - this.statusMessageService.showErrorToast(resp.error.message); - }, - }); - }, () => {}); - } - /** * Deletes the entire course from the instructor */ @@ -357,15 +328,6 @@ export class InstructorHomePageComponent extends InstructorSessionModalPageCompo this.statusMessageService.showErrorToast(resp.error.message); }, }); - this.courseService.getAllCoursesAsInstructor('archived').subscribe({ - next: (resp: Courses) => { - this.allCoursesList.push(...resp.courses); - }, - error: (resp: ErrorMessageOutput) => { - this.hasCoursesLoadingFailed = true; - this.statusMessageService.showErrorToast(resp.error.message); - }, - }); this.courseService.getAllCoursesAsInstructor('softDeleted').subscribe({ next: (resp: Courses) => { this.allCoursesList.push(...resp.courses); From 56c712b3e675060404bf85a3a9c9b992e93b24d1 Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 14:29:24 +0800 Subject: [PATCH 02/17] Remove from course service --- src/web/services/course.service.spec.ts | 19 +------------------ src/web/services/course.service.ts | 18 ++---------------- 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/src/web/services/course.service.spec.ts b/src/web/services/course.service.spec.ts index 89c55fccb7af..4460da5d6ed2 100644 --- a/src/web/services/course.service.spec.ts +++ b/src/web/services/course.service.spec.ts @@ -5,7 +5,7 @@ import { CourseService } from './course.service'; import { HttpRequestService } from './http-request.service'; import createSpyFromClass from '../test-helpers/create-spy-from-class'; import { ResourceEndpoints } from '../types/api-const'; -import { CourseArchiveRequest, CourseCreateRequest, CourseUpdateRequest } from '../types/api-request'; +import { CourseCreateRequest, CourseUpdateRequest } from '../types/api-request'; describe('CourseService', () => { let spyHttpRequestService: any; @@ -82,14 +82,8 @@ describe('CourseService', () => { entitytype: 'instructor', user: googleId, }; - const archivedCoursesParamMap: { [key: string]: string } = { - coursestatus: 'archived', - entitytype: 'instructor', - user: googleId, - }; service.getInstructorCoursesInMasqueradeMode(googleId); expect(spyHttpRequestService.get).toHaveBeenCalledWith(ResourceEndpoints.COURSES, activeCoursesParamMap); - expect(spyHttpRequestService.get).toHaveBeenCalledWith(ResourceEndpoints.COURSES, archivedCoursesParamMap); }); it('should execute GET when getting all active instructor courses', () => { @@ -132,17 +126,6 @@ describe('CourseService', () => { expect(spyHttpRequestService.delete).toHaveBeenCalledWith(ResourceEndpoints.COURSE, paramMap); }); - it('should execute PUT to archive course', () => { - const courseid: string = 'test-id'; - const request: CourseArchiveRequest = { - archiveStatus: true, - }; - const paramMap: { [key: string]: string } = { courseid }; - service.changeArchiveStatus(courseid, request); - expect(spyHttpRequestService.put) - .toHaveBeenCalledWith(ResourceEndpoints.COURSE_ARCHIVE, paramMap, request); - }); - it('should execute PUT to bin course', () => { const courseid: string = 'test-id'; const paramMap: { [key: string]: string } = { courseid }; diff --git a/src/web/services/course.service.ts b/src/web/services/course.service.ts index 676a112f557a..d91879fe789f 100644 --- a/src/web/services/course.service.ts +++ b/src/web/services/course.service.ts @@ -3,8 +3,8 @@ import { forkJoin, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { HttpRequestService } from './http-request.service'; import { ResourceEndpoints } from '../types/api-const'; -import { Course, CourseArchive, Courses, HasResponses, JoinStatus, MessageOutput, Student } from '../types/api-output'; -import { CourseArchiveRequest, CourseCreateRequest, CourseUpdateRequest } from '../types/api-request'; +import { Course, Courses, HasResponses, JoinStatus, MessageOutput, Student } from '../types/api-output'; +import { CourseCreateRequest, CourseUpdateRequest } from '../types/api-request'; /** * The statistics of a course @@ -95,15 +95,9 @@ export class CourseService { entitytype: 'instructor', user: googleId, }; - const archivedCoursesParamMap: Record = { - coursestatus: 'archived', - entitytype: 'instructor', - user: googleId, - }; return forkJoin([ this.httpRequestService.get(ResourceEndpoints.COURSES, activeCoursesParamMap), - this.httpRequestService.get(ResourceEndpoints.COURSES, archivedCoursesParamMap), ]).pipe( map((vals: Courses[]) => { return { @@ -149,14 +143,6 @@ export class CourseService { return this.httpRequestService.delete(ResourceEndpoints.COURSE, paramMap); } - /** - * Changes the archive status of a course by calling API. - */ - changeArchiveStatus(courseid: string, request: CourseArchiveRequest): Observable { - const paramMap: Record = { courseid }; - return this.httpRequestService.put(ResourceEndpoints.COURSE_ARCHIVE, paramMap, request); - } - /** * Bin (soft-delete) a course by calling API. */ From 0814c25bcbfc6654c333a6db083cdf34c7afee79 Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 14:29:39 +0800 Subject: [PATCH 03/17] Remove from instructor-courses-page --- .../instructor-courses-page.component.html | 102 -------------- .../instructor-courses-page.component.scss | 16 --- .../instructor-courses-page.component.spec.ts | 109 ++------------- .../instructor-courses-page.component.ts | 130 +----------------- 4 files changed, 14 insertions(+), 343 deletions(-) diff --git a/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.html b/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.html index 30d219746895..25a48d49e39e 100644 --- a/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.html +++ b/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.html @@ -160,12 +160,6 @@

Active courses

[disabled]="isCopyingCourse"> Copy - View Logs @@ -203,102 +197,6 @@

Active courses

-
-

- Archived courses -

-
- - - -
-
- Archive -
- -
-
-
- - - - - - - - - - - - - - - - - -
- - - - - - Action(s)
{{course.course.courseId}}{{course.course.courseName}} - {{course.course.creationTimestamp - | date:'d MMM yyyy'}} - - - - -
-
-
-
-
-

diff --git a/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.scss b/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.scss index c7dd21100452..3d7bd786971c 100644 --- a/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.scss +++ b/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.scss @@ -6,14 +6,6 @@ } } -// applies only to mobile screens -@media (width <= 768px) { - .custom-button-archived { - width: 95px; - margin-bottom: 5px; - } -} - .sortable-header { cursor: pointer; @@ -79,14 +71,6 @@ margin-bottom: 0; } -.archive-body { - padding: 0; -} - -.archive-table { - margin-bottom: 0; -} - .margin-top-30px { margin-top: 30px; } diff --git a/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.spec.ts b/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.spec.ts index 50b2b9865865..67d0396e1976 100644 --- a/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.spec.ts +++ b/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.spec.ts @@ -11,7 +11,7 @@ import { SimpleModalService } from '../../../services/simple-modal.service'; import { StudentService } from '../../../services/student.service'; import { TimezoneService } from '../../../services/timezone.service'; import { createMockNgbModalRef } from '../../../test-helpers/mock-ngb-modal-ref'; -import { Course, CourseArchive, Courses, JoinState, Students } from '../../../types/api-output'; +import { Course, Courses, JoinState, Students } from '../../../types/api-output'; describe('InstructorCoursesPageComponent', () => { let component: InstructorCoursesPageComponent; @@ -53,29 +53,6 @@ describe('InstructorCoursesPageComponent', () => { }, ]; - const archivedCoursesSnap: any[] = [ - { - course: { - courseId: 'CS2104', - courseName: 'Can modify archived', - timeZone: 'UTC', - creationTimestamp: date3.getTime(), - deletionTimestamp: 0, - }, - canModifyCourse: true, - }, - { - course: { - courseId: 'CS2106', - courseName: 'Cannot modify archived', - timeZone: 'UTC', - creationTimestamp: date3.getTime(), - deletionTimestamp: 0, - }, - canModifyCourse: false, - }, - ]; - const deletedCoursesSnap: any[] = [ { course: { @@ -287,31 +264,26 @@ describe('InstructorCoursesPageComponent', () => { const courseSpy: SpyInstance = jest.spyOn(courseService, 'getAllCoursesAsInstructor').mockImplementation( (courseStatus: string): Observable => { if (courseStatus === 'active') { - return of({ courses: [courseCS1231] }); - } - if (courseStatus === 'archived') { - return of({ courses: [courseCS3281, courseCS3282] }); + return of({ courses: [courseCS1231, courseCS3281, courseCS3282] }); } + // softDeleted return of({ courses: [courseST4234] }); }); component.loadInstructorCourses(); - expect(courseSpy).toHaveBeenCalledTimes(3); + expect(courseSpy).toHaveBeenCalledTimes(2); expect(courseSpy).toHaveBeenNthCalledWith(1, 'active'); - expect(courseSpy).toHaveBeenNthCalledWith(2, 'archived'); - expect(courseSpy).toHaveBeenNthCalledWith(3, 'softDeleted'); + expect(courseSpy).toHaveBeenNthCalledWith(2, 'softDeleted'); - expect(component.activeCourses.length).toEqual(1); + expect(component.activeCourses.length).toEqual(3); expect(component.activeCourses[0].course.courseId).toEqual('CS1231'); expect(component.activeCourses[0].course.courseName).toEqual('Discrete Structures'); - - expect(component.archivedCourses.length).toEqual(2); - expect(component.archivedCourses[0].course.courseId).toEqual('CS3282'); - expect(component.archivedCourses[0].course.courseName).toEqual('Thematic Systems Project II'); - expect(component.archivedCourses[1].course.courseId).toEqual('CS3281'); - expect(component.archivedCourses[1].course.courseName).toEqual('Thematic Systems Project I'); + expect(component.activeCourses[1].course.courseId).toEqual('CS3281'); + expect(component.activeCourses[1].course.courseName).toEqual('Thematic Systems Project I'); + expect(component.activeCourses[2].course.courseId).toEqual('CS3282'); + expect(component.activeCourses[2].course.courseName).toEqual('Thematic Systems Project II'); expect(component.softDeletedCourses.length).toEqual(1); expect(component.softDeletedCourses[0].course.courseId).toEqual('ST4234'); @@ -332,42 +304,6 @@ describe('InstructorCoursesPageComponent', () => { expect(component.courseStats['CS1231']['unregistered']).toEqual(1); }); - it('should archive an active course', () => { - const courseArchiveCS1231: CourseArchive = { - courseId: 'CS1231', - isArchived: true, - }; - component.activeCourses = [courseModelCS1231]; - const courseSpy: SpyInstance = jest.spyOn(courseService, 'changeArchiveStatus') - .mockReturnValue(of(courseArchiveCS1231)); - component.changeArchiveStatus('CS1231', true); - - expect(courseSpy).toHaveBeenCalledTimes(1); - expect(courseSpy).toHaveBeenLastCalledWith('CS1231', { archiveStatus: true }); - - expect(component.activeCourses.length).toEqual(0); - expect(component.archivedCourses.length).toEqual(1); - expect(component.archivedCourses[0].course.courseId).toEqual('CS1231'); - }); - - it('should unarchive an archived course', () => { - const courseArchiveCS1231: CourseArchive = { - courseId: 'CS1231', - isArchived: false, - }; - component.archivedCourses = [courseModelCS1231]; - const courseSpy: SpyInstance = jest.spyOn(courseService, 'changeArchiveStatus') - .mockReturnValue(of(courseArchiveCS1231)); - component.changeArchiveStatus('CS1231', false); - - expect(courseSpy).toHaveBeenCalledTimes(1); - expect(courseSpy).toHaveBeenNthCalledWith(1, 'CS1231', { archiveStatus: false }); - - expect(component.archivedCourses.length).toEqual(0); - expect(component.activeCourses.length).toEqual(1); - expect(component.activeCourses[0].course.courseId).toEqual('CS1231'); - }); - it('should restore a soft deleted course', () => { component.softDeletedCourses = [courseModelCS1231]; expect(component.softDeletedCourses.length).toEqual(1); @@ -382,7 +318,6 @@ describe('InstructorCoursesPageComponent', () => { expect(courseSpy).toHaveBeenCalledTimes(1); expect(courseSpy).toHaveBeenNthCalledWith(1, 'CS1231'); - expect(component.archivedCourses.length).toEqual(0); expect(component.softDeletedCourses.length).toEqual(0); }); @@ -402,7 +337,7 @@ describe('InstructorCoursesPageComponent', () => { }); it('should permanently delete a course', async () => { - component.archivedCourses = [courseModelCS1231]; + component.softDeletedCourses = [courseModelCS1231]; const courseSpy: SpyInstance = jest.spyOn(courseService, 'deleteCourse') .mockReturnValue(of({ message: 'Message' })); jest.spyOn(simpleModalService, 'openConfirmationModal').mockReturnValue( @@ -420,7 +355,6 @@ describe('InstructorCoursesPageComponent', () => { it('should show add course form and disable button when clicking on add new course', () => { component.activeCourses = [courseModelCS3282]; component.isLoadingActiveCourses = false; - component.isLoadingArchivedCourses = false; component.isLoadingSoftDeletedCourses = false; fixture.detectChanges(); @@ -453,17 +387,6 @@ describe('InstructorCoursesPageComponent', () => { expect(button.className).toContain('disabled'); }); - it('should disable delete button when instructor cannot modify archived course', () => { - component.archivedCourses = [courseModelST4234]; - component.isLoadingArchivedCourses = false; - component.isArchivedCourseExpanded = true; - fixture.detectChanges(); - - const button: any = fixture.debugElement.nativeElement.querySelector('#btn-soft-delete-archived-disabled-0'); - expect(button.textContent).toEqual(' Delete '); - expect(button.className).toContain('disabled'); - }); - it('should disable restore and permanently delete buttons when instructor cannot modify deleted course', () => { component.softDeletedCourses = [courseModelST4234]; component.isLoadingSoftDeletedCourses = false; @@ -524,7 +447,6 @@ describe('InstructorCoursesPageComponent', () => { it('should snap with all courses in course stats', () => { component.activeCourses = activeCoursesSnap; - component.archivedCourses = archivedCoursesSnap; component.softDeletedCourses = deletedCoursesSnap; component.courseStats = courseStatsSnap; component.isLoadingActiveCourses = false; @@ -534,7 +456,6 @@ describe('InstructorCoursesPageComponent', () => { it('should snap when it is undeletable and unrestorable', () => { component.activeCourses = activeCoursesSnap; - component.archivedCourses = archivedCoursesSnap; component.softDeletedCourses = deletedCoursesSnap; component.courseStats = courseStatsSnap; component.canDeleteAll = false; @@ -560,7 +481,6 @@ describe('InstructorCoursesPageComponent', () => { it('should snap when new course form is expanded', () => { component.isAddNewCourseFormExpanded = true; component.isLoadingActiveCourses = false; - component.isLoadingArchivedCourses = false; component.isLoadingSoftDeletedCourses = false; // Mock the timezone service to prevent unexpected changes in time zones over time, such as daylight savings time const timezones: Record = { @@ -573,11 +493,4 @@ describe('InstructorCoursesPageComponent', () => { fixture.detectChanges(); expect(fixture).toMatchSnapshot(); }); - - it('should snap when archived courses are expanded', () => { - component.archivedCourses = archivedCoursesSnap; - component.isArchivedCourseExpanded = true; - fixture.detectChanges(); - expect(fixture).toMatchSnapshot(); - }); }); diff --git a/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.ts b/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.ts index 120b8f79f7da..fc4d035e0567 100644 --- a/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.ts +++ b/src/web/app/pages-instructor/instructor-courses-page/instructor-courses-page.component.ts @@ -22,7 +22,6 @@ import { TableComparatorService } from '../../../services/table-comparator.servi import { TimezoneService } from '../../../services/timezone.service'; import { Course, - CourseArchive, Courses, FeedbackSession, FeedbackSessions, @@ -92,7 +91,6 @@ interface CourseModel { export class InstructorCoursesPageComponent implements OnInit { activeCourses: CourseModel[] = []; - archivedCourses: CourseModel[] = []; softDeletedCourses: CourseModel[] = []; allCoursesList: Course[] = []; activeCoursesList: Course[] = []; @@ -102,8 +100,6 @@ export class InstructorCoursesPageComponent implements OnInit { activeTableSortOrder: SortOrder = SortOrder.ASC; activeTableSortBy: SortBy = SortBy.COURSE_CREATION_DATE; - archivedTableSortOrder: SortOrder = SortOrder.ASC; - archivedTableSortBy: SortBy = SortBy.COURSE_NAME; deletedTableSortOrder: SortOrder = SortOrder.ASC; deletedTableSortBy: SortBy = SortBy.COURSE_NAME; @@ -113,14 +109,12 @@ export class InstructorCoursesPageComponent implements OnInit { CourseEditFormMode: typeof CourseEditFormMode = CourseEditFormMode; isLoadingActiveCourses: boolean = false; - isLoadingArchivedCourses: boolean = false; isLoadingSoftDeletedCourses: boolean = false; hasLoadingFailed: boolean = false; isRecycleBinExpanded: boolean = false; canDeleteAll: boolean = true; canRestoreAll: boolean = true; isAddNewCourseFormExpanded: boolean = false; - isArchivedCourseExpanded: boolean = false; isCopyingCourse: boolean = false; copyProgressPercentage: number = 0; @@ -130,7 +124,7 @@ export class InstructorCoursesPageComponent implements OnInit { modifiedSessions: Record = {}; get isLoadingCourses(): boolean { - return this.isLoadingActiveCourses || this.isLoadingArchivedCourses || this.isLoadingSoftDeletedCourses; + return this.isLoadingActiveCourses || this.isLoadingSoftDeletedCourses; } @Output() courseAdded: EventEmitter = new EventEmitter(); @@ -168,10 +162,8 @@ export class InstructorCoursesPageComponent implements OnInit { loadInstructorCourses(): void { this.hasLoadingFailed = false; this.isLoadingActiveCourses = true; - this.isLoadingArchivedCourses = true; this.isLoadingSoftDeletedCourses = true; this.activeCourses = []; - this.archivedCourses = []; this.softDeletedCourses = []; this.activeCoursesList = []; this.allCoursesList = []; @@ -202,32 +194,6 @@ export class InstructorCoursesPageComponent implements OnInit { }, }); - this.courseService.getAllCoursesAsInstructor('archived').subscribe({ - next: (resp: Courses) => { - for (const course of resp.courses) { - this.allCoursesList.push(course); - let canModifyCourse: boolean = false; - let canModifyStudent: boolean = false; - if (course.privileges) { - canModifyCourse = course.privileges.canModifyCourse; - canModifyStudent = course.privileges.canModifyStudent; - } - const isLoadingCourseStats: boolean = false; - const archivedCourse: CourseModel = { - course, canModifyCourse, canModifyStudent, isLoadingCourseStats, - }; - this.archivedCourses.push(archivedCourse); - this.archivedCoursesDefaultSort(); - } - this.isLoadingArchivedCourses = false; - }, - error: (resp: ErrorMessageOutput) => { - this.isLoadingArchivedCourses = false; - this.hasLoadingFailed = true; - this.statusMessageService.showErrorToast(resp.error.message); - }, - }); - this.courseService.getAllCoursesAsInstructor('softDeleted').subscribe({ next: (resp: Courses) => { for (const course of resp.courses) { @@ -293,61 +259,6 @@ export class InstructorCoursesPageComponent implements OnInit { }); } - /** - * Changes the status of an archived course. - */ - changeArchiveStatus(courseId: string, toArchive: boolean): void { - if (!courseId) { - this.statusMessageService.showErrorToast(`Course ${courseId} is not found!`); - return; - } - this.courseService.changeArchiveStatus(courseId, { - archiveStatus: toArchive, - }).subscribe({ - next: (courseArchive: CourseArchive) => { - if (courseArchive.isArchived) { - this.changeModelFromActiveToArchived(courseId); - this.statusMessageService.showSuccessToast(`The course ${courseId} has been archived. ` - + 'It will not appear on the home page anymore.'); - } else { - this.changeModelFromArchivedToActive(courseId); - this.statusMessageService.showSuccessToast('The course has been unarchived.'); - } - }, - error: (resp: ErrorMessageOutput) => { - this.statusMessageService.showErrorToast(resp.error.message); - }, - }); - } - - /** - * Moves a course model from active courses list to archived list. - * This is to reduce the need to refresh the entire list of courses multiple times. - */ - changeModelFromActiveToArchived(courseId: string): void { - const courseToBeRemoved: CourseModel | undefined = this.findCourse(this.activeCourses, courseId); - this.activeCourses = this.removeCourse(this.activeCourses, courseId); - this.activeCoursesList = this.activeCourses.map((courseModel: CourseModel) => courseModel.course); - if (courseToBeRemoved !== undefined) { - this.archivedCourses.push(courseToBeRemoved); - this.archivedCourses.sort(this.sortBy(this.archivedTableSortBy, this.archivedTableSortOrder)); - } - } - - /** - * Moves a course model from archived courses list to active list. - * This is to reduce the need to refresh the entire list of courses multiple times. - */ - changeModelFromArchivedToActive(courseId: string): void { - const courseToBeRemoved: CourseModel | undefined = this.findCourse(this.archivedCourses, courseId); - this.archivedCourses = this.removeCourse(this.archivedCourses, courseId); - if (courseToBeRemoved !== undefined) { - this.activeCourses.push(courseToBeRemoved); - this.activeCoursesList = this.activeCourses.map((courseModel: CourseModel) => courseModel.course); - this.activeCourses.sort(this.sortBy(this.activeTableSortBy, this.activeTableSortOrder)); - } - } - /** * Creates new course */ @@ -651,7 +562,7 @@ export class InstructorCoursesPageComponent implements OnInit { } /** - * Moves an active/archived course to Recycle Bin. + * Moves an active course to Recycle Bin. */ onDelete(courseId: string): Promise { if (!courseId) { @@ -676,7 +587,7 @@ export class InstructorCoursesPageComponent implements OnInit { } /** - * Moves an active/archived course to Recycle Bin. + * Moves an active course to Recycle Bin. * This is to reduce the need to refresh the entire list of courses multiple times. */ moveCourseToRecycleBin(courseId: string, deletionTimeStamp: number): void { @@ -687,14 +598,6 @@ export class InstructorCoursesPageComponent implements OnInit { activeCourseToBeRemoved.course.deletionTimestamp = deletionTimeStamp; this.softDeletedCourses.push(activeCourseToBeRemoved); this.softDeletedCourses.sort(this.sortBy(this.deletedTableSortBy, this.deletedTableSortOrder)); - } else { - const archivedCourseToBeRemoved: CourseModel | undefined = this.findCourse(this.archivedCourses, courseId); - this.archivedCourses = this.removeCourse(this.archivedCourses, courseId); - if (archivedCourseToBeRemoved !== undefined) { - archivedCourseToBeRemoved.course.deletionTimestamp = deletionTimeStamp; - this.softDeletedCourses.push(archivedCourseToBeRemoved); - this.softDeletedCourses.sort(this.sortBy(this.deletedTableSortBy, this.deletedTableSortOrder)); - } } } @@ -809,7 +712,6 @@ export class InstructorCoursesPageComponent implements OnInit { this.softDeletedCourses = []; this.allCoursesList = []; this.allCoursesList.push(...this.activeCourses.map((courseModel: CourseModel) => courseModel.course)); - this.allCoursesList.push(...this.archivedCourses.map((courseModel: CourseModel) => courseModel.course)); this.statusMessageService.showSuccessToast('All courses have been permanently deleted.'); }, error: (resp: ErrorMessageOutput) => { @@ -865,32 +767,6 @@ export class InstructorCoursesPageComponent implements OnInit { this.activeCourses.sort(this.sortBy(this.activeTableSortBy, this.activeTableSortOrder)); } - /** - * Sorts the archived courses table - */ - sortArchivedCoursesEvent(by: SortBy): void { - this.archivedTableSortOrder = this.archivedTableSortBy === by && this.archivedTableSortOrder === SortOrder.ASC - ? SortOrder.DESC : SortOrder.ASC; - this.archivedTableSortBy = by; - this.archivedCourses.sort(this.sortBy(by, this.archivedTableSortOrder)); - } - - getAriaSortArchived(by: SortBy): string { - if (by !== this.archivedTableSortBy) { - return 'none'; - } - return this.archivedTableSortOrder === SortOrder.ASC ? 'ascending' : 'descending'; - } - - /** - * Archived courses default sort on page load - */ - archivedCoursesDefaultSort(): void { - this.archivedTableSortBy = SortBy.COURSE_CREATION_DATE; - this.archivedTableSortOrder = SortOrder.DESC; - this.archivedCourses.sort(this.sortBy(this.archivedTableSortBy, this.archivedTableSortOrder)); - } - /** * Sorts the soft-deleted courses table */ From 97bcdf6acd82918969ef9ff4ffa8340b802ccced Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 14:31:11 +0800 Subject: [PATCH 04/17] Remove from instructor-help-course-section component --- .../courses-section-questions.ts | 15 ------ ...ructor-help-courses-section.component.html | 48 ------------------- ...structor-help-courses-section.component.ts | 3 -- 3 files changed, 66 deletions(-) diff --git a/src/web/app/pages-help/instructor-help-page/instructor-help-courses-section/courses-section-questions.ts b/src/web/app/pages-help/instructor-help-page/instructor-help-courses-section/courses-section-questions.ts index 334298bd23c5..985d2ba832ea 100644 --- a/src/web/app/pages-help/instructor-help-page/instructor-help-courses-section/courses-section-questions.ts +++ b/src/web/app/pages-help/instructor-help-page/instructor-help-courses-section/courses-section-questions.ts @@ -67,21 +67,6 @@ export enum CoursesSectionQuestions { */ DEL_STUDENTS = 'del-students', - /** - * How do I archive a course? - */ - COURSE_ARCHIVE = 'course-archive', - - /** - * How do I view courses I have archived? - */ - COURSE_VIEW_ARCHIVED = 'course-view-archived', - - /** - * How do I unarchive an archived course? - */ - COURSE_UNARCHIVE = 'course-unarchive', - /** * How do I view courses I have deleted? */ diff --git a/src/web/app/pages-help/instructor-help-page/instructor-help-courses-section/instructor-help-courses-section.component.html b/src/web/app/pages-help/instructor-help-page/instructor-help-courses-section/instructor-help-courses-section.component.html index b321cd0d0c27..3b4aff0baa14 100644 --- a/src/web/app/pages-help/instructor-help-page/instructor-help-courses-section/instructor-help-courses-section.component.html +++ b/src/web/app/pages-help/instructor-help-page/instructor-help-courses-section/instructor-help-courses-section.component.html @@ -253,54 +253,6 @@

Managing Courses

-

Archiving Courses

- - -

- When a course has ended, you can archive it so that it doesn't appear in your home page. Course, student and session details of an archived course are still stored on TEAMMATES. However, you cannot edit, create feedback sessions for or enroll students in an archived course. -

-

- In your Home page, you will see panels for each course and a table of feedback sessions inside it.
- Click on the button on the card heading of the course you want to archive.
- Then select Archive in the drop-down menu and click Yes to confirm. -

-

- You can also archive a course from the Courses page.
- Under 'Active Courses', click on the button in the row corresponding to the course you want to archive.
- Then select Archive in the drop-down menu. -

-
- - -

- You can view all your archived courses by navigating to the Courses page.
- Scroll to the Archived courses heading. -

-

- The courses you have previously archived are listed here. - In order to access information in an archived course, unarchive the course. -

- - - -

- To unarchive a course, first view the course that you would like to unarchive in the Courses page.
- Then, click on the button corresponding to the course you want to unarchive. -

-
-

Restoring Deleted Courses

Date: Sun, 8 Feb 2026 14:33:27 +0800 Subject: [PATCH 05/17] Remove from instructor-sessions-page component --- .../instructor-sessions-page.component.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/web/app/pages-instructor/instructor-sessions-page/instructor-sessions-page.component.html b/src/web/app/pages-instructor/instructor-sessions-page/instructor-sessions-page.component.html index 7c8108b82502..bc3d5a0fa366 100644 --- a/src/web/app/pages-instructor/instructor-sessions-page/instructor-sessions-page.component.html +++ b/src/web/app/pages-instructor/instructor-sessions-page/instructor-sessions-page.component.html @@ -1,7 +1,7 @@
@@ -56,9 +56,8 @@

- Note: The table above doesn't contain sessions from archived courses and courses in recycle bin. - To view sessions from an archived course, unarchive the course first; to view sessions from a course in recycle - bin, restore the course first. + Note: The table above doesn't contain sessions from courses in recycle bin. + To view sessions from a course in recycle bin, restore the course first.

From c763b84a43ecbeb07c1a0664a30fca2a6ef99049 Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 14:36:36 +0800 Subject: [PATCH 06/17] Remove from copy-instructors-from-other-courses-modal --- .../copy-instructors-from-other-courses-modal-model.ts | 1 - ...opy-instructors-from-other-courses-modal.component.html | 7 +++---- ...-instructors-from-other-courses-modal.component.spec.ts | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal-model.ts b/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal-model.ts index 39fcfe145092..9ab666a854be 100644 --- a/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal-model.ts +++ b/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal-model.ts @@ -8,7 +8,6 @@ export interface CourseTabModel { courseId: string; courseName: string; creationTimestamp: number; - isArchived: boolean; instructorCandidates: InstructorToCopyCandidateModel[]; instructorCandidatesSortBy: SortBy; diff --git a/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal.component.html b/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal.component.html index 859b119450ab..5bbc8193d297 100644 --- a/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal.component.html +++ b/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal.component.html @@ -13,9 +13,8 @@
-
- [{{course.courseId}}]: {{course.courseName}} - [{{course.courseId}}] (Archived): {{course.courseName}} +
+ [{{course.courseId}}]: {{course.courseName}}
@@ -27,7 +26,7 @@
- +
# diff --git a/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal.component.spec.ts b/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal.component.spec.ts index 1dbeac147338..c39990a7f8cc 100644 --- a/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal.component.spec.ts +++ b/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/copy-instructors-from-other-courses-modal.component.spec.ts @@ -91,7 +91,6 @@ describe('CopyInstructorsFromOtherCoursesModalComponent', () => { courseId: 'FAN0002', courseName: 'Test Course 1', creationTimestamp: new Date('2022-07-26T01:00:15Z').getTime(), - isArchived: true, instructorCandidates: [], instructorCandidatesSortBy: SortBy.NONE, instructorCandidatesSortOrder: SortOrder.ASC, @@ -104,7 +103,6 @@ describe('CopyInstructorsFromOtherCoursesModalComponent', () => { courseId: 'FAN0001', courseName: 'Test Course 2', creationTimestamp: new Date('2022-02-22T22:22:22Z').getTime(), - isArchived: false, instructorCandidates: [], instructorCandidatesSortBy: SortBy.NONE, instructorCandidatesSortOrder: SortOrder.ASC, @@ -117,7 +115,6 @@ describe('CopyInstructorsFromOtherCoursesModalComponent', () => { courseId: 'CS2103T', courseName: 'XXX Software Engineering', creationTimestamp: new Date('2022-06-21T07:51:20Z').getTime(), - isArchived: false, instructorCandidates: [], instructorCandidatesSortBy: SortBy.NONE, instructorCandidatesSortOrder: SortOrder.ASC, From 16ba5955fd9d5b9687f9799342e7770710c49558 Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 14:38:01 +0800 Subject: [PATCH 07/17] Remove from instructor-course-edit-page component --- .../instructor-course-edit-page.component.ts | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/web/app/pages-instructor/instructor-course-edit-page/instructor-course-edit-page.component.ts b/src/web/app/pages-instructor/instructor-course-edit-page/instructor-course-edit-page.component.ts index ee3e54d5722c..6c1f7070949c 100644 --- a/src/web/app/pages-instructor/instructor-course-edit-page/instructor-course-edit-page.component.ts +++ b/src/web/app/pages-instructor/instructor-course-edit-page/instructor-course-edit-page.component.ts @@ -693,11 +693,9 @@ export class InstructorCourseEditPageComponent implements OnInit { forkJoin([ this.courseService.getAllCoursesAsInstructor('active'), - this.courseService.getAllCoursesAsInstructor('archived'), ]).subscribe({ next: (values: Courses[]) => { const activeCourses: Courses = values[0]; - const archivedCourses: Courses = values[1]; activeCourses.courses.forEach((course: Course) => { if (course.courseId !== this.courseId && course.institute === this.courseFormModel.course.institute) { @@ -705,24 +703,6 @@ export class InstructorCourseEditPageComponent implements OnInit { courseId: course.courseId, courseName: course.courseName, creationTimestamp: course.creationTimestamp, - isArchived: false, - instructorCandidates: [], - instructorCandidatesSortBy: SortBy.NONE, - instructorCandidatesSortOrder: SortOrder.ASC, - hasInstructorsLoaded: false, - isTabExpanded: false, - hasLoadingFailed: false, - }; - courseTabModels.push(model); - } - }); - archivedCourses.courses.forEach((course: Course) => { - if (course.courseId !== this.courseId && course.institute === this.courseFormModel.course.institute) { - const model: CourseTabModel = { - courseId: course.courseId, - courseName: course.courseName, - creationTimestamp: course.creationTimestamp, - isArchived: true, instructorCandidates: [], instructorCandidatesSortBy: SortBy.NONE, instructorCandidatesSortOrder: SortOrder.ASC, From c5cb8dfa5b5df9e7337f1e0b657cab841d29ed2e Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 14:39:24 +0800 Subject: [PATCH 08/17] Remove from session-edit-form component --- .../session-edit-form/session-edit-form.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/app/components/session-edit-form/session-edit-form.component.html b/src/web/app/components/session-edit-form/session-edit-form.component.html index 5b6ed9207470..aa5b517ca539 100644 --- a/src/web/app/components/session-edit-form/session-edit-form.component.html +++ b/src/web/app/components/session-edit-form/session-edit-form.component.html @@ -55,7 +55,7 @@
Or
- There is no un-archived course. + There is no course.
{{ model.courseId }}
@@ -346,7 +346,7 @@
Or
-

You need to have an active(unarchived) course to create a session!

+

You need to have an active course to create a session!

From 9d0ac128437d04def9570c5849e0e725b3c8904f Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 15:33:39 +0800 Subject: [PATCH 10/17] Update snapshots and pass tests --- .../client/scripts/sql/typicalDataBundle.json | 177 ------------ src/main/appengine/index.yaml | 2 - ...other-courses-modal.component.spec.ts.snap | 18 +- ...ructor-courses-page.component.spec.ts.snap | 273 +----------------- .../instructor-courses-page.component.spec.ts | 8 +- ...nstructor-home-page.component.spec.ts.snap | 40 --- ...uctor-sessions-page.component.spec.ts.snap | 18 +- 7 files changed, 23 insertions(+), 513 deletions(-) diff --git a/src/client/java/teammates/client/scripts/sql/typicalDataBundle.json b/src/client/java/teammates/client/scripts/sql/typicalDataBundle.json index 36b86ad1774b..025e508ea7e1 100644 --- a/src/client/java/teammates/client/scripts/sql/typicalDataBundle.json +++ b/src/client/java/teammates/client/scripts/sql/typicalDataBundle.json @@ -77,12 +77,6 @@ "email": "iwosc@yahoo.tmt", "readNotifications": {} }, - "instructorOfArchivedCourse": { - "googleId": "idOfInstructorOfArchivedCourse", - "name": "InstructorOfArchiveCourse name", - "email": "instructorOfArchiveCourse@archiveCourse.tmt", - "readNotifications": {} - }, "instructor1OfTestingSanitizationCourse": { "googleId": "idOfInstructor1OfTestingSanitizationCourse", "name": "Instructor", @@ -101,12 +95,6 @@ "email": "student2InCourse1@gmail.tmt", "readNotifications": {} }, - "student1InArchivedCourse": { - "googleId": "student1InArchivedCourse", - "name": "Student in Archived Course", - "email": "student1InCourse1@gmail.tmt", - "readNotifications": {} - }, "student1InTestingSanitizationCourse": { "googleId": "student1InTestingSanitizationCourse", "name": "Stud1", @@ -156,12 +144,6 @@ "institute": "TEAMMATES Test Institute 7", "timeZone": "UTC" }, - "archivedCourse": { - "id": "idOfArchivedCourse", - "name": "Archived Course", - "institute": "TEAMMATES Test Institute 5", - "timeZone": "UTC" - }, "unregisteredCourse": { "id": "idOfUnregisteredCourse", "name": "Unregistered Course", @@ -189,7 +171,6 @@ "courseId": "idOfTypicalCourse1", "name": "Instructor1 Course1", "email": "instructor1@course1.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -213,7 +194,6 @@ "courseId": "idOfTypicalCourse1", "name": "Instructor2 Course1", "email": "instructor2@course1.tmt", - "isArchived": false, "role": "Manager", "isDisplayedToStudents": true, "displayedName": "Manager", @@ -237,7 +217,6 @@ "courseId": "idOfTypicalCourse1", "name": "Helper Course1", "email": "helper@course1.tmt", - "isArchived": false, "role": "Custom", "isDisplayedToStudents": false, "displayedName": "Helper", @@ -260,7 +239,6 @@ "courseId": "idOfTypicalCourse1", "name": "Instructor Not Yet Joined Course 1", "email": "instructorNotYetJoinedCourse1@email.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -284,7 +262,6 @@ "courseId": "idOfTypicalCourse2", "name": "Instructor1 Course2", "email": "instructor1@course2.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -308,7 +285,6 @@ "courseId": "idOfTypicalCourse2", "name": "Instructor2 Course2", "email": "instructor2@course2.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -332,7 +308,6 @@ "courseId": "idOfTypicalCourse3", "name": "Instructor1 Course3", "email": "instructor1@course3.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -356,7 +331,6 @@ "courseId": "idOfTypicalCourse3", "name": "Instructor2 Course3", "email": "instructor2@course3.tmt", - "isArchived": false, "role": "Custom", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -380,7 +354,6 @@ "courseId": "idOfTypicalCourse4", "name": "Instructor1 Course4", "email": "instructor1@course3.tmt", - "isArchived": false, "role": "Custom", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -404,7 +377,6 @@ "courseId": "idOfTypicalCourse1", "name": "Instructor3 Course1", "email": "instructor3@course1.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -428,7 +400,6 @@ "courseId": "idOfTypicalCourse2", "name": "Instructor3 Course2", "email": "instructor3@course2.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -452,7 +423,6 @@ "courseId": "idOfCourseNoEvals", "name": "Instructor4 name", "email": "instructor4@courseNoEvals.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -476,7 +446,6 @@ "courseId": "idOfUnregisteredCourse", "name": "Instructor 5 of CourseNoRegister", "email": "instructor5@courseNoRegister.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -500,31 +469,6 @@ "courseId": "idOfSampleCourse-demo", "name": "Instructor With Only One Sample Course", "email": "iwosc@yahoo.tmt", - "isArchived": false, - "role": "Co-owner", - "isDisplayedToStudents": true, - "displayedName": "Instructor", - "privileges": { - "courseLevel": { - "canViewStudentInSections": true, - "canSubmitSessionInSections": true, - "canModifySessionCommentsInSections": true, - "canModifyCourse": true, - "canViewSessionInSections": true, - "canModifySession": true, - "canModifyStudent": true, - "canModifyInstructor": true - }, - "sectionLevel": {}, - "sessionLevel": {} - } - }, - "instructorOfArchivedCourse": { - "googleId": "idOfInstructorOfArchivedCourse", - "courseId": "idOfArchivedCourse", - "name": "InstructorOfArchiveCourse name", - "email": "instructorOfArchiveCourse@archiveCourse.tmt", - "isArchived": true, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -548,7 +492,6 @@ "courseId": "idOfTestingInstructorsDisplayedCourse", "name": "name1", "email": "instructorNotDisplayed@NotDisplayed.tmt", - "isArchived": true, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -572,7 +515,6 @@ "courseId": "idOfTestingInstructorsDisplayedCourse", "name": "name2", "email": "secondInstructorNotDisplayed@NotDisplayed.tmt", - "isArchived": true, "role": "Co-owner", "isDisplayedToStudents": false, "displayedName": "Instructor", @@ -595,7 +537,6 @@ "courseId": "idOfSampleCourse-demo", "name": "Instructor Not Yet Joined Course", "email": "instructorNotYetJoined@email.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "Instructor", @@ -619,7 +560,6 @@ "courseId": "idOfTestingSanitizationCourse", "name": "Instructor", "email": "instructor1@sanitization.tmt", - "isArchived": false, "role": "Co-owner", "isDisplayedToStudents": true, "displayedName": "inst'\"/>", @@ -730,15 +670,6 @@ "team": "Team 2", "section": "Section 2" }, - "student1InArchivedCourse": { - "googleId": "student1InArchivedCourse", - "email": "student1InArchivedCourse@gmail.tmt", - "course": "idOfArchivedCourse", - "name": "student1 In Course1", - "comments": "", - "team": "Team 2.1", - "section": "None" - }, "student1InTestingSanitizationCourse": { "googleId": "student1InTestingSanitizationCourse", "email": "normal@sanitization.tmt", @@ -903,52 +834,6 @@ "studentDeadlines": {}, "instructorDeadlines": {} }, - "archiveCourse.session1": { - "feedbackSessionName": "session without student questions", - "courseId": "idOfArchivedCourse", - "creatorEmail": "instructor1@course1.tmt", - "instructions": "Please please fill in the following questions.", - "createdTime": "2013-01-20T23:00:00Z", - "startTime": "2013-02-20T23:00:00Z", - "endTime": "2026-04-28T23:00:00Z", - "sessionVisibleFromTime": "2013-02-20T23:00:00Z", - "resultsVisibleFromTime": "2026-04-29T23:00:00Z", - "timeZone": "Africa/Johannesburg", - "gracePeriod": 5, - "sentOpeningSoonEmail": true, - "sentOpenedEmail": true, - "sentClosingSoonEmail": true, - "sentClosedEmail": true, - "sentPublishedEmail": true, - "isOpenedEmailEnabled": true, - "isClosingSoonEmailEnabled": true, - "isPublishedEmailEnabled": true, - "studentDeadlines": {}, - "instructorDeadlines": {} - }, - "archiveCourse.session2": { - "feedbackSessionName": "session without instructor questions", - "courseId": "idOfArchivedCourse", - "creatorEmail": "instructor1@course1.tmt", - "instructions": "Please please fill in the following questions.", - "createdTime": "2013-01-20T23:00:00Z", - "startTime": "2013-02-20T23:00:00Z", - "endTime": "2026-04-28T23:00:00Z", - "sessionVisibleFromTime": "2013-02-20T23:00:00Z", - "resultsVisibleFromTime": "2026-04-29T23:00:00Z", - "timeZone": "Africa/Johannesburg", - "gracePeriod": 5, - "sentOpeningSoonEmail": true, - "sentOpenedEmail": true, - "sentClosingSoonEmail": false, - "sentClosedEmail": false, - "sentPublishedEmail": false, - "isOpenedEmailEnabled": true, - "isClosingSoonEmailEnabled": true, - "isPublishedEmailEnabled": true, - "studentDeadlines": {}, - "instructorDeadlines": {} - }, "session1InCourse2": { "feedbackSessionName": "Instructor feedback session", "courseId": "idOfTypicalCourse2", @@ -1386,48 +1271,6 @@ "RECEIVER" ] }, - "qn1InSessionInArchivedCourse": { - "feedbackSessionName": "session without student questions", - "courseId": "idOfArchivedCourse", - "questionDetails": { - "questionType": "TEXT", - "questionText": "Give feedback to students" - }, - "questionNumber": 1, - "giverType": "INSTRUCTORS", - "recipientType": "STUDENTS_EXCLUDING_SELF", - "numberOfEntitiesToGiveFeedbackTo": 4, - "showResponsesTo": [ - "RECEIVER" - ], - "showGiverNameTo": [ - "RECEIVER" - ], - "showRecipientNameTo": [ - "RECEIVER" - ] - }, - "qn1InSession2InArchivedCourse": { - "feedbackSessionName": "session without instructor questions", - "courseId": "idOfArchivedCourse", - "questionDetails": { - "questionType": "TEXT", - "questionText": "Give feedback to each other" - }, - "questionNumber": 1, - "giverType": "STUDENTS", - "recipientType": "STUDENTS_EXCLUDING_SELF", - "numberOfEntitiesToGiveFeedbackTo": 4, - "showResponsesTo": [ - "RECEIVER" - ], - "showGiverNameTo": [ - "RECEIVER" - ], - "showRecipientNameTo": [ - "RECEIVER" - ] - }, "qn1InSession1InCourse2": { "feedbackSessionName": "Instructor feedback session", "courseId": "idOfTypicalCourse2", @@ -1685,19 +1528,6 @@ "questionType": "TEXT", "answer": "Response from instr1InC2 to student1InC2." } - }, - "response1ForNVSQ1": { - "feedbackSessionName": "session without student questions", - "courseId": "idOfArchivedCourse", - "feedbackQuestionId": "1", - "giver": "instructorOfArchiveCourse@archiveCourse.tmt", - "recipient": "student1InArchivedCourse@gmail.tmt", - "giverSection": "None", - "recipientSection": "Section 1", - "responseDetails": { - "questionType": "TEXT", - "answer": "Response from instructor to student" - } } }, "feedbackResponseComments": { @@ -1955,13 +1785,6 @@ "createdAt": "2011-01-01T00:00:00Z", "registeredAt": "1970-02-14T00:00:00Z" }, - "instructorOfArchivedCourse": { - "name": "InstructorOfArchiveCourse name", - "email": "instructorOfArchiveCourse@archiveCourse.tmt", - "institute": "TEAMMATES Test Institute 5", - "createdAt": "2011-01-01T00:00:00Z", - "registeredAt": "1970-02-14T00:00:00Z" - }, "instructor1OfTestingSanitizationCourse": { "name": "Instructor", "email": "instructor1@sanitization.tmt", diff --git a/src/main/appengine/index.yaml b/src/main/appengine/index.yaml index b0be0e132758..c1b804ba4614 100644 --- a/src/main/appengine/index.yaml +++ b/src/main/appengine/index.yaml @@ -17,8 +17,6 @@ indexes: properties: - direction: asc name: googleId - - direction: asc - name: isArchived - kind: FeedbackSession properties: - direction: asc diff --git a/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/__snapshots__/copy-instructors-from-other-courses-modal.component.spec.ts.snap b/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/__snapshots__/copy-instructors-from-other-courses-modal.component.spec.ts.snap index 304359162020..089badd9bf8b 100644 --- a/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/__snapshots__/copy-instructors-from-other-courses-modal.component.spec.ts.snap +++ b/src/web/app/pages-instructor/instructor-course-edit-page/copy-instructors-from-other-courses-modal/__snapshots__/copy-instructors-from-other-courses-modal.component.spec.ts.snap @@ -70,12 +70,12 @@ exports[`CopyInstructorsFromOtherCoursesModalComponent should snap when feedback class="card" >

- [FAN0002] (Archived): Test Course 1 + [FAN0002]: Test Course 1
- [FAN0002] (Archived): Test Course 1 + [FAN0002]: Test Course 1
@@ -475,12 +475,12 @@ exports[`CopyInstructorsFromOtherCoursesModalComponent should snap when instruct class="card" >
- [FAN0002] (Archived): Test Course 1 + [FAN0002]: Test Course 1
- [FAN0002] (Archived): Test Course 1 + [FAN0002]: Test Course 1
-

-

- -
-
-
- Loading... -
-
- -
-

-

- -
-
-
- Loading... -
-
- -
Copy -
-

-

- -
-
-
- Loading... -
-
- -
-

-

-
- -
-
Copy -
-

-

- -
-
-
- Loading... -
-
- -
-

-

- -
-
-
- Loading... -
-
- -
Copy -
-

-

- -
-
-
- Loading... -
-
- -
{ expect(component.activeCourses.length).toEqual(3); expect(component.activeCourses[0].course.courseId).toEqual('CS1231'); expect(component.activeCourses[0].course.courseName).toEqual('Discrete Structures'); - expect(component.activeCourses[1].course.courseId).toEqual('CS3281'); - expect(component.activeCourses[1].course.courseName).toEqual('Thematic Systems Project I'); - expect(component.activeCourses[2].course.courseId).toEqual('CS3282'); - expect(component.activeCourses[2].course.courseName).toEqual('Thematic Systems Project II'); + expect(component.activeCourses[1].course.courseId).toEqual('CS3282'); + expect(component.activeCourses[1].course.courseName).toEqual('Thematic Systems Project II'); + expect(component.activeCourses[2].course.courseId).toEqual('CS3281'); + expect(component.activeCourses[2].course.courseName).toEqual('Thematic Systems Project I'); expect(component.softDeletedCourses.length).toEqual(1); expect(component.softDeletedCourses[0].course.courseId).toEqual('ST4234'); diff --git a/src/web/app/pages-instructor/instructor-home-page/__snapshots__/instructor-home-page.component.spec.ts.snap b/src/web/app/pages-instructor/instructor-home-page/__snapshots__/instructor-home-page.component.spec.ts.snap index a5ec0a38c2b6..1c4781fcbeac 100644 --- a/src/web/app/pages-instructor/instructor-home-page/__snapshots__/instructor-home-page.component.spec.ts.snap +++ b/src/web/app/pages-instructor/instructor-home-page/__snapshots__/instructor-home-page.component.spec.ts.snap @@ -514,14 +514,6 @@ exports[`InstructorHomePageComponent should snap with one course with one feedba class="dropdown-menu" ngbdropdownmenu="" > - - Archive - - - Archive - - - Archive - - - Archive - - - Archive -

- Note: The table above doesn't contain sessions from archived courses and courses in recycle bin. To view sessions from an archived course, unarchive the course first; to view sessions from a course in recycle bin, restore the course first. + Note: The table above doesn't contain sessions from courses in recycle bin. To view sessions from a course in recycle bin, restore the course first.

@@ -205,7 +205,7 @@ exports[`InstructorSessionsPageComponent should snap when feedback sessions are class="col-12 text-muted" >

- Note: The table above doesn't contain sessions from archived courses and courses in recycle bin. To view sessions from an archived course, unarchive the course first; to view sessions from a course in recycle bin, restore the course first. + Note: The table above doesn't contain sessions from courses in recycle bin. To view sessions from a course in recycle bin, restore the course first.

@@ -377,7 +377,7 @@ exports[`InstructorSessionsPageComponent should snap when new session form is ex > here - to create or unarchive a course. + to create a course.
@@ -1201,7 +1201,7 @@ exports[`InstructorSessionsPageComponent should snap when new session form is ex class="text-danger margin-top-20px" > - You need to have an active(unarchived) course to create a session! + You need to have an active course to create a session!

@@ -1243,7 +1243,7 @@ exports[`InstructorSessionsPageComponent should snap when new session form is ex class="col-12 text-muted" >

- Note: The table above doesn't contain sessions from archived courses and courses in recycle bin. To view sessions from an archived course, unarchive the course first; to view sessions from a course in recycle bin, restore the course first. + Note: The table above doesn't contain sessions from courses in recycle bin. To view sessions from a course in recycle bin, restore the course first.

@@ -1359,7 +1359,7 @@ exports[`InstructorSessionsPageComponent should snap when recycle bin section is class="col-12 text-muted" >

- Note: The table above doesn't contain sessions from archived courses and courses in recycle bin. To view sessions from an archived course, unarchive the course first; to view sessions from a course in recycle bin, restore the course first. + Note: The table above doesn't contain sessions from courses in recycle bin. To view sessions from a course in recycle bin, restore the course first.

@@ -1475,7 +1475,7 @@ exports[`InstructorSessionsPageComponent should snap with active sessions 1`] = class="col-12 text-muted" >

- Note: The table above doesn't contain sessions from archived courses and courses in recycle bin. To view sessions from an archived course, unarchive the course first; to view sessions from a course in recycle bin, restore the course first. + Note: The table above doesn't contain sessions from courses in recycle bin. To view sessions from a course in recycle bin, restore the course first.

@@ -1591,7 +1591,7 @@ exports[`InstructorSessionsPageComponent should snap with default fields 1`] = ` class="col-12 text-muted" >

- Note: The table above doesn't contain sessions from archived courses and courses in recycle bin. To view sessions from an archived course, unarchive the course first; to view sessions from a course in recycle bin, restore the course first. + Note: The table above doesn't contain sessions from courses in recycle bin. To view sessions from a course in recycle bin, restore the course first.

From 939a24e0b9a0e561a85c13e219ac5023127d475f Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Sun, 8 Feb 2026 15:53:12 +0800 Subject: [PATCH 11/17] Remove obsolete snapshot --- ...ructor-courses-page.component.spec.ts.snap | 112 ------------------ 1 file changed, 112 deletions(-) diff --git a/src/web/app/pages-instructor/instructor-courses-page/__snapshots__/instructor-courses-page.component.spec.ts.snap b/src/web/app/pages-instructor/instructor-courses-page/__snapshots__/instructor-courses-page.component.spec.ts.snap index 362a7c999322..6461615651c5 100644 --- a/src/web/app/pages-instructor/instructor-courses-page/__snapshots__/instructor-courses-page.component.spec.ts.snap +++ b/src/web/app/pages-instructor/instructor-courses-page/__snapshots__/instructor-courses-page.component.spec.ts.snap @@ -1,117 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`InstructorCoursesPageComponent should snap when courses are expanded 1`] = ` - -
- -
-
-

- Active courses -

- -
-
-
- Loading... -
-
- -
-
-
-

-

- -
-
-
- Loading... -
-
- -
-
- -`; - exports[`InstructorCoursesPageComponent should snap when courses are still loading 1`] = ` Date: Sun, 8 Feb 2026 16:40:14 +0800 Subject: [PATCH 12/17] Wait for table visibility --- src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java b/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java index c9788057fd8a..26fff16c8f86 100644 --- a/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java +++ b/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java @@ -50,6 +50,7 @@ public void verifyAccountDetails(AccountData account) { } public void clickRemoveInstructorFromCourse(String courseId) { + waitForElementVisibility(instructorTable); List instructorRows = instructorTable.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); @@ -69,6 +70,7 @@ public void clickRemoveInstructorFromCourse(String courseId) { } public void clickRemoveStudentFromCourse(String courseId) { + waitForElementVisibility(studentTable); List studentRows = studentTable.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); From 791bcb35fa8a23a0959873f9fc16ee725098fe8d Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Mon, 9 Feb 2026 12:56:32 +0800 Subject: [PATCH 13/17] Wait for page to load --- src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java b/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java index 26fff16c8f86..1e146812b92e 100644 --- a/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java +++ b/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java @@ -50,6 +50,7 @@ public void verifyAccountDetails(AccountData account) { } public void clickRemoveInstructorFromCourse(String courseId) { + waitForPageToLoad(); waitForElementVisibility(instructorTable); List instructorRows = instructorTable.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); @@ -70,6 +71,7 @@ public void clickRemoveInstructorFromCourse(String courseId) { } public void clickRemoveStudentFromCourse(String courseId) { + waitForPageToLoad(); waitForElementVisibility(studentTable); List studentRows = studentTable.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); From c2b25836bff9f44d0d9508ad8618a24a0417f9ea Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Mon, 9 Feb 2026 13:06:30 +0800 Subject: [PATCH 14/17] Wait for table and contents to load --- src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java b/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java index 1e146812b92e..660caea66e12 100644 --- a/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java +++ b/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java @@ -52,6 +52,8 @@ public void verifyAccountDetails(AccountData account) { public void clickRemoveInstructorFromCourse(String courseId) { waitForPageToLoad(); waitForElementVisibility(instructorTable); + // Wait for table to be populated with data + waitForElementVisibility(By.cssSelector("#instructor-table tbody tr")); List instructorRows = instructorTable.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); @@ -73,6 +75,8 @@ public void clickRemoveInstructorFromCourse(String courseId) { public void clickRemoveStudentFromCourse(String courseId) { waitForPageToLoad(); waitForElementVisibility(studentTable); + // Wait for table to be populated with data + waitForElementVisibility(By.cssSelector("#student-table tbody tr")); List studentRows = studentTable.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); From 42f7179902b88c0e49ffaed008c638ec6bacf2d8 Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Mon, 9 Feb 2026 13:31:26 +0800 Subject: [PATCH 15/17] Revert wait and fix bug in course service --- .../e2e/cases/sql/AdminAccountsPageE2ETest.java | 7 +++++++ .../e2e/pageobjects/AdminAccountsPage.java | 8 -------- src/web/services/course.service.ts | 13 ++----------- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java b/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java index 12c37afe75f2..23dae806f8d2 100644 --- a/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java +++ b/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java @@ -1,5 +1,6 @@ package teammates.e2e.cases.sql; +import org.testng.annotations.AfterClass; import org.testng.annotations.Test; import teammates.common.util.AppUrl; @@ -65,4 +66,10 @@ public void testAll() { verifyAbsentInDatabase(student2); verifyAbsentInDatabase(student3); } + + @AfterClass + public void classTeardown() { + // Restore test data that was deleted during the test to avoid affecting other tests + removeAndRestoreDataBundle(loadSqlDataBundle("/AdminAccountsPageE2ETestSql.json")); + } } diff --git a/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java b/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java index 660caea66e12..c9788057fd8a 100644 --- a/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java +++ b/src/e2e/java/teammates/e2e/pageobjects/AdminAccountsPage.java @@ -50,10 +50,6 @@ public void verifyAccountDetails(AccountData account) { } public void clickRemoveInstructorFromCourse(String courseId) { - waitForPageToLoad(); - waitForElementVisibility(instructorTable); - // Wait for table to be populated with data - waitForElementVisibility(By.cssSelector("#instructor-table tbody tr")); List instructorRows = instructorTable.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); @@ -73,10 +69,6 @@ public void clickRemoveInstructorFromCourse(String courseId) { } public void clickRemoveStudentFromCourse(String courseId) { - waitForPageToLoad(); - waitForElementVisibility(studentTable); - // Wait for table to be populated with data - waitForElementVisibility(By.cssSelector("#student-table tbody tr")); List studentRows = studentTable.findElement(By.tagName("tbody")).findElements(By.tagName("tr")); diff --git a/src/web/services/course.service.ts b/src/web/services/course.service.ts index d91879fe789f..bde8496dc9df 100644 --- a/src/web/services/course.service.ts +++ b/src/web/services/course.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core'; -import { forkJoin, Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; +import { Observable } from 'rxjs'; import { HttpRequestService } from './http-request.service'; import { ResourceEndpoints } from '../types/api-const'; import { Course, Courses, HasResponses, JoinStatus, MessageOutput, Student } from '../types/api-output'; @@ -96,15 +95,7 @@ export class CourseService { user: googleId, }; - return forkJoin([ - this.httpRequestService.get(ResourceEndpoints.COURSES, activeCoursesParamMap), - ]).pipe( - map((vals: Courses[]) => { - return { - courses: vals[0].courses.concat(vals[1].courses), - }; - }), - ); + return this.httpRequestService.get(ResourceEndpoints.COURSES, activeCoursesParamMap); } /** From 918a967155194b69235c09f3d7e0eb6de1e02a43 Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Mon, 9 Feb 2026 17:45:45 +0800 Subject: [PATCH 16/17] Revert class teardown --- .../e2e/cases/sql/AdminAccountsPageE2ETest.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java b/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java index 23dae806f8d2..dd4bdae7d5af 100644 --- a/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java +++ b/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java @@ -1,6 +1,5 @@ package teammates.e2e.cases.sql; -import org.testng.annotations.AfterClass; import org.testng.annotations.Test; import teammates.common.util.AppUrl; @@ -65,11 +64,4 @@ public void testAll() { // student entities should be deleted verifyAbsentInDatabase(student2); verifyAbsentInDatabase(student3); - } - - @AfterClass - public void classTeardown() { - // Restore test data that was deleted during the test to avoid affecting other tests - removeAndRestoreDataBundle(loadSqlDataBundle("/AdminAccountsPageE2ETestSql.json")); - } -} + }} From 92ba842306582895912085f96c43ad4d8bdbe35f Mon Sep 17 00:00:00 2001 From: YongJunXi Date: Mon, 9 Feb 2026 17:52:20 +0800 Subject: [PATCH 17/17] Fix checkstyle --- .../java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java b/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java index dd4bdae7d5af..12c37afe75f2 100644 --- a/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java +++ b/src/e2e/java/teammates/e2e/cases/sql/AdminAccountsPageE2ETest.java @@ -64,4 +64,5 @@ public void testAll() { // student entities should be deleted verifyAbsentInDatabase(student2); verifyAbsentInDatabase(student3); - }} + } +}