From 1c09533497981f98944f3a25068b7608e317ce4d Mon Sep 17 00:00:00 2001 From: Wen Date: Mon, 14 Oct 2024 17:05:35 +1100 Subject: [PATCH 1/7] Change recipient selection from select to input with dropdown list --- .../question-submission-form.component.html | 27 ++++++++---- .../question-submission-form.component.ts | 42 ++++++++++++++++++- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/web/app/components/question-submission-form/question-submission-form.component.html b/src/web/app/components/question-submission-form/question-submission-form.component.html index e2d079b9840..e690c824c70 100644 --- a/src/web/app/components/question-submission-form/question-submission-form.component.html +++ b/src/web/app/components/question-submission-form/question-submission-form.component.html @@ -69,20 +69,31 @@

Question {{ model.questionNumber }}: {{ mode
{{ getRecipientName(recipientSubmissionFormModel.recipientIdentifier) }} ({{ model.recipientType | recipientTypeName:model.giverType }})
-
- - - - - - + [attr.aria-label]="'Select recipient input question ' + model.questionNumber + ' index ' + i" + placeholder="Type to search..." /> +
({{ model.recipientType | recipientTypeName: model.giverType }})
+ +
r.recipientIdentifier === recipientIdentifier); - return recipient ? recipient.recipientName : 'Unknown'; + return recipient ? recipient.recipientName : ''; } /** @@ -595,4 +598,41 @@ export class QuestionSubmissionFormComponent implements DoCheck { return false; } } + + /** + * Filters the recipient list based on the input value and updates the filtered recipients array at the specified index. + */ + filterRecipients(value: string, index: number) { + + this.filteredRecipients[index] = this.model.recipientList.filter(recipient => + this.getSelectionOptionLabel(recipient).toLowerCase().includes(value.toLowerCase()) + ); + this.dropdownVisible[index] = this.filteredRecipients[index].length > 0; + } + + /** + * Sets the dropdown visibility to true for the specified recipient index. + */ + showDropdown(index: number) { + this.dropdownVisible[index] = true; + } + + /** + * Hides the dropdown for the specified recipient index after a short delay. + */ + hideDropdown(index: number) { + setTimeout(() => { + this.dropdownVisible[index] = false; + }, 100); + } + + /** + * Updates the recipient selection in the form model and sets the displayed name for the selected recipient. + */ + selectRecipient(recipient: any, recipientSubmissionFormModel: any, index: number) { + recipientSubmissionFormModel.recipientIdentifier = recipient.recipientIdentifier; + this.displayedRecipientName[index] = recipient.recipientName; + this.filteredRecipients[index] = []; + this.dropdownVisible[index] = false; + } } From d7adae989f75a9a30e79835fa1fd9612925f3393 Mon Sep 17 00:00:00 2001 From: Wen Date: Mon, 14 Oct 2024 22:05:37 +1100 Subject: [PATCH 2/7] Fix display of 'Unknown' when input is cleared --- .../question-submission-form.component.html | 2 +- .../question-submission-form.component.ts | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/web/app/components/question-submission-form/question-submission-form.component.html b/src/web/app/components/question-submission-form/question-submission-form.component.html index e690c824c70..3ec6322f643 100644 --- a/src/web/app/components/question-submission-form/question-submission-form.component.html +++ b/src/web/app/components/question-submission-form/question-submission-form.component.html @@ -73,7 +73,7 @@

