Skip to content

Commit

Permalink
Merge branch 'feature/13054-searchable-dropdown-Grace' into feature/1…
Browse files Browse the repository at this point in the history
…3054-searchable-dropdown
  • Loading branch information
GraceXiehahaha committed Oct 12, 2024
2 parents 6d4f9f4 + 11ebfab commit 15c9445
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,23 @@ <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"
(ngModelChange)="triggerRecipientSubmissionFormChange(i, 'recipientIdentifier', $event)"
[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>
<div class="row form-control select-editable col">
<select id="recipient-dropdown-qn-{{ model.questionNumber }}-idx-{{ i }}" class="form-control form-select fw-bold" [ngModel]="recipientSubmissionFormModel.recipientIdentifier"
(ngModelChange)="triggerRecipientIdentifierChange(i, $event)"
[disabled]="isFormsDisabled"
[attr.aria-label]="'Select recipient dropdown question ' + model.questionNumber + ' index ' + i">
<option value=""></option>
<ng-container *ngFor="let recipient of filterRecipientsBySearchText(searchNameTexts[i],model.recipientList)">
<option *ngIf="!isRecipientSelected(recipient) || recipientSubmissionFormModel.recipientIdentifier === recipient.recipientIdentifier" [ngValue]="recipient.recipientIdentifier">{{ getSelectionOptionLabel(recipient) }}</option>
</ng-container>
</select>
<input type="text" class="select-input fw-bold form-control"
[(ngModel)]="searchNameTexts[i]"
(ngModelChange)="triggerSelectInputChange(i)"
[disabled]="isFormsDisabled"
[attr.aria-label]="'Recipient names filter ' + model.questionNumber + ' index ' + i"
[ngClass]="filterRecipientsBySearchText(searchNameTexts[i],model.recipientList).length === 0 ? 'no-match' : ''" />
</div>
<div class="col-auto text-start">
({{ model.recipientType | recipientTypeName: model.giverType }})
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,26 @@
.collapse-caret {
margin-right: 10px;
}

.select-editable {
position: relative;
border: 0;
}

.select-input {
position: absolute;
left: 0;
top: 0;
width: 75%;
border: 0;
background-color: transparent;
padding: .75rem 1.5rem;
}

.select-input:focus {
box-shadow: none;
}

.no-match {
color: var(--bs-danger)
}
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,30 @@ describe('QuestionSubmissionFormComponent', () => {
expect(component.isRecipientSelected(feedbackResponseRecipient)).toBeFalsy();
});

it('filterRecipientsBySearchText: should return correct filtered names', () => {
const doubleLucy = { recipientIdentifier: 'lucyLucy', recipientName: 'Lucy Lucy' };
const charlie = { recipientIdentifier: 'charlieBrown', recipientName: 'Charlie Brown' };
const lucy = { recipientIdentifier: 'lucyVanPelt', recipientName: 'Lucy van Pelt' };
const sally = { recipientIdentifier: 'sallyBrown', recipientName: 'Sally Brown' };
const snoopy = { recipientIdentifier: 'snoopy', recipientName: 'Snoopy' };
const linus = { recipientIdentifier: 'linusVanPelt', recipientName: 'Linus van Pelt' };
const benny = { recipientIdentifier: 'bennyCharles', recipientName: 'Benny Charles' };
const charlieDavis = { recipientIdentifier: 'charlieDavis', recipientName: 'Charlie Davis' };
const francis = { recipientIdentifier: 'francisGabriel', recipientName: 'Francis Gabriel' };

const recipients = [doubleLucy, charlie, lucy, sally, snoopy, linus, benny, charlieDavis, francis];
expect(component.filterRecipientsBySearchText('', recipients)).toStrictEqual(recipients);
expect(component.filterRecipientsBySearchText(' ', recipients)).toStrictEqual(recipients);
expect(component.filterRecipientsBySearchText('Lucy', recipients)).toStrictEqual([doubleLucy, lucy]);
expect(component.filterRecipientsBySearchText('s', recipients)).toStrictEqual([sally, snoopy, linus, benny, charlieDavis, francis]);
expect(component.filterRecipientsBySearchText('Brow', recipients)).toStrictEqual([charlie, sally]);
expect(component.filterRecipientsBySearchText('van pel', recipients)).toStrictEqual([lucy, linus]);
expect(component.filterRecipientsBySearchText('van Pelt', recipients)).toStrictEqual([lucy, linus]);
expect(component.filterRecipientsBySearchText('cy', recipients)).toStrictEqual([doubleLucy, lucy]);
expect(component.filterRecipientsBySearchText('char', recipients)).toStrictEqual([charlie, benny, charlieDavis]);
expect(component.filterRecipientsBySearchText('is', recipients)).toStrictEqual([charlieDavis, francis]);
});

it('triggerDeleteCommentEvent: should emit the correct index to deleteCommentEvent', () => {
let emittedIndex: number | undefined;
testEventEmission(component.deleteCommentEvent, (index) => { emittedIndex = index; });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ export class QuestionSubmissionFormComponent implements DoCheck {
isSaved: boolean = false;
hasResponseChanged: boolean = false;

searchNameTexts: string[] = [];

@Input()
formMode: QuestionSubmissionFormMode = QuestionSubmissionFormMode.FIXED_RECIPIENT;

Expand Down Expand Up @@ -94,6 +96,7 @@ export class QuestionSubmissionFormComponent implements DoCheck {
this.model.isTabExpandedForRecipients.set(recipient.recipientIdentifier, true);
});
this.hasResponseChanged = Array.from(this.model.hasResponseChangedForRecipients.values()).some((value) => value);
this.searchNameTexts = new Array(this.model.recipientSubmissionForms.length).fill('');
}

@Input()
Expand Down Expand Up @@ -320,6 +323,18 @@ export class QuestionSubmissionFormComponent implements DoCheck {
this.updateSubmissionFormIndexes();
}

filterRecipientsBySearchText(searchText: string, recipients: FeedbackResponseRecipient[])
: FeedbackResponseRecipient[] {
if (!searchText) return recipients;
const searchName = searchText.trim().toLowerCase();
if (searchName.length === 0) return recipients;
if (searchName.includes(' ')) {
return recipients.filter((s) => s.recipientName.toLowerCase().includes(searchName));
}

return recipients.filter((r) => r.recipientName.split(' ').some((s) => s.toLowerCase().includes(searchName)));
}

private sortRecipientsBySectionTeam(): void {
if (this.recipientLabelType === FeedbackRecipientLabelType.INCLUDE_SECTION) {
this.model.recipientList.sort((firstRecipient, secondRecipient) => {
Expand Down Expand Up @@ -361,6 +376,21 @@ export class QuestionSubmissionFormComponent implements DoCheck {
recipientSubmissionFormModel.recipientIdentifier === recipient.recipientIdentifier);
}

/**
* Triggers the changes of the recipient selection
*/
triggerRecipientIdentifierChange(index: number, data: any): void {
this.searchNameTexts[index] = "";
this.triggerRecipientSubmissionFormChange(index, 'recipientIdentifier', data);
}

/**
* Triggers the changes of the recipient search text input
*/
triggerSelectInputChange(index: number): void {
this.model.recipientSubmissionForms[index].recipientIdentifier = '';
}

/**
* Triggers the change of the recipient submission form.
*/
Expand Down

0 comments on commit 15c9445

Please sign in to comment.