From 1d964a54fbbc980dbff2052ba65897ac840afff2 Mon Sep 17 00:00:00 2001 From: Respirayson Date: Sat, 22 Jun 2024 15:00:32 +0800 Subject: [PATCH 1/5] Add spinners for approve, reject and reset in account-request-table --- .../account-request-table.component.html | 6 ++--- .../account-request-table.component.ts | 24 ++++++++++++++++++- .../account-request-table.module.ts | 2 ++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/web/app/components/account-requests-table/account-request-table.component.html b/src/web/app/components/account-requests-table/account-request-table.component.html index 924cb5592d0..175165e117b 100644 --- a/src/web/app/components/account-requests-table/account-request-table.component.html +++ b/src/web/app/components/account-requests-table/account-request-table.component.html @@ -66,16 +66,16 @@ - + - +
- +
diff --git a/src/web/app/components/account-requests-table/account-request-table.component.ts b/src/web/app/components/account-requests-table/account-request-table.component.ts index 3e7fc957730..911fb49a3bb 100755 --- a/src/web/app/components/account-requests-table/account-request-table.component.ts +++ b/src/web/app/components/account-requests-table/account-request-table.component.ts @@ -36,6 +36,10 @@ export class AccountRequestTableComponent { @Input() searchString = ''; + isRejectingAccount: boolean = false; + isApprovingAccount: boolean = false; + isResettingAccount: boolean = false; + constructor( private statusMessageService: StatusMessageService, private simpleModalService: SimpleModalService, @@ -95,6 +99,7 @@ export class AccountRequestTableComponent { } approveAccountRequest(accountRequest: AccountRequestTableRowModel): void { + this.isApprovingAccount = true; this.accountService.approveAccountRequest(accountRequest.id, accountRequest.name, accountRequest.email, accountRequest.instituteAndCountry) .subscribe({ @@ -103,21 +108,26 @@ export class AccountRequestTableComponent { this.statusMessageService.showSuccessToast( `Account request was successfully approved. Email has been sent to ${accountRequest.email}.`, ); + this.isApprovingAccount = false; }, error: (resp: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(resp.error.message); + this.isApprovingAccount = false; }, }); } resetAccountRequest(accountRequest: AccountRequestTableRowModel): void { + this.isResettingAccount = true; const modalContent = `Are you sure you want to reset the account request for ${accountRequest.name} with email ${accountRequest.email} from ${accountRequest.instituteAndCountry}? An email with the account registration link will also be sent to the instructor.`; const modalRef: NgbModalRef = this.simpleModalService.openConfirmationModal( `Reset account request for ${accountRequest.name}?`, SimpleModalType.WARNING, modalContent); - + modalRef.dismissed.subscribe(() => { + this.isResettingAccount = false; + }); modalRef.result.then(() => { this.accountService.resetAccountRequest(accountRequest.id) .subscribe({ @@ -125,9 +135,11 @@ export class AccountRequestTableComponent { this.statusMessageService .showSuccessToast(`Reset successful. An email has been sent to ${accountRequest.email}.`); accountRequest.registeredAtText = ''; + this.isResettingAccount = false; }, error: (resp: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(resp.error.message); + this.isResettingAccount = false; }, }); }, () => {}); @@ -163,23 +175,31 @@ export class AccountRequestTableComponent { } rejectAccountRequest(accountRequest: AccountRequestTableRowModel): void { + this.isRejectingAccount = true; this.accountService.rejectAccountRequest(accountRequest.id) .subscribe({ next: (resp : AccountRequest) => { accountRequest.status = resp.status; this.statusMessageService.showSuccessToast('Account request was successfully rejected.'); + this.isRejectingAccount = false; }, error: (resp: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(resp.error.message); + this.isRejectingAccount = false; }, }); } rejectAccountRequestWithReason(accountRequest: AccountRequestTableRowModel): void { + this.isRejectingAccount = true; const modalRef: NgbModalRef = this.ngbModal.open(RejectWithReasonModalComponent); modalRef.componentInstance.accountRequestName = accountRequest.name; modalRef.componentInstance.accountRequestEmail = accountRequest.email; + modalRef.dismissed.subscribe(() => { + this.isRejectingAccount = false; + }); + modalRef.result.then((res: RejectWithReasonModalComponentResult) => { this.accountService.rejectAccountRequest(accountRequest.id, res.rejectionReasonTitle, res.rejectionReasonBody) @@ -189,9 +209,11 @@ export class AccountRequestTableComponent { this.statusMessageService.showSuccessToast( `Account request was successfully rejected. Email has been sent to ${accountRequest.email}.`, ); + this.isRejectingAccount = false; }, error: (resp: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(resp.error.message); + this.isRejectingAccount = false; }, }); }, () => {}); diff --git a/src/web/app/components/account-requests-table/account-request-table.module.ts b/src/web/app/components/account-requests-table/account-request-table.module.ts index 2ff431b1021..eb0768663a9 100644 --- a/src/web/app/components/account-requests-table/account-request-table.module.ts +++ b/src/web/app/components/account-requests-table/account-request-table.module.ts @@ -8,6 +8,7 @@ import { RejectWithReasonModalComponent, } from './admin-reject-with-reason-modal/admin-reject-with-reason-modal.component'; import { Pipes } from '../../pipes/pipes.module'; +import { AjaxLoadingModule } from '../ajax-loading/ajax-loading.module'; import { RichTextEditorModule } from '../rich-text-editor/rich-text-editor.module'; /** @@ -29,6 +30,7 @@ import { RichTextEditorModule } from '../rich-text-editor/rich-text-editor.modul NgbDropdownModule, Pipes, RichTextEditorModule, + AjaxLoadingModule, ], }) export class AccountRequestTableModule { } From b16c2530dd372760a200fdc1beea0ebb0b8cc0f7 Mon Sep 17 00:00:00 2001 From: Respirayson Date: Sun, 23 Jun 2024 13:38:13 +0800 Subject: [PATCH 2/5] Add spinners to regenerate keys in admin-search-page --- .../admin-search-page.component.html | 4 ++-- .../admin-search-page.component.ts | 24 +++++++++++++++++-- .../admin-search-page.module.ts | 2 ++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.html b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.html index 8084c47362c..e17839a6d2f 100644 --- a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.html +++ b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.html @@ -64,7 +64,7 @@ Reset Google ID
- + @@ -159,7 +159,7 @@ Reset Google ID
- + diff --git a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts index 08b577d788c..60fd7093e81 100755 --- a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts +++ b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts @@ -43,6 +43,9 @@ export class AdminSearchPageComponent { accountRequests: AccountRequestTableRowModel[] = []; characterLimit = 100; + isRegeneratingInstructorKeys: boolean[] = []; + isRegeneratingStudentKeys: boolean[] = []; + constructor( private statusMessageService: StatusMessageService, private simpleModalService: SimpleModalService, @@ -83,6 +86,9 @@ export class AdminSearchPageComponent { this.hideAllInstructorsLinks(); this.hideAllStudentsLinks(); + this.isRegeneratingInstructorKeys = new Array(this.instructors.length).fill(false); + this.isRegeneratingStudentKeys = new Array(this.students.length).fill(false); + // prompt user to use more specific terms if search results limit reached const limit: number = ApiConst.SEARCH_QUERY_SIZE_LIMIT; const limitsReached: string[] = []; @@ -222,22 +228,29 @@ export class AdminSearchPageComponent { /** * Regenerates the student's registration key. */ - regenerateStudentKey(student: StudentAccountSearchResult): void { + regenerateStudentKey(student: StudentAccountSearchResult, index: number): void { + this.isRegeneratingStudentKeys[index] = true; const modalContent: string = `Are you sure you want to regenerate the registration key for ${student.name} for the course ${student.courseId}? An email will be sent to the student with all the new course registration and feedback session links.`; const modalRef: NgbModalRef = this.simpleModalService.openConfirmationModal( `Regenerate ${student.name}'s course links?`, SimpleModalType.WARNING, modalContent); + modalRef.dismissed.subscribe(() => { + this.isRegeneratingStudentKeys[index] = false; + }); + modalRef.result.then(() => { this.studentService.regenerateStudentKey(student.courseId, student.email) .subscribe({ next: (resp: RegenerateKey) => { this.statusMessageService.showSuccessToast(resp.message); this.updateDisplayedStudentCourseLinks(student, resp.newRegistrationKey); + this.isRegeneratingStudentKeys[index] = false; }, error: (response: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(response.error.message); + this.isRegeneratingStudentKeys[index] = false; }, }); }, () => {}); @@ -246,22 +259,29 @@ export class AdminSearchPageComponent { /** * Regenerates the instructor's registration key. */ - regenerateInstructorKey(instructor: InstructorAccountSearchResult): void { + regenerateInstructorKey(instructor: InstructorAccountSearchResult, index: number): void { + this.isRegeneratingInstructorKeys[index] = true; const modalContent: string = `Are you sure you want to regenerate the registration key for ${instructor.name} for the course ${instructor.courseId}? An email will be sent to the instructor with all the new course registration and feedback session links.`; const modalRef: NgbModalRef = this.simpleModalService.openConfirmationModal( `Regenerate ${instructor.name}'s course links?`, SimpleModalType.WARNING, modalContent); + modalRef.dismissed.subscribe(() => { + this.isRegeneratingInstructorKeys[index] = false; + }); + modalRef.result.then(() => { this.instructorService.regenerateInstructorKey(instructor.courseId, instructor.email) .subscribe({ next: (resp: RegenerateKey) => { this.statusMessageService.showSuccessToast(resp.message); this.updateDisplayedInstructorCourseLinks(instructor, resp.newRegistrationKey); + this.isRegeneratingInstructorKeys[index] = false; }, error: (response: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(response.error.message); + this.isRegeneratingInstructorKeys[index] = false; }, }); }, () => {}); diff --git a/src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts b/src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts index 6b70a93077a..4447f2bc5f1 100644 --- a/src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts +++ b/src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts @@ -8,6 +8,7 @@ import { AccountRequestTableModule, } from '../../components/account-requests-table/account-request-table.module'; import { Pipes } from '../../pipes/pipes.module'; +import { AjaxLoadingModule } from '../../components/ajax-loading/ajax-loading.module'; const routes: Routes = [ { @@ -33,6 +34,7 @@ const routes: Routes = [ AccountRequestTableModule, RouterModule.forChild(routes), Pipes, + AjaxLoadingModule, ], }) export class AdminSearchPageModule { } From 74b1ec409e595768efe53e1d9dad9333b99cf50b Mon Sep 17 00:00:00 2001 From: Respirayson Date: Sun, 23 Jun 2024 14:14:27 +0800 Subject: [PATCH 3/5] Update spinners in account-request-table to work individually --- .../account-request-table.component.html | 10 ++--- .../account-request-table.component.ts | 42 +++++++++---------- .../admin-search-page.component.ts | 6 +-- .../admin-search-page.module.ts | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/web/app/components/account-requests-table/account-request-table.component.html b/src/web/app/components/account-requests-table/account-request-table.component.html index 175165e117b..979b20c4ec5 100644 --- a/src/web/app/components/account-requests-table/account-request-table.component.html +++ b/src/web/app/components/account-requests-table/account-request-table.component.html @@ -66,16 +66,16 @@ - + - +
- - + +
- +
diff --git a/src/web/app/components/account-requests-table/account-request-table.component.ts b/src/web/app/components/account-requests-table/account-request-table.component.ts index 911fb49a3bb..1bb241ed261 100755 --- a/src/web/app/components/account-requests-table/account-request-table.component.ts +++ b/src/web/app/components/account-requests-table/account-request-table.component.ts @@ -36,9 +36,9 @@ export class AccountRequestTableComponent { @Input() searchString = ''; - isRejectingAccount: boolean = false; - isApprovingAccount: boolean = false; - isResettingAccount: boolean = false; + isRejectingAccount: boolean[] = new Array(this.accountRequests.length).fill(false); + isApprovingAccount: boolean[] = new Array(this.accountRequests.length).fill(false); + isResettingAccount: boolean[] = new Array(this.accountRequests.length).fill(false); constructor( private statusMessageService: StatusMessageService, @@ -98,8 +98,8 @@ export class AccountRequestTableComponent { }, () => {}); } - approveAccountRequest(accountRequest: AccountRequestTableRowModel): void { - this.isApprovingAccount = true; + approveAccountRequest(accountRequest: AccountRequestTableRowModel, index: number): void { + this.isApprovingAccount[index] = true; this.accountService.approveAccountRequest(accountRequest.id, accountRequest.name, accountRequest.email, accountRequest.instituteAndCountry) .subscribe({ @@ -108,17 +108,17 @@ export class AccountRequestTableComponent { this.statusMessageService.showSuccessToast( `Account request was successfully approved. Email has been sent to ${accountRequest.email}.`, ); - this.isApprovingAccount = false; + this.isApprovingAccount[index] = false; }, error: (resp: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(resp.error.message); - this.isApprovingAccount = false; + this.isApprovingAccount[index] = false; }, }); } - resetAccountRequest(accountRequest: AccountRequestTableRowModel): void { - this.isResettingAccount = true; + resetAccountRequest(accountRequest: AccountRequestTableRowModel, index: number): void { + this.isResettingAccount[index] = true; const modalContent = `Are you sure you want to reset the account request for ${accountRequest.name} with email ${accountRequest.email} from ${accountRequest.instituteAndCountry}? @@ -126,7 +126,7 @@ export class AccountRequestTableComponent { const modalRef: NgbModalRef = this.simpleModalService.openConfirmationModal( `Reset account request for ${accountRequest.name}?`, SimpleModalType.WARNING, modalContent); modalRef.dismissed.subscribe(() => { - this.isResettingAccount = false; + this.isResettingAccount[index] = false; }); modalRef.result.then(() => { this.accountService.resetAccountRequest(accountRequest.id) @@ -135,11 +135,11 @@ export class AccountRequestTableComponent { this.statusMessageService .showSuccessToast(`Reset successful. An email has been sent to ${accountRequest.email}.`); accountRequest.registeredAtText = ''; - this.isResettingAccount = false; + this.isResettingAccount[index] = false; }, error: (resp: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(resp.error.message); - this.isResettingAccount = false; + this.isResettingAccount[index] = false; }, }); }, () => {}); @@ -174,30 +174,30 @@ export class AccountRequestTableComponent { modalRef.result.then(() => {}, () => {}); } - rejectAccountRequest(accountRequest: AccountRequestTableRowModel): void { - this.isRejectingAccount = true; + rejectAccountRequest(accountRequest: AccountRequestTableRowModel, index: number): void { + this.isRejectingAccount[index] = true; this.accountService.rejectAccountRequest(accountRequest.id) .subscribe({ next: (resp : AccountRequest) => { accountRequest.status = resp.status; this.statusMessageService.showSuccessToast('Account request was successfully rejected.'); - this.isRejectingAccount = false; + this.isRejectingAccount[index] = false; }, error: (resp: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(resp.error.message); - this.isRejectingAccount = false; + this.isRejectingAccount[index] = false; }, }); } - rejectAccountRequestWithReason(accountRequest: AccountRequestTableRowModel): void { - this.isRejectingAccount = true; + rejectAccountRequestWithReason(accountRequest: AccountRequestTableRowModel, index: number): void { + this.isRejectingAccount[index] = true; const modalRef: NgbModalRef = this.ngbModal.open(RejectWithReasonModalComponent); modalRef.componentInstance.accountRequestName = accountRequest.name; modalRef.componentInstance.accountRequestEmail = accountRequest.email; modalRef.dismissed.subscribe(() => { - this.isRejectingAccount = false; + this.isRejectingAccount[index] = false; }); modalRef.result.then((res: RejectWithReasonModalComponentResult) => { @@ -209,11 +209,11 @@ export class AccountRequestTableComponent { this.statusMessageService.showSuccessToast( `Account request was successfully rejected. Email has been sent to ${accountRequest.email}.`, ); - this.isRejectingAccount = false; + this.isRejectingAccount[index] = false; }, error: (resp: ErrorMessageOutput) => { this.statusMessageService.showErrorToast(resp.error.message); - this.isRejectingAccount = false; + this.isRejectingAccount[index] = false; }, }); }, () => {}); diff --git a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts index 60fd7093e81..ede96196a81 100755 --- a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts +++ b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.ts @@ -239,7 +239,7 @@ export class AdminSearchPageComponent { modalRef.dismissed.subscribe(() => { this.isRegeneratingStudentKeys[index] = false; }); - + modalRef.result.then(() => { this.studentService.regenerateStudentKey(student.courseId, student.email) .subscribe({ @@ -269,8 +269,8 @@ export class AdminSearchPageComponent { modalRef.dismissed.subscribe(() => { this.isRegeneratingInstructorKeys[index] = false; - }); - + }); + modalRef.result.then(() => { this.instructorService.regenerateInstructorKey(instructor.courseId, instructor.email) .subscribe({ diff --git a/src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts b/src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts index 4447f2bc5f1..71925363326 100644 --- a/src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts +++ b/src/web/app/pages-admin/admin-search-page/admin-search-page.module.ts @@ -7,8 +7,8 @@ import { AdminSearchPageComponent } from './admin-search-page.component'; import { AccountRequestTableModule, } from '../../components/account-requests-table/account-request-table.module'; -import { Pipes } from '../../pipes/pipes.module'; import { AjaxLoadingModule } from '../../components/ajax-loading/ajax-loading.module'; +import { Pipes } from '../../pipes/pipes.module'; const routes: Routes = [ { From 50d51805bc4cd09e7080e0430bf7be3ac301be77 Mon Sep 17 00:00:00 2001 From: Respirayson Date: Sun, 23 Jun 2024 17:12:15 +0800 Subject: [PATCH 4/5] Update tests --- ...count-request-table.component.spec.ts.snap | 9 ++++ .../account-request-table.component.spec.ts | 27 ++++++++--- .../account-request-table.component.ts | 2 + .../admin-search-page.component.spec.ts.snap | 10 ++++ .../admin-search-page.component.spec.ts | 48 ++++++++++++++----- 5 files changed, 78 insertions(+), 18 deletions(-) diff --git a/src/web/app/components/account-requests-table/__snapshots__/account-request-table.component.spec.ts.snap b/src/web/app/components/account-requests-table/__snapshots__/account-request-table.component.spec.ts.snap index bbf59a6a945..3b8d24519c6 100644 --- a/src/web/app/components/account-requests-table/__snapshots__/account-request-table.component.spec.ts.snap +++ b/src/web/app/components/account-requests-table/__snapshots__/account-request-table.component.spec.ts.snap @@ -4,6 +4,9 @@ exports[`AccountRequestTableComponent should display account requests with no re { component.searchString = 'test'; fixture.detectChanges(); - const modalSpy = jest.spyOn(simpleModalService, 'openConfirmationModal').mockImplementation(() => { - return createMockNgbModalRef({}); - }); + const mockModalRef = { + componentInstance: {}, + result: Promise.resolve({}), + dismissed: { + subscribe: jest.fn(), + }, + }; + + const modalSpy = jest.spyOn(simpleModalService, 'openConfirmationModal').mockReturnValue(mockModalRef as any); jest.spyOn(accountService, 'resetAccountRequest').mockReturnValue(of({ joinLink: 'joinlink', @@ -245,9 +251,15 @@ describe('AccountRequestTableComponent', () => { component.searchString = 'test'; fixture.detectChanges(); - const modalSpy = jest.spyOn(simpleModalService, 'openConfirmationModal').mockImplementation(() => { - return createMockNgbModalRef({}); - }); + const mockModalRef = { + componentInstance: {}, + result: Promise.resolve({}), + dismissed: { + subscribe: jest.fn(), + }, + }; + + const modalSpy = jest.spyOn(simpleModalService, 'openConfirmationModal').mockReturnValue(mockModalRef as any); jest.spyOn(accountService, 'resetAccountRequest').mockReturnValue(throwError(() => ({ error: { @@ -318,6 +330,9 @@ describe('AccountRequestTableComponent', () => { const mockModalRef = { componentInstance: {}, result: Promise.resolve({}), + dismissed: { + subscribe: jest.fn(), + }, }; const modalSpy = jest.spyOn(ngbModal, 'open').mockReturnValue(mockModalRef as any); diff --git a/src/web/app/components/account-requests-table/account-request-table.component.ts b/src/web/app/components/account-requests-table/account-request-table.component.ts index 1bb241ed261..7634dfc58e1 100755 --- a/src/web/app/components/account-requests-table/account-request-table.component.ts +++ b/src/web/app/components/account-requests-table/account-request-table.component.ts @@ -125,9 +125,11 @@ export class AccountRequestTableComponent { An email with the account registration link will also be sent to the instructor.`; const modalRef: NgbModalRef = this.simpleModalService.openConfirmationModal( `Reset account request for ${accountRequest.name}?`, SimpleModalType.WARNING, modalContent); + modalRef.dismissed.subscribe(() => { this.isResettingAccount[index] = false; }); + modalRef.result.then(() => { this.accountService.resetAccountRequest(accountRequest.id) .subscribe({ diff --git a/src/web/app/pages-admin/admin-search-page/__snapshots__/admin-search-page.component.spec.ts.snap b/src/web/app/pages-admin/admin-search-page/__snapshots__/admin-search-page.component.spec.ts.snap index 58f15f5a35d..ded3505ea4b 100644 --- a/src/web/app/pages-admin/admin-search-page/__snapshots__/admin-search-page.component.spec.ts.snap +++ b/src/web/app/pages-admin/admin-search-page/__snapshots__/admin-search-page.component.spec.ts.snap @@ -8,6 +8,8 @@ exports[`AdminSearchPageComponent should snap with a deleted course 1`] = ` emailGenerationService={[Function EmailGenerationService]} instructorService={[Function InstructorService]} instructors={[Function Array]} + isRegeneratingInstructorKeys={[Function Array]} + isRegeneratingStudentKeys={[Function Array]} loadingBarService={[Function LoadingBarService]} searchQuery="" searchService={[Function SearchService]} @@ -339,6 +341,8 @@ exports[`AdminSearchPageComponent should snap with a search key 1`] = ` emailGenerationService={[Function EmailGenerationService]} instructorService={[Function InstructorService]} instructors={[Function Array]} + isRegeneratingInstructorKeys={[Function Array]} + isRegeneratingStudentKeys={[Function Array]} loadingBarService={[Function LoadingBarService]} searchQuery={[Function String]} searchService={[Function SearchService]} @@ -392,6 +396,8 @@ exports[`AdminSearchPageComponent should snap with an expanded instructor table emailGenerationService={[Function EmailGenerationService]} instructorService={[Function InstructorService]} instructors={[Function Array]} + isRegeneratingInstructorKeys={[Function Array]} + isRegeneratingStudentKeys={[Function Array]} loadingBarService={[Function LoadingBarService]} searchQuery="" searchService={[Function SearchService]} @@ -649,6 +655,8 @@ exports[`AdminSearchPageComponent should snap with an expanded student table 1`] emailGenerationService={[Function EmailGenerationService]} instructorService={[Function InstructorService]} instructors={[Function Array]} + isRegeneratingInstructorKeys={[Function Array]} + isRegeneratingStudentKeys={[Function Array]} loadingBarService={[Function LoadingBarService]} searchQuery="" searchService={[Function SearchService]} @@ -955,6 +963,8 @@ exports[`AdminSearchPageComponent should snap with default fields 1`] = ` emailGenerationService={[Function EmailGenerationService]} instructorService={[Function InstructorService]} instructors={[Function Array]} + isRegeneratingInstructorKeys={[Function Array]} + isRegeneratingStudentKeys={[Function Array]} loadingBarService={[Function LoadingBarService]} searchQuery="" searchService={[Function SearchService]} diff --git a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.spec.ts b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.spec.ts index 143b3ca9d75..da5b794b03f 100644 --- a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.spec.ts +++ b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.spec.ts @@ -607,9 +607,15 @@ describe('AdminSearchPageComponent', () => { component.students = [studentResult]; fixture.detectChanges(); - jest.spyOn(ngbModal, 'open').mockImplementation(() => { - return createMockNgbModalRef({}); - }); + const mockModalRef = { + componentInstance: {}, + result: Promise.resolve({}), + dismissed: { + subscribe: jest.fn(), + }, + }; + + jest.spyOn(ngbModal, 'open').mockReturnValue(mockModalRef as any); jest.spyOn(studentService, 'regenerateStudentKey').mockReturnValue(of({ message: 'success', @@ -669,9 +675,15 @@ describe('AdminSearchPageComponent', () => { component.students = [studentResult]; fixture.detectChanges(); - jest.spyOn(ngbModal, 'open').mockImplementation(() => { - return createMockNgbModalRef({}); - }); + const mockModalRef = { + componentInstance: {}, + result: Promise.resolve({}), + dismissed: { + subscribe: jest.fn(), + }, + }; + + jest.spyOn(ngbModal, 'open').mockReturnValue(mockModalRef as any); jest.spyOn(studentService, 'regenerateStudentKey').mockReturnValue(throwError(() => ({ error: { @@ -698,9 +710,15 @@ describe('AdminSearchPageComponent', () => { component.instructors = [instructorResult]; fixture.detectChanges(); - jest.spyOn(ngbModal, 'open').mockImplementation(() => { - return createMockNgbModalRef({}); - }); + const mockModalRef = { + componentInstance: {}, + result: Promise.resolve({}), + dismissed: { + subscribe: jest.fn(), + }, + }; + + jest.spyOn(ngbModal, 'open').mockReturnValue(mockModalRef as any); jest.spyOn(instructorService, 'regenerateInstructorKey').mockReturnValue(of({ message: 'success', @@ -728,9 +746,15 @@ describe('AdminSearchPageComponent', () => { component.instructors = [instructorResult]; fixture.detectChanges(); - jest.spyOn(ngbModal, 'open').mockImplementation(() => { - return createMockNgbModalRef({}); - }); + const mockModalRef = { + componentInstance: {}, + result: Promise.resolve({}), + dismissed: { + subscribe: jest.fn(), + }, + }; + + jest.spyOn(ngbModal, 'open').mockReturnValue(mockModalRef as any); jest.spyOn(instructorService, 'regenerateInstructorKey').mockReturnValue(throwError(() => ({ error: { From 1de60ac68d53b99f514c5826db7be3a54a3ab516 Mon Sep 17 00:00:00 2001 From: Respirayson Date: Sun, 30 Jun 2024 03:44:23 +0800 Subject: [PATCH 5/5] Update buttons to be disabled while loading --- .../account-request-table.component.html | 6 +++--- .../admin-search-page/admin-search-page.component.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/web/app/components/account-requests-table/account-request-table.component.html b/src/web/app/components/account-requests-table/account-request-table.component.html index 979b20c4ec5..0c6c70a1ed9 100644 --- a/src/web/app/components/account-requests-table/account-request-table.component.html +++ b/src/web/app/components/account-requests-table/account-request-table.component.html @@ -66,16 +66,16 @@ - + - +
- +
diff --git a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.html b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.html index e17839a6d2f..eb4e8c3ad43 100644 --- a/src/web/app/pages-admin/admin-search-page/admin-search-page.component.html +++ b/src/web/app/pages-admin/admin-search-page/admin-search-page.component.html @@ -64,7 +64,7 @@ Reset Google ID
- + @@ -159,7 +159,7 @@ Reset Google ID
- +