Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development: Replace deprecated before unload event with pending changes guard #9479

Merged
merged 20 commits into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d4d9648
remove beforeunload from exam-participation.component.ts
coolchock Oct 14, 2024
0ea5bb1
remove beforeunload from quiz-exercise-update.component.ts^
coolchock Oct 14, 2024
880503a
remove beforeunload from modeling-submission.component.ts
coolchock Oct 14, 2024
35d25ee
remove beforeunload from import-course-competencies.component.ts
coolchock Oct 14, 2024
1ee2088
remove beforeunload from course-import-standardized-course-competenci…
coolchock Oct 14, 2024
26554d1
remove beforeunload from generate-competencies.component.ts
coolchock Oct 14, 2024
1b27b74
remove beforeunload from standardized-competency-management.component.ts
coolchock Oct 14, 2024
f7e17dd
replace beforeunload in text-editor.component.ts
coolchock Oct 14, 2024
8fe1529
remove deprecated beforeunload event from code-editor-container.compo…
coolchock Oct 14, 2024
e742a5c
adjust course-import-standardized-competencies.spec.ts
coolchock Oct 14, 2024
8e61617
course-import-standardized-prerequisites.spec.ts
coolchock Oct 14, 2024
c49b9dd
adjust exam-participation.component.spec.ts
coolchock Oct 14, 2024
6e29ffe
adjust generate-competencies.component.spec.ts
coolchock Oct 14, 2024
3fde2d4
adjust import-course-competencies.component.spec.ts
coolchock Oct 14, 2024
161d075
adjust quiz-exercise-update.component.spec.ts
coolchock Oct 14, 2024
fe33a48
adjust standardized-competency-management.spec.ts
coolchock Oct 14, 2024
4a678ec
Merge branch 'refs/heads/develop' into chore/replace-deprecated-unloa…
coolchock Oct 20, 2024
63edb35
update descriptions of tests in quiz-exercise-update.component.spec.ts
coolchock Oct 20, 2024
2e696fd
update test descriptions in generate-competencies.component.spec.ts
coolchock Oct 20, 2024
93fadcd
Merge branch 'develop' into chore/replace-deprecated-unload-events
krusche Oct 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/webapp/app/admin/admin.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { BuildAgentSummaryComponent } from 'app/localci/build-agents/build-agent
import { StandardizedCompetencyManagementComponent } from 'app/admin/standardized-competencies/standardized-competency-management.component';
import { BuildAgentDetailsComponent } from 'app/localci/build-agents/build-agent-details/build-agent-details/build-agent-details.component';
import { AdminImportStandardizedCompetenciesComponent } from 'app/admin/standardized-competencies/import/admin-import-standardized-competencies.component';
import { PendingChangesGuard } from 'app/shared/guard/pending-changes.guard';

