mirror of
https://github.com/datahub-project/datahub.git
synced 2025-08-11 10:46:52 +00:00

* Catchup frontend for internal development changes * Revert accidental change to test file
152 lines
5.2 KiB
TypeScript
152 lines
5.2 KiB
TypeScript
import Component from '@glimmer/component';
|
|
import { DataModelEntityInstance, DataModelEntity } from '@datahub/data-models/constants/entity';
|
|
import { inject as service } from '@ember/service';
|
|
import DataModelsService from '@datahub/data-models/services/data-models';
|
|
import { PersonEntity } from '@datahub/data-models/entity/person/person-entity';
|
|
import { tracked } from '@glimmer/tracking';
|
|
import { action } from '@ember/object';
|
|
import { RecipientType } from '@datahub/shared/constants/change-management';
|
|
import { getResultsForEntity } from '@datahub/shared/utils/search/search-results';
|
|
import { IDataModelEntitySearchResult } from '@datahub/data-models/types/entity/search';
|
|
import { task, timeout } from 'ember-concurrency';
|
|
import { ETaskPromise } from '@datahub/utils/types/concurrency';
|
|
import { GroupEntity } from '@datahub/data-models/entity/group/group-entity';
|
|
|
|
/**
|
|
* Interface for the list of the arguments being fed into the recipient-search-select component
|
|
*/
|
|
interface IRecipientSearchSelectArgs {
|
|
/**
|
|
* Placeholder method that passes the action of adding a recipient back to the parent
|
|
*/
|
|
addRecipient: (recipientType: string, recipientName: string) => void;
|
|
/**
|
|
* Placeholder method that passes the action of removing a recipient back to the parent
|
|
*/
|
|
removeRecipient: (recipientType: string, index: number) => void;
|
|
|
|
/**
|
|
* Optional Array of ldaps of individual recipients that are fed in from the parent
|
|
*/
|
|
individualRecipients?: Array<string>;
|
|
|
|
/**
|
|
* Optional Array of distributed lists / CorpGroups that are fed in from the parent
|
|
*/
|
|
distributionLists?: Array<string>;
|
|
}
|
|
|
|
/**
|
|
* Styling class for the component
|
|
*/
|
|
const baseClass = 'recipient-search-select';
|
|
|
|
/**
|
|
* Time delay that the function is being debounced for
|
|
*/
|
|
const DEBOUNCE_TIME_IN_MS = 250;
|
|
|
|
/**
|
|
* The minimum amount of characters for the user to type so that we trigger off the search and populate the recipient results
|
|
*/
|
|
const SEARCH_INPUT_MIN_LENGTH = 2;
|
|
|
|
/**
|
|
* A component that provides an interface to allow users to search for either Individuals or Groups and add them to a collective list.
|
|
* It abstracts the searching aspect of it like providing configs , de-bouncing the input , handing the keyword.
|
|
*
|
|
* It is currently able to search for either Person entity / Group entity based on how the parent chooses to provide optional arguments.
|
|
*/
|
|
export default class RecipientSearchSelect extends Component<IRecipientSearchSelectArgs> {
|
|
/**
|
|
* Styling class name
|
|
*/
|
|
baseClass = baseClass;
|
|
|
|
/**
|
|
* Debounce time provided
|
|
*/
|
|
debounceTimeInMs = DEBOUNCE_TIME_IN_MS;
|
|
|
|
/**
|
|
* Min input length for search to trigger
|
|
*/
|
|
searchInputMinLength = SEARCH_INPUT_MIN_LENGTH;
|
|
|
|
/**
|
|
* The search keyword being provided to dictate what aspect of the entity we search by
|
|
* Here we escape the double quotes with a backslash to ensure encoding meets the search query requirements
|
|
*/
|
|
@tracked
|
|
keyword = '';
|
|
|
|
/**
|
|
* Number of search results we want to display in a single page.
|
|
*/
|
|
pageSize = 5;
|
|
|
|
/**
|
|
* Returns the type of entity that is being searched.
|
|
* Defaults to PersonEntity
|
|
*/
|
|
get searchEntityType(): DataModelEntity {
|
|
if (this.args.distributionLists) {
|
|
return GroupEntity;
|
|
} else return PersonEntity;
|
|
}
|
|
|
|
/**
|
|
* Returns the type of recipient that is being added / removed from the UI.
|
|
* This value is used to tell the parent what kind of recipient we are dealing with.
|
|
*/
|
|
get recipientType(): RecipientType {
|
|
if (this.searchEntityType === GroupEntity) {
|
|
return RecipientType.DistributionList;
|
|
} else return RecipientType.IndividualRecipient;
|
|
}
|
|
/**
|
|
* Injection of the data models service to access the general dataConstructChangeManagement entity class
|
|
*/
|
|
@service('data-models')
|
|
dataModels!: DataModelsService;
|
|
|
|
/**
|
|
* Passover method to an external method incharge of adding a new recipient.
|
|
*
|
|
* @param recipient Person getting added to the inidvidualRecipients list
|
|
*/
|
|
@action
|
|
onAddRecipient(recipient: PersonEntity | GroupEntity): void {
|
|
if (recipient instanceof PersonEntity) {
|
|
this.args.addRecipient(this.recipientType, recipient.username);
|
|
}
|
|
if (recipient instanceof GroupEntity && recipient.entity?.name) {
|
|
this.args.addRecipient(this.recipientType, recipient.entity.name);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Task responsible for fetching PersonEntity results from the search api for the user provided keyword from the Typeahead component
|
|
*/
|
|
@task(function*(
|
|
this: RecipientSearchSelect,
|
|
keyword: string
|
|
): IterableIterator<Promise<IDataModelEntitySearchResult<DataModelEntityInstance> | undefined | void>> {
|
|
yield timeout(this.debounceTimeInMs);
|
|
// If we are searching for a person, we want to ensure they are active in the directory
|
|
keyword = this.searchEntityType === PersonEntity ? `${keyword} AND active:true` : keyword;
|
|
const results = ((yield getResultsForEntity(
|
|
{
|
|
facetsApiParams: {},
|
|
keyword,
|
|
page: 1,
|
|
pageSize: this.pageSize
|
|
},
|
|
this.searchEntityType.displayName,
|
|
this.dataModels
|
|
)) as unknown) as IDataModelEntitySearchResult<DataModelEntityInstance> | undefined;
|
|
return results?.data;
|
|
})
|
|
onSearchTask!: ETaskPromise<Array<DataModelEntityInstance> | undefined | void, string>;
|
|
}
|