diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index cc1841907..3da673d13 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -12,7 +12,8 @@ const routes: Routes = [
{ path: 'phaseBugReporting', loadChildren: () => PhaseBugReportingModule, canLoad: [AuthGuard] },
{ path: 'phaseTeamResponse', loadChildren: () => PhaseTeamResponseModule, canLoad: [AuthGuard] },
{ path: 'phaseTesterResponse', loadChildren: () => PhaseTesterResponseModule, canLoad: [AuthGuard] },
- { path: 'phaseModeration', loadChildren: () => PhaseModerationModule, canLoad: [AuthGuard] }
+ { path: 'phaseModeration', loadChildren: () => PhaseModerationModule, canLoad: [AuthGuard] },
+ { path: '**', redirectTo: '' }
];
@NgModule({
diff --git a/src/app/core/directives/internal-link-disable.directive.ts b/src/app/core/directives/internal-link-disable.directive.ts
new file mode 100644
index 000000000..d15db8d47
--- /dev/null
+++ b/src/app/core/directives/internal-link-disable.directive.ts
@@ -0,0 +1,32 @@
+import { Directive, HostListener } from '@angular/core';
+import { ErrorHandlingService } from '../services/error-handling.service';
+
+class InvalidLinkError extends Error {
+ constructor() {
+ super('Invalid link!');
+ Object.setPrototypeOf(this, InvalidLinkError.prototype);
+ }
+}
+
+@Directive({
+ selector: '[disableInternalLink]'
+})
+export class InternalLinkDisableDirective {
+ constructor(private errorHandlingService: ErrorHandlingService) {}
+
+ @HostListener('click', ['$event'])
+ public onClick(e: MouseEvent): void {
+ const srcElement = e.target;
+
+ if (srcElement instanceof HTMLAnchorElement) {
+ const baseURI = srcElement.baseURI;
+ const href = srcElement.href;
+
+ if (href.startsWith(baseURI)) {
+ this.errorHandlingService.handleError(new InvalidLinkError());
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ }
+ }
+}
diff --git a/src/app/core/validators/noWhitespace.validator.ts b/src/app/core/validators/noWhitespace.validator.ts
new file mode 100644
index 000000000..696232327
--- /dev/null
+++ b/src/app/core/validators/noWhitespace.validator.ts
@@ -0,0 +1,10 @@
+import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
+
+export function noWhitespace(): ValidatorFn {
+ return (title: AbstractControl): ValidationErrors | null => {
+ if (title.value && title.value.trim() === '') {
+ return { whitespace: true };
+ }
+ return null;
+ };
+}
diff --git a/src/app/phase-bug-reporting/new-issue/new-issue.component.html b/src/app/phase-bug-reporting/new-issue/new-issue.component.html
index 5af3d8332..dd98459dd 100644
--- a/src/app/phase-bug-reporting/new-issue/new-issue.component.html
+++ b/src/app/phase-bug-reporting/new-issue/new-issue.component.html
@@ -7,6 +7,7 @@
New Issue
Title required.
+ Title cannot contain only whitespaces.
Title cannot exceed 256 characters.
= 206"> {{ 256 - title.value?.length }} characters remaining.
diff --git a/src/app/phase-bug-reporting/new-issue/new-issue.component.ts b/src/app/phase-bug-reporting/new-issue/new-issue.component.ts
index 58234c92c..cbd3e3c40 100644
--- a/src/app/phase-bug-reporting/new-issue/new-issue.component.ts
+++ b/src/app/phase-bug-reporting/new-issue/new-issue.component.ts
@@ -6,6 +6,7 @@ import { Issue } from '../../core/models/issue.model';
import { ErrorHandlingService } from '../../core/services/error-handling.service';
import { IssueService } from '../../core/services/issue.service';
import { LabelService } from '../../core/services/label.service';
+import { noWhitespace } from '../../core/validators/noWhitespace.validator';
import { SUBMIT_BUTTON_TEXT } from '../../shared/view-issue/view-issue.component';
@Component({
@@ -28,7 +29,7 @@ export class NewIssueComponent implements OnInit {
ngOnInit() {
this.newIssueForm = this.formBuilder.group({
- title: ['', [Validators.required, Validators.maxLength(256)]],
+ title: ['', [Validators.required, Validators.maxLength(256), noWhitespace()]],
description: [''],
severity: ['', Validators.required],
type: ['', Validators.required]
@@ -41,6 +42,7 @@ export class NewIssueComponent implements OnInit {
if (this.newIssueForm.invalid) {
return;
}
+
this.isFormPending = true;
this.issueService
.createIssue(this.title.value, Issue.updateDescription(this.description.value), this.severity.value, this.type.value)
diff --git a/src/app/shared/comment-editor/comment-editor.component.html b/src/app/shared/comment-editor/comment-editor.component.html
index bac61dda7..67e729946 100644
--- a/src/app/shared/comment-editor/comment-editor.component.html
+++ b/src/app/shared/comment-editor/comment-editor.component.html
@@ -57,7 +57,7 @@
diff --git a/src/app/shared/issue/description/description.component.html b/src/app/shared/issue/description/description.component.html
index 1d7c9bee8..08837c415 100644
--- a/src/app/shared/issue/description/description.component.html
+++ b/src/app/shared/issue/description/description.component.html
@@ -8,7 +8,7 @@ {{ descriptionTitle }}
- #{{ duplicatedIssue.id }}
+ #{{ duplicatedIssue.id }}
cancel
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index cfc65f82c..7fd9fe400 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -4,15 +4,17 @@ import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { FormDisableControlDirective } from '../core/directives/form-disable-control.directive';
+import { InternalLinkDisableDirective } from '../core/directives/internal-link-disable.directive';
import { ActionToasterModule } from './action-toasters/action-toasters.module';
import { ErrorToasterModule } from './error-toasters/error-toaster.module';
import { MaterialModule } from './material.module';
@NgModule({
imports: [CommonModule, FormsModule, ReactiveFormsModule, HttpClientModule, RouterModule, MaterialModule, ErrorToasterModule],
- declarations: [FormDisableControlDirective],
+ declarations: [FormDisableControlDirective, InternalLinkDisableDirective],
exports: [
FormDisableControlDirective,
+ InternalLinkDisableDirective,
CommonModule,
FormsModule,
ReactiveFormsModule,
diff --git a/src/app/shared/view-issue/issue-dispute/issue-dispute.component.html b/src/app/shared/view-issue/issue-dispute/issue-dispute.component.html
index 5350eb33d..4ab0cab8d 100644
--- a/src/app/shared/view-issue/issue-dispute/issue-dispute.component.html
+++ b/src/app/shared/view-issue/issue-dispute/issue-dispute.component.html
@@ -9,10 +9,10 @@ Disputes
-
+
Disputes
-
+
{{ 'The content you are editing has chang
?
-
+
@@ -25,7 +25,7 @@ {{ 'The content you are editing has chang
-
+
Tester's Response
-
+
Tester's Response
Reason for Disagreement:
-
+