export const adminState: Routes = [
{
Expand Down Expand Up @@ -116,6 +117,7 @@ export const adminState: Routes = [
data: {
pageTitle: 'artemisApp.standardizedCompetency.title',
},
canDeactivate: [PendingChangesGuard],
},
{
// Create a new path without a component defined to prevent the StandardizedCompetencyManagementComponent from being always rendered
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, OnDestroy, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { faChevronRight, faDownLeftAndUpRightToCenter, faEye, faFileExport, faFileImport, faPlus, faUpRightAndDownLeftFromCenter } from '@fortawesome/free-solid-svg-icons';
import {
KnowledgeAreaDTO,
Expand Down Expand Up @@ -576,14 +576,4 @@ export class StandardizedCompetencyManagementComponent extends StandardizedCompe
get canDeactivateWarning(): string {
return this.translateService.instant('pendingChanges');
}

/**
* Displays the alert for confirming refreshing or closing the page if there are unsaved changes
*/
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any) {
if (!this.canDeactivate()) {
event.returnValue = this.canDeactivateWarning;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, HostListener, OnInit, ViewChild } from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { CompetencyService } from 'app/course/competencies/competency.service';
import { AlertService } from 'app/core/util/alert.service';
import { onError } from 'app/shared/util/global.utils';
Expand Down Expand Up @@ -249,14 +249,4 @@ export class GenerateCompetenciesComponent implements OnInit, ComponentCanDeacti
get canDeactivateWarning(): string {
return this.translateService.instant('pendingChanges');
}

/**
* Only allow to refresh the page if no pending changes exist
*/
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any) {
if (!this.canDeactivate()) {
event.returnValue = this.canDeactivateWarning;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
} from 'app/entities/competency/standardized-competency.model';
import { faBan, faDownLeftAndUpRightToCenter, faFileImport, faSort, faTrash, faUpRightAndDownLeftFromCenter } from '@fortawesome/free-solid-svg-icons';
import { ActivatedRoute, Router } from '@angular/router';
import { Component, HostListener, OnInit } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { onError } from 'app/shared/util/global.utils';
import { forkJoin, map } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
Expand Down Expand Up @@ -168,16 +168,6 @@ export abstract class CourseImportStandardizedCourseCompetenciesComponent extend
return this.translateService.instant('pendingChanges');
}

/**
* Displays the alert for confirming refreshing or closing the page if there are unsaved changes
*/
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any) {
if (!this.canDeactivate()) {
event.returnValue = this.canDeactivateWarning;
}
}

private convertToKnowledgeAreaForImport(knowledgeAreaDTO: KnowledgeAreaDTO, isVisible = true, level = 0, selected = false): KnowledgeAreaForImport {
const children = knowledgeAreaDTO.children?.map((child) => this.convertToKnowledgeAreaForImport(child, isVisible, level + 1));
const competencies = knowledgeAreaDTO.competencies?.map((competency) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CourseCompetency, CourseCompetencyType } from 'app/entities/competency.
import { AlertService } from 'app/core/util/alert.service';
import { SortService } from 'app/shared/service/sort.service';
import { onError } from 'app/shared/util/global.utils';
import { Component, HostListener, OnInit, inject } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
coolchock marked this conversation as resolved.
Show resolved Hide resolved
import { faBan, faFileImport, faSave, faTrash } from '@fortawesome/free-solid-svg-icons';
import { ButtonType } from 'app/shared/components/button.component';
import { ActivatedRoute, Router } from '@angular/router';
Expand Down Expand Up @@ -204,14 +204,4 @@ export abstract class ImportCourseCompetenciesComponent implements OnInit, Compo
get canDeactivateWarning(): string {
return this.translateService.instant('pendingChanges');
}

/**
* Displays the alert for confirming refreshing or closing the page if there are unsaved changes
*/
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any) {
if (!this.canDeactivate()) {
event.returnValue = this.canDeactivateWarning;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, HostListener, OnDestroy, OnInit, QueryList, ViewChildren } from '@angular/core';
import { Component, OnDestroy, OnInit, QueryList, ViewChildren } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { JhiWebsocketService } from 'app/core/websocket/websocket.service';
import { ExamParticipationService } from 'app/exam/participate/exam-participation.service';
Expand Down Expand Up @@ -246,14 +246,6 @@ export class ExamParticipationComponent implements OnInit, OnDestroy, ComponentC
return this.translateService.instant('artemisApp.examParticipation.pendingChanges');
}

// displays the alert for confirming leaving the page if there are unsaved changes
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any): void {
if (!this.canDeactivate()) {
event.returnValue = this.canDeactivateWarning;
}
}

get activePageIndex(): number {
if (!this.activeExamPage || this.activeExamPage.isOverviewPage) {
return -1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Component, HostListener, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Patch, Selection, UMLDiagramType, UMLElementType, UMLModel, UMLRelationshipType } from '@ls1intum/apollon';
import { TranslateService } from '@ngx-translate/core';
Expand Down Expand Up @@ -642,14 +642,6 @@ export class ModelingSubmissionComponent implements OnInit, OnDestroy, Component
return false;
}

// displays the alert for confirming leaving the page if there are unsaved changes
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any): void {
if (!this.canDeactivate()) {
event.returnValue = this.translateService.instant('pendingChanges');
}
}

/**
* counts the number of model elements
* is used in the submit() function
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges, ViewChild } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { isEmpty as _isEmpty, fromPairs, toPairs, uniq } from 'lodash-es';
import { CodeEditorFileService } from 'app/exercises/programming/shared/code-editor/service/code-editor-file.service';
import { ComponentCanDeactivate } from 'app/shared/guard/can-deactivate.model';
import { CodeEditorGridComponent } from 'app/exercises/programming/shared/code-editor/layout/code-editor-grid.component';
import {
CommitState,
Expand Down Expand Up @@ -37,7 +36,7 @@ export enum CollapsableCodeEditorElement {
templateUrl: './code-editor-container.component.html',
styleUrls: ['./code-editor-container.component.scss'],
})
export class CodeEditorContainerComponent implements OnChanges, ComponentCanDeactivate {
export class CodeEditorContainerComponent implements OnChanges {
readonly CommitState = CommitState;
readonly EditorState = EditorState;
readonly CollapsableCodeEditorElement = CollapsableCodeEditorElement;
Expand Down Expand Up @@ -262,13 +261,6 @@ export class CodeEditorContainerComponent implements OnChanges, ComponentCanDeac
this.alertService.error(`artemisApp.editor.errors.${errorTranslationKey}`, translationParams);
}

/**
* The user will be warned if there are unsaved changes when trying to leave the code-editor.
*/
canDeactivate() {
return _isEmpty(this.unsavedFiles);
}

