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

PeoplePicker - Added REST API filter and nometadata header to reduce payload #139

Merged
merged 1 commit into from
Oct 15, 2018
Merged
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
156 changes: 88 additions & 68 deletions src/controls/peoplepicker/PeoplePickerComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
allPersons: [],
currentPicker: 0,
peoplePartTitle: "",
peoplePartTooltip : "",
isLoading : false,
peoplePartTooltip: "",
isLoading: false,
showmessageerror: false
};
}
Expand All @@ -61,15 +61,15 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
// online mode
// Load the users
this._thisLoadUsers();
}
}
}

/**
* Generate the user photo link
*
* @param value
*/
private generateUserPhotoLink(value : string) : string {
private generateUserPhotoLink(value: string): string {
return `https://outlook.office365.com/owa/service.svc/s/GetPersonaPhoto?email=${value}&UA=0&size=HR96x96`;
}

Expand All @@ -86,7 +86,7 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
text: "Roger Federer",
secondaryText: "[email protected]",
tertiaryText: "",
optionalText:""
optionalText: ""
});
_fakeUsers.push({
id: "10dfa208-d7d4-4aef-a7ea-f9e4bb1b85c2",
Expand All @@ -95,7 +95,7 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
text: "Rafael Nadal",
secondaryText: "[email protected]",
tertiaryText: "",
optionalText:""
optionalText: ""
});
_fakeUsers.push({
id: "10dfa208-d7d4-4aef-a7ea-f9e4bb1b85c3",
Expand All @@ -104,7 +104,7 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
text: "Novak Djokovic",
secondaryText: "[email protected]",
tertiaryText: "",
optionalText:""
optionalText: ""
});
_fakeUsers.push({
id: "10dfa208-d7d4-4aef-a7ea-f9e4bb1b85c4",
Expand All @@ -113,7 +113,7 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
text: "Juan Martin del Potro",
secondaryText: "[email protected]",
tertiaryText: "",
optionalText:""
optionalText: ""
});

