@pnp/spfx-property-controls
Version:
Reusable property pane controls for SharePoint Framework solutions
289 lines • 12.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const IPropertyFieldPeoplePicker_1 = require("./IPropertyFieldPeoplePicker");
const Pickers_1 = require("@fluentui/react/lib/Pickers");
const Label_1 = require("@fluentui/react/lib/Label");
const Persona_1 = require("@fluentui/react/lib/Persona");
const Utilities_1 = require("@fluentui/react/lib/Utilities");
const strings = tslib_1.__importStar(require("PropertyControlStrings"));
const SPPeopleSearchService_1 = tslib_1.__importDefault(require("../../services/SPPeopleSearchService"));
const FieldErrorMessage_1 = tslib_1.__importDefault(require("../errorMessage/FieldErrorMessage"));
const telemetry = tslib_1.__importStar(require("../../common/telemetry"));
const GeneralHelper_1 = require("../../helpers/GeneralHelper");
/**
* Renders the controls for PropertyFieldPeoplePicker component
*/
class PropertyFieldPeoplePickerHost extends React.Component {
/**
* Constructor method
*/
constructor(props) {
super(props);
this.intialPersonas = new Array();
this.resultsPeople = new Array();
this.resultsPersonas = new Array();
this.selectedPeople = new Array();
this.selectedPersonas = new Array();
telemetry.track('PropertyFieldPeoplePicker', {
allowDuplicate: props.allowDuplicate,
principalType: props.principalType ? props.principalType.toString() : '',
disabled: props.disabled
});
this.searchService = new SPPeopleSearchService_1.default();
this.onSearchFieldChanged = this.onSearchFieldChanged.bind(this);
this.onItemChanged = this.onItemChanged.bind(this);
this.createInitialPersonas();
this.state = {
resultsPeople: this.resultsPeople,
resultsPersonas: this.resultsPersonas,
errorMessage: ''
};
this.async = new Utilities_1.Async(this);
this.validate = this.validate.bind(this);
this.notifyAfterValidate = this.notifyAfterValidate.bind(this);
this.delayedValidate = this.async.debounce(this.validate, this.props.deferredValidationTime);
}
/**
* A search field change occured
*/
onSearchFieldChanged(searchText, currentSelected) {
if (searchText.length >= this.props.searchTextLimit) {
// Clear the suggestions list
this.setState({ resultsPeople: this.resultsPeople, resultsPersonas: this.resultsPersonas });
// Request the search service
const result = this.searchService.searchPeople(this.props.context, searchText, this.props.principalType, this.props.targetSiteUrl).then((response) => {
this.resultsPeople = [];
this.resultsPersonas = [];
// If allowDuplicate === false, so remove duplicates from results
if (this.props.allowDuplicate === false) {
response = this.removeDuplicates(response);
}
response.forEach((element, index) => {
// Fill the results Array
this.resultsPeople.push(element);
// Transform the response in IPersonaProps object
this.resultsPersonas.push(this.getPersonaFromPeople(element, index));
});
// Refresh the component's state
this.setState({ resultsPeople: this.resultsPeople, resultsPersonas: this.resultsPersonas });
return this.resultsPersonas;
});
return result;
}
else {
return [];
}
}
/**
* Remove the duplicates if property allowDuplicate equals false
*/
removeDuplicates(responsePeople) {
if (this.selectedPeople === null || this.selectedPeople.length === 0) {
return responsePeople;
}
const res = [];
for (const element of responsePeople) {
let found = false;
for (let i = 0; i < this.selectedPeople.length; i++) {
const responseItem = this.selectedPeople[i];
if (responseItem.login === element.login &&
responseItem.id === element.id) {
found = true;
break;
}
}
if (found === false) {
res.push(element);
}
}
return res;
}
/**
* Creates the collection of initial personas from initial IPropertyFieldGroupOrPerson collection
*/
createInitialPersonas() {
if (this.props.initialData === null || typeof (this.props.initialData) !== typeof Array()) {
return;
}
this.props.initialData.forEach((element, index) => {
const persona = this.getPersonaFromPeople(element, index);
this.intialPersonas.push(persona);
this.selectedPersonas.push(persona);
this.selectedPeople.push(element);
});
}
/**
* Generates a IPersonaProps object from a IPropertyFieldGroupOrPerson object
*/
getPersonaFromPeople(element, index) {
return {
primaryText: element.fullName,
secondaryText: element.jobTitle,
imageUrl: element.imageUrl,
imageInitials: element.initials,
presence: Persona_1.PersonaPresence.none,
initialsColor: this.getRandomInitialsColor(index)
};
}
/**
* Refreshes the web part properties
*/
refreshWebPartProperties() {
this.delayedValidate(this.selectedPeople);
}
/**
* Validates the new custom field value
*/
validate(value) {
if (this.props.onGetErrorMessage === null || this.props.onGetErrorMessage === undefined) {
this.notifyAfterValidate(this.props.initialData, value);
return;
}
const errResult = this.props.onGetErrorMessage(value || []);
if (errResult) {
if (typeof errResult === 'string') {
if (errResult === '') {
this.notifyAfterValidate(this.props.initialData, value);
}
this.setState({
errorMessage: errResult
});
}
else {
errResult.then((errorMessage) => {
if (!errorMessage) {
this.notifyAfterValidate(this.props.initialData, value);
}
this.setState({
errorMessage: errorMessage
});
}).catch(() => { });
}
}
else {
this.notifyAfterValidate(this.props.initialData, value);
this.setState({
errorMessage: null
});
}
}
/**
* Notifies the parent Web Part of a property value change
*/
notifyAfterValidate(oldValue, newValue) {
if (this.props.onPropertyChange && newValue) {
(0, GeneralHelper_1.setPropertyValue)(this.props.properties, this.props.targetProperty, newValue);
this.props.onPropertyChange(this.props.targetProperty, oldValue, newValue);
// Trigger the apply button
if (typeof this.props.onChange !== 'undefined' && this.props.onChange !== null) {
this.props.onChange(this.props.targetProperty, newValue);
}
}
}
/**
* Called when the component will unmount
*/
componentWillUnmount() {
this.async.dispose();
}
/**
* Find the index of the selected person
* @param selectedItem
*/
_findIndex(selectedItem) {
for (let i = 0; i < this.resultsPersonas.length; i++) {
const crntPersona = this.resultsPersonas[i];
// Check if the imageUrl, primaryText, secondaryText are equal
if (crntPersona.imageUrl === selectedItem.imageUrl &&
crntPersona.primaryText === selectedItem.primaryText &&
crntPersona.secondaryText === selectedItem.secondaryText) {
return i;
}
}
return -1;
}
/**
* Event raises when the user changed people from the PeoplePicker component
*/
onItemChanged(selectedItems) {
if (selectedItems.length > 0) {
if (selectedItems.length > this.selectedPersonas.length) {
const index = this._findIndex(selectedItems[selectedItems.length - 1]);
if (index > -1) {
const people = this.resultsPeople[index];
this.selectedPeople.push(people);
this.selectedPersonas.push(this.resultsPersonas[index]);
}
}
else {
this.selectedPersonas.forEach((person, index2) => {
const selectedItemIndex = selectedItems.indexOf(person);
if (selectedItemIndex === -1) {
this.selectedPersonas.splice(index2, 1);
this.selectedPeople.splice(index2, 1);
}
});
}
}
else {
this.selectedPersonas.splice(0, this.selectedPersonas.length);
this.selectedPeople.splice(0, this.selectedPeople.length);
}
this.refreshWebPartProperties();
}
/**
* Generate a PersonaInitialsColor from the item position in the collection
*/
getRandomInitialsColor(index) {
const num = index % 13;
switch (num) {
case 0: return Persona_1.PersonaInitialsColor.blue;
case 1: return Persona_1.PersonaInitialsColor.darkBlue;
case 2: return Persona_1.PersonaInitialsColor.teal;
case 3: return Persona_1.PersonaInitialsColor.lightGreen;
case 4: return Persona_1.PersonaInitialsColor.green;
case 5: return Persona_1.PersonaInitialsColor.darkGreen;
case 6: return Persona_1.PersonaInitialsColor.lightPink;
case 7: return Persona_1.PersonaInitialsColor.pink;
case 8: return Persona_1.PersonaInitialsColor.magenta;
case 9: return Persona_1.PersonaInitialsColor.purple;
case 10: return Persona_1.PersonaInitialsColor.black;
case 11: return Persona_1.PersonaInitialsColor.orange;
case 12: return Persona_1.PersonaInitialsColor.red;
case 13: return Persona_1.PersonaInitialsColor.darkRed;
default: return Persona_1.PersonaInitialsColor.blue;
}
}
/**
* Renders the PeoplePicker controls with Office UI Fabric
*/
render() {
const suggestionProps = {
suggestionsHeaderText: strings.PeoplePickerSuggestedContacts,
noResultsFoundText: strings.PeoplePickerNoResults,
loadingText: strings.PeoplePickerLoading,
};
// Check which text have to be shown
if (this.props.principalType && this.props.principalType.length > 0) {
const userType = this.props.principalType.indexOf(IPropertyFieldPeoplePicker_1.PrincipalType.Users) !== -1;
const groupType = this.props.principalType.indexOf(IPropertyFieldPeoplePicker_1.PrincipalType.SharePoint) !== -1 || this.props.principalType.indexOf(IPropertyFieldPeoplePicker_1.PrincipalType.Security) !== -1;
// Check if both user and group are present
if (userType && groupType) {
suggestionProps.suggestionsHeaderText = strings.PeoplePickerSuggestedCombined;
}
// If only group is active
if (!userType && groupType) {
suggestionProps.suggestionsHeaderText = strings.PeoplePickerSuggestedGroups;
}
}
// Renders content
return (React.createElement("div", null,
this.props.label && React.createElement(Label_1.Label, null, this.props.label),
React.createElement(Pickers_1.NormalPeoplePicker, { disabled: this.props.disabled, pickerSuggestionsProps: suggestionProps, onResolveSuggestions: this.onSearchFieldChanged, onChange: this.onItemChanged, defaultSelectedItems: this.intialPersonas, itemLimit: this.props.multiSelect ? undefined : 1 }),
React.createElement(FieldErrorMessage_1.default, { errorMessage: this.state.errorMessage })));
}
}
exports.default = PropertyFieldPeoplePickerHost;
//# sourceMappingURL=PropertyFieldPeoplePickerHost.js.map