From 3951d6daaf2a9a976fa402b07cb1b7b807c952c0 Mon Sep 17 00:00:00 2001
From: chia-yh <0.chiayuhong.0@gmail.com>
Date: Thu, 22 Jun 2023 15:01:50 +0800
Subject: [PATCH 01/14] Add title-editor.component, title-editor.module
---
.../title-editor/title-editor.component.css | 3 +
.../title-editor/title-editor.component.html | 26 ++++
.../title-editor/title-editor.component.ts | 139 ++++++++++++++++++
.../title-editor/title-editor.module.ts | 11 ++
4 files changed, 179 insertions(+)
create mode 100644 src/app/shared/title-editor/title-editor.component.css
create mode 100644 src/app/shared/title-editor/title-editor.component.html
create mode 100644 src/app/shared/title-editor/title-editor.component.ts
create mode 100644 src/app/shared/title-editor/title-editor.module.ts
diff --git a/src/app/shared/title-editor/title-editor.component.css b/src/app/shared/title-editor/title-editor.component.css
new file mode 100644
index 000000000..53a4bc5e4
--- /dev/null
+++ b/src/app/shared/title-editor/title-editor.component.css
@@ -0,0 +1,3 @@
+mat-form-field {
+ width: 100%;
+}
\ No newline at end of file
diff --git a/src/app/shared/title-editor/title-editor.component.html b/src/app/shared/title-editor/title-editor.component.html
new file mode 100644
index 000000000..1c4ce4eeb
--- /dev/null
+++ b/src/app/shared/title-editor/title-editor.component.html
@@ -0,0 +1,26 @@
+
\ No newline at end of file
diff --git a/src/app/shared/title-editor/title-editor.component.ts b/src/app/shared/title-editor/title-editor.component.ts
new file mode 100644
index 000000000..7bdc8569f
--- /dev/null
+++ b/src/app/shared/title-editor/title-editor.component.ts
@@ -0,0 +1,139 @@
+import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
+import { AbstractControl, FormGroup, Validators } from '@angular/forms';
+import { UndoRedo } from '../../core/models/undoredo.model';
+
+const ISSUE_BODY_SIZE_LIMIT = 256;
+
+type textEntry = {
+ text: string;
+ selectStart: number;
+ selectEnd: number;
+};
+
+@Component({
+ selector: 'app-title-editor',
+ templateUrl: './title-editor.component.html',
+ styleUrls: ['./title-editor.component.css']
+})
+export class TitleEditorComponent implements OnInit {
+
+ constructor() {}
+
+ @Input() titleField: AbstractControl; // Compulsory Input
+ @Input() titleForm: FormGroup; // Compulsory Input
+ @Input() id: string; // Compulsory Input
+
+ @Input() initialTitle?: string;
+ placeholderText = 'Title';
+
+ @ViewChild('titleInput', { static: true }) titleInput: ElementRef;
+
+ maxLength = ISSUE_BODY_SIZE_LIMIT;
+
+ history: UndoRedo;
+
+ ngOnInit() {
+ if (this.initialTitle !== undefined) {
+ this.titleField.setValue(this.initialTitle);
+ }
+
+ if (this.titleField === undefined || this.titleForm === undefined || this.id === undefined) {
+ throw new Error("Title Editor's compulsory properties are not defined.");
+ }
+
+ this.titleField.setValidators([Validators.required, Validators.maxLength(this.maxLength)]);
+ this.history = new UndoRedo(
+ 75,
+ () => {
+ return {
+ text: this.titleInput.nativeElement.value,
+ selectStart: this.titleInput.nativeElement.selectionStart,
+ selectEnd: this.titleInput.nativeElement.selectionEnd
+ };
+ },
+ 500
+ );
+ }
+
+ onKeyPress(event: KeyboardEvent) {
+ if (this.isUndo(event)) {
+ event.preventDefault();
+ this.undo();
+ return;
+ } else if (this.isRedo(event)) {
+ this.redo();
+ event.preventDefault();
+ return;
+ }
+ }
+
+ onPaste(event: ClipboardEvent) {
+ // the text area is not changed at this point
+ this.history.forceSave(null, true, false);
+ }
+
+ handleBeforeInputChange(event: InputEvent): void {
+ switch (event.inputType) {
+ case 'historyUndo':
+ case 'historyRedo':
+ // ignore these events that doesn't modify the text
+ event.preventDefault();
+ break;
+ case 'insertFromPaste':
+ // paste events will be handled exclusively by onPaste
+ break;
+
+ default:
+ this.history.updateBeforeChange();
+ }
+ }
+
+ handleInputChange(event: InputEvent): void {
+ switch (event.inputType) {
+ case 'historyUndo':
+ case 'historyRedo':
+ // ignore these events that doesn't modify the text
+ event.preventDefault();
+ break;
+ case 'insertFromPaste':
+ // paste events will be handled exclusively by onPaste
+ break;
+
+ default:
+ this.history.createDelayedSave();
+ }
+ }
+
+ private undo(): void {
+ const entry = this.history.undo();
+ if (entry === null) {
+ return;
+ }
+ this.titleField.setValue(entry.text);
+ this.titleInput.nativeElement.setSelectionRange(entry.selectStart, entry.selectEnd);
+ }
+
+ private redo(): void {
+ const entry = this.history.redo();
+ if (entry === null) {
+ return;
+ }
+ this.titleInput.nativeElement.value = entry.text;
+ this.titleInput.nativeElement.setSelectionRange(entry.selectStart, entry.selectEnd);
+ }
+
+ private isUndo(event: KeyboardEvent) {
+ // prevents undo from firing when ctrl shift z is pressed
+ if (navigator.platform.indexOf('Mac') === 0) {
+ return event.metaKey && event.code === 'KeyZ' && !event.shiftKey;
+ }
+ return event.ctrlKey && event.code === 'KeyZ' && !event.shiftKey;
+ }
+
+ private isRedo(event: KeyboardEvent) {
+ if (navigator.platform.indexOf('Mac') === 0) {
+ return event.metaKey && event.shiftKey && event.code === 'KeyZ';
+ }
+ return (event.ctrlKey && event.shiftKey && event.code === 'KeyZ') || (event.ctrlKey && event.code === 'KeyY');
+ }
+}
diff --git a/src/app/shared/title-editor/title-editor.module.ts b/src/app/shared/title-editor/title-editor.module.ts
new file mode 100644
index 000000000..b63883771
--- /dev/null
+++ b/src/app/shared/title-editor/title-editor.module.ts
@@ -0,0 +1,11 @@
+import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
+import { SharedModule } from '../shared.module';
+import { TitleEditorComponent } from './title-editor.component';
+
+@NgModule({
+ imports: [SharedModule],
+ declarations: [TitleEditorComponent],
+ exports: [TitleEditorComponent],
+ schemas: [CUSTOM_ELEMENTS_SCHEMA]
+})
+export class TitleEditorModule {}
From 9429a7e9f6b9436996ad63058ed39b8083277b23 Mon Sep 17 00:00:00 2001
From: chia-yh <0.chiayuhong.0@gmail.com>
Date: Thu, 22 Jun 2023 15:04:45 +0800
Subject: [PATCH 02/14] Modify existing titles to use title-editor
---
.../new-issue/new-issue.component.css | 2 +-
.../new-issue/new-issue.component.html | 12 ++---
.../new-issue/new-issue.component.ts | 2 +-
.../phase-bug-reporting.module.ts | 2 +
.../shared/issue/issue-components.module.ts | 9 +++-
.../shared/issue/title/title.component.css | 4 ++
.../shared/issue/title/title.component.html | 48 ++++++++++---------
src/app/shared/issue/title/title.component.ts | 2 +-
.../title-editor/title-editor.component.css | 2 +-
.../title-editor/title-editor.component.html | 2 +-
10 files changed, 50 insertions(+), 35 deletions(-)
diff --git a/src/app/phase-bug-reporting/new-issue/new-issue.component.css b/src/app/phase-bug-reporting/new-issue/new-issue.component.css
index dfd602a10..c7bd63c26 100644
--- a/src/app/phase-bug-reporting/new-issue/new-issue.component.css
+++ b/src/app/phase-bug-reporting/new-issue/new-issue.component.css
@@ -3,7 +3,7 @@
margin: 0 auto;
}
-mat-form-field {
+app-title-editor {
width: 100%;
}
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..774243899 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
@@ -4,12 +4,12 @@ New Issue