getText(): string {
return this.monacoEditor.getText() ?? '';
}
Expand All @@ -286,14 +278,6 @@ export class CodeEditorContainerComponent implements OnChanges, ComponentCanDeac
this.monacoEditor.highlightLines(startLine, endLine);
}

// displays the alert for confirming refreshing or closing the page if there are unsaved changes
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any) {
if (!this.canDeactivate()) {
event.returnValue = this.translateService.instant('pendingChanges');
}
}

onToggleCollapse(event: InteractableEvent, collapsableElement: CollapsableCodeEditorElement) {
this.grid.toggleCollapse(event, collapsableElement);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, OnChanges, OnInit, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnChanges, OnInit, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
import { QuizExerciseService } from './quiz-exercise.service';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
Expand Down Expand Up @@ -355,16 +355,6 @@ export class QuizExerciseUpdateComponent extends QuizExerciseValidationDirective
return !this.pendingChangesCache;
}

/**
* Displays the alert for confirming refreshing or closing the page if there are unsaved changes
*/
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any) {
if (!this.canDeactivate()) {
event.returnValue = this.translateService.instant('pendingChanges');
}
}

/**
* @desc Callback for datepicker to decide whether given date should be disabled
* All dates which are in the past (< today) are disabled
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { ActivatedRoute } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http';
Expand Down Expand Up @@ -248,14 +248,6 @@ export class TextEditorComponent implements OnInit, OnDestroy, ComponentCanDeact
return this.stringCountService.countCharacters(this.answer);
}

// Displays the alert for confirming refreshing or closing the page if there are unsaved changes
@HostListener('window:beforeunload', ['$event'])
unloadNotification(event: any) {
if (!this.canDeactivate()) {
event.returnValue = this.translateService.instant('pendingChanges');
}
}

canDeactivate(): boolean {
if (!this.submission) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Routes } from '@angular/router';
import { UserRouteAccessService } from 'app/core/auth/user-route-access-service';
import { TextEditorComponent } from './text-editor.component';
import { Authority } from 'app/shared/constants/authority.constants';
import { PendingChangesGuard } from 'app/shared/guard/pending-changes.guard';

export const textEditorRoute: Routes = [
{
Expand All @@ -12,5 +13,6 @@ export const textEditorRoute: Routes = [
pageTitle: 'artemisApp.textExercise.home.title',
},
canActivate: [UserRouteAccessService],
canDeactivate: [PendingChangesGuard],
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,8 @@ describe('GenerateCompetenciesComponent', () => {

it('should send a warning when trying to reload', () => {
generateCompetenciesComponent.isLoading = true;
const event = { returnValue: undefined };
generateCompetenciesComponent.unloadNotification(event);
expect(event.returnValue).toBe(generateCompetenciesComponent.canDeactivateWarning);
const canDeactivate = generateCompetenciesComponent.canDeactivate();
expect(canDeactivate).toBeFalse();
pzdr7 marked this conversation as resolved.
Show resolved Hide resolved
});

function createCompetencyFormGroup(title?: string, description?: string, taxonomy?: CompetencyTaxonomy, viewed = false): FormGroup<CompetencyFormControlsWithViewed> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,15 @@ describe('ImportCourseCompetenciesComponent', () => {
expect(component.disabledIds).toHaveLength(3);
});

it('should not unload with pending changes', () => {
const deactivateWarningSpy = jest.spyOn(component, 'canDeactivateWarning', 'get');

it('should not deactivate with pending changes', () => {
let canDeactivate;
component['isSubmitted'] = true;
component.selectedCourseCompetencies = { resultsOnPage: [{ id: 1 }], numberOfPages: 0 };
component['unloadNotification']({ returnValue: '' });
expect(deactivateWarningSpy).not.toHaveBeenCalled();
canDeactivate = component.canDeactivate();
expect(canDeactivate).toBeTrue();

component['isSubmitted'] = false;
component['unloadNotification']({ returnValue: '' });
expect(deactivateWarningSpy).toHaveBeenCalled();
canDeactivate = component.canDeactivate();
expect(canDeactivate).toBeFalse();
coolchock marked this conversation as resolved.
Show resolved Hide resolved
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -767,16 +767,6 @@ describe('ExamParticipationComponent', () => {
});
});

describe('unloadNotification', () => {
it('should set event return value', () => {
jest.spyOn(comp, 'canDeactivate').mockReturnValue(false);
jest.spyOn(comp, 'canDeactivateWarning', 'get').mockReturnValue('warning');
const event = { returnValue: undefined };
comp.unloadNotification(event);
expect(event.returnValue).toBe('warning');
});
});

describe('isOver', () => {
it('should return true if exam has ended', () => {
const studentExam = new StudentExam();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,16 +635,14 @@ describe('QuizExerciseUpdateComponent', () => {

it('should set event return value to translate if not canDeactivate', () => {
comp.pendingChangesCache = true;
const ev = { returnValue: undefined };
comp.unloadNotification(ev);
expect(ev.returnValue).toBe('pendingChanges');
const canDeactivate = comp.canDeactivate();
expect(canDeactivate).toBeFalse();
});

it('should not set event return value to translate if canDeactivate', () => {
comp.pendingChangesCache = false;
const ev = { returnValue: undefined };
comp.unloadNotification(ev);
expect(ev.returnValue).toBeUndefined();
const canDeactivate = comp.canDeactivate();
expect(canDeactivate).toBeTrue();
});
pzdr7 marked this conversation as resolved.
Show resolved Hide resolved
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,14 @@ describe('CourseImportStandardizedCompetenciesComponent', () => {
});

it('should not deactivate with pending changes', () => {
const deactivateWarningSpy = jest.spyOn(component as any, 'canDeactivateWarning', 'get');
let canDeactivate;

component['isLoading'] = false;
component['unloadNotification']({ returnValue: '' });
expect(deactivateWarningSpy).not.toHaveBeenCalled();
canDeactivate = component.canDeactivate();
expect(canDeactivate).toBeTrue();

component['isLoading'] = true;
component['unloadNotification']({ returnValue: '' });
expect(deactivateWarningSpy).toHaveBeenCalled();
canDeactivate = component.canDeactivate();
expect(canDeactivate).toBeFalse();
coolchock marked this conversation as resolved.
Show resolved Hide resolved
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,14 @@ describe('CourseImportStandardizedPrerequisitesComponent', () => {
});

it('should not deactivate with pending changes', () => {
const deactivateWarningSpy = jest.spyOn(component as any, 'canDeactivateWarning', 'get');
let canDeactivate;

component['isLoading'] = false;
component['unloadNotification']({ returnValue: '' });
expect(deactivateWarningSpy).not.toHaveBeenCalled();
canDeactivate = component.canDeactivate();
expect(canDeactivate).toBeTrue();

component['isLoading'] = true;
component['unloadNotification']({ returnValue: '' });
expect(deactivateWarningSpy).toHaveBeenCalled();
canDeactivate = component.canDeactivate();
expect(canDeactivate).toBeFalse();
coolchock marked this conversation as resolved.
Show resolved Hide resolved
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -479,15 +479,15 @@ describe('StandardizedCompetencyManagementComponent', () => {
});

it('should not deactivate with pending changes', () => {
const deactivateWarningSpy = jest.spyOn(component, 'canDeactivateWarning', 'get');
let canDeactivate;

component['isEditing'] = false;
component['unloadNotification']({ returnValue: '' });
expect(deactivateWarningSpy).not.toHaveBeenCalled();
canDeactivate = component.canDeactivate();
expect(canDeactivate).toBeTrue();

component['isEditing'] = true;
component['unloadNotification']({ returnValue: '' });
expect(deactivateWarningSpy).toHaveBeenCalled();
canDeactivate = component.canDeactivate();
expect(canDeactivate).toBeFalse();
});

function prepareAndExecuteCompetencyUpdate(tree: KnowledgeAreaDTO[], competencyToUpdate: StandardizedCompetencyDTO, updatedCompetency: StandardizedCompetencyDTO) {
Expand Down
Loading