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

[#13054] Make substrings of the name in dropdown selections of recipient to be searchable #13183

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,28 @@ <h2 class="question-details"><b>Question {{ model.questionNumber }}: </b>{{ mode
<b>{{ getRecipientName(recipientSubmissionFormModel.recipientIdentifier) }} </b> <span>({{ model.recipientType | recipientTypeName:model.giverType }})</span>
</div>
<div class="row evaluee-select align-items-center" *ngIf="formMode === QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT">
<select id="recipient-dropdown-qn-{{ model.questionNumber }}-idx-{{ i }}" class="form-control form-select fw-bold col" [ngModel]="recipientSubmissionFormModel.recipientIdentifier"
<input type="text"
id="recipient-input-qn-{{ model.questionNumber }}-idx-{{ i }}"
class="form-control fw-bold col"
[ngModel]="displayedRecipientName[i] || getRecipientNameForInput(model.recipientSubmissionForms[i].recipientIdentifier)"
(ngModelChange)="triggerRecipientSubmissionFormChange(i, 'recipientIdentifier', $event)"
(input)="filterRecipients($event.target.value, i)"
(focus)="showDropdown(i)"
(blur)="hideDropdown(i)"
[disabled]="isFormsDisabled"
[attr.aria-label]="'Select recipient dropdown question ' + model.questionNumber + ' index ' + i">
<option value=""></option>
<ng-container *ngFor="let recipient of model.recipientList">
<option *ngIf="!isRecipientSelected(recipient) || recipientSubmissionFormModel.recipientIdentifier === recipient.recipientIdentifier" [ngValue]="recipient.recipientIdentifier">{{ getSelectionOptionLabel(recipient) }}</option>
</ng-container>
</select>
[attr.aria-label]="'Select recipient input question ' + model.questionNumber + ' index ' + i"
placeholder="Type to search..." />
<div class="col-auto text-start">
({{ model.recipientType | recipientTypeName: model.giverType }})
</div>
</div>
<div *ngIf="formMode === QuestionSubmissionFormMode.FLEXIBLE_RECIPIENT && filteredRecipients[i]?.length > 0 && dropdownVisible[i]" class="dropdown-menu evaluee-select show">
<div class="dropdown-item"
*ngFor="let recipient of filteredRecipients[i]"
(click)="selectRecipient(recipient, recipientSubmissionFormModel, i)">
{{ getSelectionOptionLabel(recipient) }}
</div>
</div>
</div>
<div class="margin-top-20px" [ngClass]="isMCQDropDownEnabled ? 'col-12' : 'col'">
<tm-contribution-question-edit-answer-form *ngIf="model.questionType === FeedbackQuestionType.CONTRIB" [questionDetails]="model.questionDetails"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1157,4 +1157,47 @@ 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 = '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);

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');

expect(component.dropdownVisible[index]).toBe(true);
});

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' },
];

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);
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ export class QuestionSubmissionFormComponent implements DoCheck {
isMCQDropDownEnabled: boolean = false;
isSaved: boolean = false;
hasResponseChanged: boolean = false;
dropdownVisible: boolean[] = [];
filteredRecipients: any[][] = [];
displayedRecipientName: string[] = [];

@Input()
formMode: QuestionSubmissionFormMode = QuestionSubmissionFormMode.FIXED_RECIPIENT;
Expand Down Expand Up @@ -595,4 +598,52 @@ export class QuestionSubmissionFormComponent implements DoCheck {
return false;
}
}

/**
* Filters the recipient list by input value and updates the filtered recipients array at the given index.
*/
filterRecipients(value: string, index: number): void {

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): void {
this.dropdownVisible[index] = true;
}

/**
* Hides the dropdown for the specified recipient index after a short delay.
*/
hideDropdown(index: number): void {
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): void {
recipientSubmissionFormModel.recipientIdentifier = recipient.recipientIdentifier;
this.displayedRecipientName[index] = recipient.recipientName;
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 : '';
}
}
Loading