mirror of
https://github.com/datahub-project/datahub.git
synced 2025-08-14 12:16:52 +00:00
117 lines
3.8 KiB
TypeScript
117 lines
3.8 KiB
TypeScript
import Component from '@glimmer/component';
|
|
import { PersonEntity } from '@datahub/data-models/entity/person/person-entity';
|
|
import { ISearchDataWithMetadata, IDataModelEntitySearchResult } from '@datahub/data-models/types/entity/search';
|
|
import { action } from '@ember/object';
|
|
import { tracked } from '@glimmer/tracking';
|
|
import { RecipientType } from '@datahub/shared/constants/change-management';
|
|
import { debounce } from '@ember/runloop';
|
|
|
|
/**
|
|
* Interface for recipient power select's arguments
|
|
*/
|
|
interface IRecipientPowerSelectArgs {
|
|
// Search result from user query
|
|
result: IDataModelEntitySearchResult<ISearchDataWithMetadata<PersonEntity>>;
|
|
// placeholder method that is called upon when user enters a query
|
|
onSearch: (query: string) => Promise<void>;
|
|
// List of individual recipients to be displayed
|
|
individualRecipients: Array<string>;
|
|
// placeholder method that is called when user wants to add a new recipient
|
|
addRecipient: (recipientType: string, recipientName: string) => void;
|
|
// placeholder method that is called when user wants to delete a recipient
|
|
removeRecipient: (recipientType: string, recipientName: string, index: number) => void;
|
|
}
|
|
|
|
/**
|
|
* Properties that exist on the options that an user sees in the power select dropdown
|
|
*/
|
|
interface IRecipientOption {
|
|
fullName: string;
|
|
email: string;
|
|
username: string;
|
|
}
|
|
|
|
/**
|
|
* Styling class for the component
|
|
*/
|
|
const baseClass = 'recipient-power-select';
|
|
|
|
/**
|
|
*
|
|
*/
|
|
export default class RecipientPowerSelect extends Component<IRecipientPowerSelectArgs> {
|
|
/**
|
|
* Attached to component for easier access from template.
|
|
*/
|
|
baseClass = baseClass;
|
|
|
|
/**
|
|
* Types of recipients possible
|
|
*/
|
|
recipientType: Record<string, string> = {
|
|
individualRecipient: RecipientType.IndividualRecipient,
|
|
distributionList: RecipientType.DistributionList
|
|
};
|
|
|
|
/**
|
|
* Flag that controls if we want to display the power select dropdown or not
|
|
*/
|
|
@tracked
|
|
showOptions = false;
|
|
|
|
/**
|
|
* A getter that massages the `result` data from the search api into something meaningful and light that can be
|
|
* used by power-select as options.
|
|
*/
|
|
get options(): Array<IRecipientOption> {
|
|
const { result } = this.args;
|
|
|
|
const dataArray = result?.data || [];
|
|
const dataEntities: Array<PersonEntity> = dataArray.mapBy('data');
|
|
|
|
// Fetch the usernames
|
|
const userNames: Array<string> = dataEntities.mapBy('entity').map(resultResponse => resultResponse.username);
|
|
// Fetch the name , email and append username to it.
|
|
|
|
const options = dataEntities
|
|
.mapBy('entity')
|
|
.map(resultResponse => resultResponse.info)
|
|
.map((person, index) => {
|
|
return { fullName: person.fullName, email: person.email, username: userNames[index] };
|
|
});
|
|
return options;
|
|
}
|
|
|
|
/**
|
|
* Triggers a search when user enters 2 letters or more in the input field.
|
|
*
|
|
* @param keyEvent HTML event from a keypress
|
|
*/
|
|
@action
|
|
onSearchLocal(keyEvent: KeyboardEvent): Promise<void> | void {
|
|
const userInputField = keyEvent.target as HTMLInputElement;
|
|
if (userInputField && userInputField.value.length >= 2 && typeof this.args.onSearch === 'function') {
|
|
const keyword = userInputField.value;
|
|
this.showOptions = true;
|
|
return this.onSearchDebounced(keyword);
|
|
} else {
|
|
this.showOptions = false;
|
|
}
|
|
}
|
|
|
|
onSearchDebounced(keyword: string): void {
|
|
debounce(this, this.args.onSearch, keyword, 250);
|
|
}
|
|
|
|
/**
|
|
* Incharge of adding a recipient when the user selects an option from the list of user suggestions.a1
|
|
*
|
|
* @param selection One of the options in the power-select dropdown
|
|
*/
|
|
@action
|
|
onChangeSelection(selection: IRecipientOption): void {
|
|
this.args.addRecipient(this.recipientType.individualRecipient, selection.username);
|
|
this.showOptions = false;
|
|
}
|
|
}
|