From b20b3ef240a8c4fe32f4e016da21d89dd173b6de Mon Sep 17 00:00:00 2001 From: Nguyen <87511888+nknguyenhc@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:39:57 +0800 Subject: [PATCH 1/3] Fix broken duplicate link (#1233) Fix the broken link of a duplicate issue Currently, the user cannot open the link to a duplicate issue when opening an issue, as described in CATcher-org/CATcher#1228. The links now work as expected. --- .../issue/duplicatedIssues/duplicated-issues.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/issue/duplicatedIssues/duplicated-issues.component.html b/src/app/shared/issue/duplicatedIssues/duplicated-issues.component.html index af561b623..be1d58882 100644 --- a/src/app/shared/issue/duplicatedIssues/duplicated-issues.component.html +++ b/src/app/shared/issue/duplicatedIssues/duplicated-issues.component.html @@ -8,7 +8,7 @@ matTooltipPosition="above" (removed)="removeDuplicateStatus(duplicatedIssue)" > - #{{ duplicatedIssue.id }} + #{{ duplicatedIssue.id }} cancel From fe7be44f9ae19c5caabb0506cb631743b9e84bb9 Mon Sep 17 00:00:00 2001 From: AdityaMisra <114080910+MadLamprey@users.noreply.github.com> Date: Thu, 25 Jan 2024 17:35:32 +0800 Subject: [PATCH 2/3] Add whitespace validation (#1237) * Add whitespace validation * Update whitespace validation for new issue * Update whitespace validation for title of new issues * Update whitespace validation for title of new issues * Move validators into core * Update import order --------- Co-authored-by: Misra Aditya --- src/app/core/validators/noWhitespace.validator.ts | 10 ++++++++++ .../new-issue/new-issue.component.html | 1 + .../new-issue/new-issue.component.ts | 4 +++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/app/core/validators/noWhitespace.validator.ts 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. {{ 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) From d4b5422a2a0c83a73956032f3791dd6835a25090 Mon Sep 17 00:00:00 2001 From: NereusWB922 <107099783+NereusWB922@users.noreply.github.com> Date: Sat, 3 Feb 2024 01:36:35 +0800 Subject: [PATCH 3/3] Fix uncaught errors when attempting to access an invalid route There is an uncaught error when the users click on an invalid internal link in Markdown or enter an invalid link in browser. Internal links are unlikely to be used for bug reporting and are more likely to be invalid. Let's show an error toaster and stop the navigation when clicking on an internal link in Markdown. Also, redirect the users to the login page if the users enter invalid link in browser. --- src/app/app-routing.module.ts | 3 +- .../internal-link-disable.directive.ts | 32 +++++++++++++++++++ .../comment-editor.component.html | 2 +- .../description/description.component.html | 2 +- src/app/shared/shared.module.ts | 4 ++- .../issue-dispute.component.html | 6 ++-- .../team-response.component.html | 2 +- .../conflict-dialog.component.html | 4 +-- .../tester-response.component.html | 6 ++-- 9 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 src/app/core/directives/internal-link-disable.directive.ts 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/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 @@
- +
Nothing to preview.
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 }}

- +
Disputes
?
- +

- +
Disputes
- +
Team's Response
- +
{{ '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:

- +