Question {{ model.questionNumber }}: {{ mode r.recipientIdentifier === recipientIdentifier); - return recipient ? recipient.recipientName : ''; + return recipient ? recipient.recipientName : 'Unknown'; } /** @@ -635,4 +635,16 @@ export class QuestionSubmissionFormComponent implements DoCheck { this.filteredRecipients[index] = []; this.dropdownVisible[index] = false; } + + /** + * Gets recipient name in {@code FIXED_RECIPIENT} mode. + * Origin from getRecipientName + */ + getRecipientNameForInput(recipientIdentifier: string): string { + const recipient: FeedbackResponseRecipient | undefined = + this.model.recipientList.find( + (r: FeedbackResponseRecipient) => r.recipientIdentifier === recipientIdentifier); + return recipient ? recipient.recipientName : ''; + } + } From 48d2d84910659df2021068bf21fbd4297a2d7822 Mon Sep 17 00:00:00 2001 From: Wen Date: Mon, 14 Oct 2024 22:06:17 +1100 Subject: [PATCH 3/7] Add test for filterRecipients --- ...question-submission-form.component.spec.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts b/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts index 1ff82d95cac..afd0aa5a7b8 100644 --- a/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts +++ b/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts @@ -1157,4 +1157,24 @@ describe('QuestionSubmissionFormComponent', () => { fixture.detectChanges(); expect(component.isSavedForRecipient('recipientId')).toBeTruthy(); }); + + it('filterRecipients: should filter recipient list in the dropdown list and update dropdown visibility', ()=>{ + + const value = 'alice'; + const index = 0; + + component.model.recipientList = [ + { recipientIdentifier: '0', recipientName: 'Alice Betsy' }, + { recipientIdentifier: '1', recipientName: 'Benny Charles' } + ]; + + component.getSelectionOptionLabel = (recipient: any) => recipient.recipientName; + component.filterRecipients(value, index); + + expect(component.filteredRecipients[index].length).toBe(1); + expect(component.filteredRecipients[index][0].recipientName).toBe('Alice Betsy'); + + expect(component.dropdownVisible[index]).toBe(true); + }) + }); From dd9d784e01973f1a243a5e3d8c6d0223a0c7303c Mon Sep 17 00:00:00 2001 From: u7706346 Date: Fri, 18 Oct 2024 23:41:42 +1100 Subject: [PATCH 4/7] Add some instances for testing the filter function --- ...question-submission-form.component.spec.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts b/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts index afd0aa5a7b8..bb77ee30c66 100644 --- a/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts +++ b/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts @@ -1176,5 +1176,31 @@ describe('QuestionSubmissionFormComponent', () => { expect(component.dropdownVisible[index]).toBe(true); }) + + it('filterRecipients: should filter recipient list in the dropdown list and update dropdown visibility', ()=>{ + + const value = 'alex'; + const index = 0; + + component.model.recipientList = [ + { recipientIdentifier: '0', recipientName: 'Alice Betsy' }, + { recipientIdentifier: '1', recipientName: 'Benny Charles' }, + { recipientIdentifier: '2', recipientName: 'Group 2 | Tutorial 13 | Alex Kim' }, + { recipientIdentifier: '3', recipientName: 'Lecture #1 @ Room A | Jason Doe' }, + { recipientIdentifier: '4', recipientName: 'Lab Session *10* | Annie K. & John L.' }, + { recipientIdentifier: '5', recipientName: 'Group 3: Research Team | Dr. Alex Smith' } + ]; + + component.getSelectionOptionLabel = (recipient: any) => recipient.recipientName; + component.filterRecipients(value, index); + + // Testing for the filtered recipients based on 'alex' + expect(component.filteredRecipients[index].length).toBe(2); + expect(component.filteredRecipients[index][0].recipientName).toBe('Group 2 | Tutorial 13 | Alex Kim'); + expect(component.filteredRecipients[index][1].recipientName).toBe('Group 3: Research Team | Dr. Alex Smith'); + + // Dropdown should be visible for the filtered results + expect(component.dropdownVisible[index]).toBe(true); + }); }); From a476c677dbcea22d5f3271ea6c0655d7e371086a Mon Sep 17 00:00:00 2001 From: Yixia Sun Date: Sat, 19 Oct 2024 17:25:53 +1100 Subject: [PATCH 5/7] add test for filterRecipients empty case --- ...question-submission-form.component.spec.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts b/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts index bb77ee30c66..e527d471ae5 100644 --- a/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts +++ b/src/web/app/components/question-submission-form/question-submission-form.component.spec.ts @@ -1203,4 +1203,23 @@ describe('QuestionSubmissionFormComponent', () => { expect(component.dropdownVisible[index]).toBe(true); }); + it('filterRecipients: should filter recipient list and resuld should be empty and dropdown should not be visible', ()=>{ + + const value = 'alice'; + const index = 0; + + component.model.recipientList = [ + { recipientIdentifier: '0', recipientName: 'Matty Betsy' }, + { recipientIdentifier: '1', recipientName: 'Benny Charles' } + ]; + + component.getSelectionOptionLabel = (recipient: any) => recipient.recipientName; + component.filterRecipients(value, index); + + expect(component.filteredRecipients[index].length).toBe(0); + expect(component.filteredRecipients[index][0]).toBeUndefined(); + + expect(component.dropdownVisible[index]).toBe(false); + }) + }); From c422815048d79f80b12f11592244a01b2d89ae44 Mon Sep 17 00:00:00 2001 From: Wen Date: Sat, 19 Oct 2024 20:34:13 +1100 Subject: [PATCH 6/7] Fix unexpected trailing spaces --- .../question-submission-form.component.html | 1 - 1 file changed, 1 deletion(-) diff --git a/src/web/app/components/question-submission-form/question-submission-form.component.html b/src/web/app/components/question-submission-form/question-submission-form.component.html index 3ec6322f643..c31c3eec43e 100644 --- a/src/web/app/components/question-submission-form/question-submission-form.component.html +++ b/src/web/app/components/question-submission-form/question-submission-form.component.html @@ -81,7 +81,6 @@

Question {{ model.questionNumber }}: {{ mode [disabled]="isFormsDisabled" [attr.aria-label]="'Select recipient input question ' + model.questionNumber + ' index ' + i" placeholder="Type to search..." /> -
({{ model.recipientType | recipientTypeName: model.giverType }})
From 279428dc1410d051a62c5ca6a0bc6c2910a3f313 Mon Sep 17 00:00:00 2001 From: Wen Date: Sat, 19 Oct 2024 21:10:54 +1100 Subject: [PATCH 7/7] Fix linting errors and improving code readability --- .../question-submission-form.component.html | 3 +- ...question-submission-form.component.spec.ts | 34 ++++--------------- .../question-submission-form.component.ts | 33 +++++++++--------- 3 files changed, 23 insertions(+), 47 deletions(-) diff --git a/src/web/app/components/question-submission-form/question-submission-form.component.html b/src/web/app/components/question-submission-form/question-submission-form.component.html index c31c3eec43e..66fd3283571 100644 --- a/src/web/app/components/question-submission-form/question-submission-form.component.html +++ b/src/web/app/components/question-submission-form/question-submission-form.component.html @@ -69,7 +69,7 @@

Question {{ model.questionNumber }}: {{ mode
{{ getRecipientName(recipientSubmissionFormModel.recipientIdentifier) }} ({{ model.recipientType | recipientTypeName:model.giverType }})
-
+
Question {{ model.questionNumber }}: {{ mode {{ getSelectionOptionLabel(recipient) }}
-

{ expect(component.isSavedForRecipient('recipientId')).toBeTruthy(); }); - it('filterRecipients: should filter recipient list in the dropdown list and update dropdown visibility', ()=>{ - - const value = 'alice'; - const index = 0; - - component.model.recipientList = [ - { recipientIdentifier: '0', recipientName: 'Alice Betsy' }, - { recipientIdentifier: '1', recipientName: 'Benny Charles' } - ]; - - component.getSelectionOptionLabel = (recipient: any) => recipient.recipientName; - component.filterRecipients(value, index); - - expect(component.filteredRecipients[index].length).toBe(1); - expect(component.filteredRecipients[index][0].recipientName).toBe('Alice Betsy'); - - expect(component.dropdownVisible[index]).toBe(true); - }) - - it('filterRecipients: should filter recipient list in the dropdown list and update dropdown visibility', ()=>{ + it('filterRecipients: should filter recipient list in the dropdown list and update dropdown visibility', () => { const value = 'alex'; const index = 0; @@ -1188,38 +1169,35 @@ describe('QuestionSubmissionFormComponent', () => { { recipientIdentifier: '2', recipientName: 'Group 2 | Tutorial 13 | Alex Kim' }, { recipientIdentifier: '3', recipientName: 'Lecture #1 @ Room A | Jason Doe' }, { recipientIdentifier: '4', recipientName: 'Lab Session *10* | Annie K. & John L.' }, - { recipientIdentifier: '5', recipientName: 'Group 3: Research Team | Dr. Alex Smith' } + { recipientIdentifier: '5', recipientName: 'Group 3: Research Team | Dr. Alex Smith' }, ]; component.getSelectionOptionLabel = (recipient: any) => recipient.recipientName; component.filterRecipients(value, index); - // Testing for the filtered recipients based on 'alex' expect(component.filteredRecipients[index].length).toBe(2); expect(component.filteredRecipients[index][0].recipientName).toBe('Group 2 | Tutorial 13 | Alex Kim'); expect(component.filteredRecipients[index][1].recipientName).toBe('Group 3: Research Team | Dr. Alex Smith'); - // Dropdown should be visible for the filtered results expect(component.dropdownVisible[index]).toBe(true); }); - - it('filterRecipients: should filter recipient list and resuld should be empty and dropdown should not be visible', ()=>{ + + it('filterRecipients: should filter the list with no results, hiding the dropdown', () => { const value = 'alice'; const index = 0; component.model.recipientList = [ { recipientIdentifier: '0', recipientName: 'Matty Betsy' }, - { recipientIdentifier: '1', recipientName: 'Benny Charles' } + { recipientIdentifier: '1', recipientName: 'Benny Charles' }, ]; component.getSelectionOptionLabel = (recipient: any) => recipient.recipientName; component.filterRecipients(value, index); - expect(component.filteredRecipients[index].length).toBe(0); expect(component.filteredRecipients[index][0]).toBeUndefined(); expect(component.dropdownVisible[index]).toBe(false); - }) + }); }); diff --git a/src/web/app/components/question-submission-form/question-submission-form.component.ts b/src/web/app/components/question-submission-form/question-submission-form.component.ts index a2743eb6d59..2633530bc56 100644 --- a/src/web/app/components/question-submission-form/question-submission-form.component.ts +++ b/src/web/app/components/question-submission-form/question-submission-form.component.ts @@ -58,8 +58,8 @@ export class QuestionSubmissionFormComponent implements DoCheck { isMCQDropDownEnabled: boolean = false; isSaved: boolean = false; hasResponseChanged: boolean = false; - dropdownVisible: boolean[] = []; - filteredRecipients: any[][] = []; + dropdownVisible: boolean[] = []; + filteredRecipients: any[][] = []; displayedRecipientName: string[] = []; @Input() @@ -600,40 +600,40 @@ export class QuestionSubmissionFormComponent implements DoCheck { } /** - * Filters the recipient list based on the input value and updates the filtered recipients array at the specified index. + * Filters the recipient list by input value and updates the filtered recipients array at the given index. */ - filterRecipients(value: string, index: number) { + filterRecipients(value: string, index: number): void { - this.filteredRecipients[index] = this.model.recipientList.filter(recipient => - this.getSelectionOptionLabel(recipient).toLowerCase().includes(value.toLowerCase()) + this.filteredRecipients[index] = this.model.recipientList.filter((recipient) => + this.getSelectionOptionLabel(recipient).toLowerCase().includes(value.toLowerCase()), ); - this.dropdownVisible[index] = this.filteredRecipients[index].length > 0; + this.dropdownVisible[index] = this.filteredRecipients[index].length > 0; } /** * Sets the dropdown visibility to true for the specified recipient index. */ - showDropdown(index: number) { + showDropdown(index: number): void { this.dropdownVisible[index] = true; } /** * Hides the dropdown for the specified recipient index after a short delay. */ - hideDropdown(index: number) { + hideDropdown(index: number): void { setTimeout(() => { - this.dropdownVisible[index] = false; - }, 100); + this.dropdownVisible[index] = false; + }, 100); } /** * Updates the recipient selection in the form model and sets the displayed name for the selected recipient. */ - selectRecipient(recipient: any, recipientSubmissionFormModel: any, index: number) { - recipientSubmissionFormModel.recipientIdentifier = recipient.recipientIdentifier; - this.displayedRecipientName[index] = recipient.recipientName; - this.filteredRecipients[index] = []; - this.dropdownVisible[index] = false; + selectRecipient(recipient: any, recipientSubmissionFormModel: any, index: number): void { + recipientSubmissionFormModel.recipientIdentifier = recipient.recipientIdentifier; + this.displayedRecipientName[index] = recipient.recipientName; + this.filteredRecipients[index] = []; + this.dropdownVisible[index] = false; } /** @@ -646,5 +646,4 @@ export class QuestionSubmissionFormComponent implements DoCheck { (r: FeedbackResponseRecipient) => r.recipientIdentifier === recipientIdentifier); return recipient ? recipient.recipientName : ''; } - }