let personaList: IPersonaProps[] = [];
Expand All @@ -137,20 +137,40 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
* Retrieve the users
*/
private async _thisLoadUsers(): Promise<void> {
var stringVal = "";
var stringVal: string = "";

let filtered: boolean = false;

if (this.props.groupName) {
stringVal = `/_api/web/sitegroups/GetByName('${this.props.groupName}')/users`;
} else {
stringVal = "/_api/web/siteusers";
}

// filter for principal Type
var filterVal: string = "";
if (this.props.principleTypes) {
filterVal = `${"?$filter="}${this.props.principleTypes.map(principalType => `(PrincipalType eq ${principalType})`).join(" or ")}`;
filtered = true;
}

// filter for showHiddenInUI
if (this.props.showHiddenInUI) {
filterVal = filtered ? `${filterVal} and (IsHiddenInUI eq ${this.props.showHiddenInUI})` : `?$filter=IsHiddenInUI eq ${this.props.showHiddenInUI}`;
filtered = true;
}

const webAbsoluteUrl = this.props.webAbsoluteUrl || this.props.context.pageContext.web.absoluteUrl;
// Create the rest API
const restApi = `${webAbsoluteUrl}${stringVal}`;
const restApi = filtered ? `${webAbsoluteUrl}${stringVal}${filterVal}` : `${webAbsoluteUrl}${stringVal}`;

try {
// Call the API endpoint
const items: IUsers = await this.props.context.spHttpClient.get(restApi, SPHttpClient.configurations.v1).then(resp => resp.json());
const items: IUsers = await this.props.context.spHttpClient.get(restApi, SPHttpClient.configurations.v1, {
headers: {
'Accept': 'application/json;odata.metadata=none'
}
}).then(resp => resp.json());

// Check if items were retrieved
if (items && items.value && items.value.length > 0) {
Expand All @@ -160,7 +180,7 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
// Loop over all the retrieved items
for (let i = 0; i < items.value.length; i++) {
const item = items.value[i];
if (!item.IsHiddenInUI || (this.props.showHiddenInUI && item.IsHiddenInUI)) {
if (!item.IsHiddenInUI || (this.props.showHiddenInUI && item.IsHiddenInUI)) {
// Check if the the type must be returned
if (!this.props.principleTypes || this.props.principleTypes.indexOf(item.PrincipalType) !== -1) {
userValuesArray.push({
Expand All @@ -177,7 +197,7 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
}

// Set Default selected persons
let defaultUsers : any = [];
let defaultUsers: any = [];
let defaultPeopleList: IPersonaProps[] = [];
if (this.props.defaultSelectedUsers) {
defaultUsers = this.getDefaultUsers(userValuesArray, this.props.defaultSelectedUsers);
Expand All @@ -197,10 +217,10 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic

// Update the current state
this.setState({
allPersons : userValuesArray,
selectedPersons : defaultPeopleList.length != 0 ? defaultPeopleList : [],
peoplePersonaMenu : personaList,
mostRecentlyUsedPersons : personaList.slice(0,5),
allPersons: userValuesArray,
selectedPersons: defaultPeopleList.length != 0 ? defaultPeopleList : [],
peoplePersonaMenu: personaList,
mostRecentlyUsedPersons: personaList.slice(0, 5),
showmessageerror: this.props.isRequired && this.state.selectedPersons.length === 0
});
}
Expand Down Expand Up @@ -275,10 +295,10 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
*/
private _filterPersons(filterText: string): IPersonaProps[] {
return this.state.peoplePersonaMenu.filter(item =>
this._doesTextStartWith(item.text as string, filterText)
|| this._doesTextContains(item.text as string, filterText)
|| this._doesTextStartWith(item.secondaryText as string, filterText)
|| this._doesTextContains(item.secondaryText as string, filterText));
this._doesTextStartWith(item.text as string, filterText)
|| this._doesTextContains(item.text as string, filterText)
|| this._doesTextStartWith(item.secondaryText as string, filterText)
|| this._doesTextContains(item.secondaryText as string, filterText));
}


Expand All @@ -302,12 +322,12 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
return text && text.toLowerCase().indexOf(filterText.toLowerCase()) === 0;
}

/**
* Checks if text contains
*
* @param text
* @param filterText
*/
/**
* Checks if text contains
*
* @param text
* @param filterText
*/
private _doesTextContains(text: string, filterText: string): boolean {
return text && text.toLowerCase().indexOf(filterText.toLowerCase()) > 0;
}
Expand All @@ -332,23 +352,23 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
* @param userValuesArray
* @param selectedUsers
*/
private getDefaultUsers(userValuesArray : any[], selectedUsers : string[]) : any {
private getDefaultUsers(userValuesArray: any[], selectedUsers: string[]): any {
let defaultuserValuesArray: any[] = [];
for (let i = 0; i < selectedUsers.length; i++) {
const obj = { valToCompare: selectedUsers[i] };
const length = defaultuserValuesArray.length;
defaultuserValuesArray = defaultuserValuesArray.length !== 0 ? defaultuserValuesArray.concat(userValuesArray.filter(this.filterUsers, obj)) : userValuesArray.filter(this.filterUsers, obj);
defaultuserValuesArray = defaultuserValuesArray.length !== 0 ? defaultuserValuesArray.concat(userValuesArray.filter(this.filterUsers, obj)) : userValuesArray.filter(this.filterUsers, obj);
if (length === defaultuserValuesArray.length) {
const defaultUnknownUser = [{
id: 1000 + i, //just a random number
imageUrl: "",
imageInitials: "",
text: selectedUsers[i] , //Name
text: selectedUsers[i], //Name
secondaryText: selectedUsers[i], //Role
tertiaryText: "", //status
optionalText: "" //stgring
}];
defaultuserValuesArray = defaultuserValuesArray.length !== 0 ? defaultuserValuesArray.concat(defaultUnknownUser) : defaultUnknownUser;
defaultuserValuesArray = defaultuserValuesArray.length !== 0 ? defaultuserValuesArray.concat(defaultUnknownUser) : defaultUnknownUser;
}
}
return defaultuserValuesArray;
Expand All @@ -372,49 +392,49 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
<Label>{this.props.titleText || strings.peoplePickerComponentTitleText}</Label>

<NormalPeoplePicker pickerSuggestionsProps={suggestionProps}
onResolveSuggestions={this._onPersonFilterChanged}
onEmptyInputFocus={ this._returnMostRecentlyUsedPerson}
getTextFromItem={(peoplePersonaMenu: IPersonaProps) => peoplePersonaMenu.text}
className={`'ms-PeoplePicker' ${this.props.peoplePickerCntrlclassName ? this.props.peoplePickerCntrlclassName : ''}`}
key={'normal'}
onValidateInput={this._validateInputPeople}
removeButtonAriaLabel={'Remove'}
inputProps={{
'aria-label': 'People Picker'
}}
selectedItems={this.state.selectedPersons}
itemLimit={this.props.personSelectionLimit || 1}
disabled={this.props.disabled}
onChange={this._onPersonItemsChange} />
onResolveSuggestions={this._onPersonFilterChanged}
onEmptyInputFocus={this._returnMostRecentlyUsedPerson}
getTextFromItem={(peoplePersonaMenu: IPersonaProps) => peoplePersonaMenu.text}
className={`'ms-PeoplePicker' ${this.props.peoplePickerCntrlclassName ? this.props.peoplePickerCntrlclassName : ''}`}
key={'normal'}
onValidateInput={this._validateInputPeople}
removeButtonAriaLabel={'Remove'}
inputProps={{
'aria-label': 'People Picker'
}}
selectedItems={this.state.selectedPersons}
itemLimit={this.props.personSelectionLimit || 1}
disabled={this.props.disabled}
onChange={this._onPersonItemsChange} />
</div>
);

return (
<div>
{
this.props.showtooltip ? (
<TooltipHost content={this.props.tooltipMessage || strings.peoplePickerComponentTooltipMessage}
id='pntp'
calloutProps={ { gapSpace: 0 } }
directionalHint={this.props.tooltipDirectional || DirectionalHint.leftTopEdge}>
{peoplepicker}
</TooltipHost>
) : (
<div>
{peoplepicker}
</div>
)
}
{
this.props.showtooltip ? (
<TooltipHost content={this.props.tooltipMessage || strings.peoplePickerComponentTooltipMessage}
id='pntp'
calloutProps={{ gapSpace: 0 }}
directionalHint={this.props.tooltipDirectional || DirectionalHint.leftTopEdge}>
{peoplepicker}
</TooltipHost>
) : (
<div>
{peoplepicker}
</div>
)
}

{
(this.props.isRequired && this.state.showmessageerror) && (
<MessageBar messageBarType={MessageBarType.error}
isMultiline={false}
className={`${this.props.errorMessageclassName ? this.props.errorMessageclassName : ''}`}>
{this.props.errorMessage ? this.props.errorMessage : strings.peoplePickerComponentErrorMessage}
</MessageBar>
)
}
{
(this.props.isRequired && this.state.showmessageerror) && (
<MessageBar messageBarType={MessageBarType.error}
isMultiline={false}
className={`${this.props.errorMessageclassName ? this.props.errorMessageclassName : ''}`}>
{this.props.errorMessage ? this.props.errorMessage : strings.peoplePickerComponentErrorMessage}
</MessageBar>
)
}
</div>
);
}
Expand Down