Skip to content

Commit

Permalink
Merge pull request #26 from SharePoint/dev
Browse files Browse the repository at this point in the history
Various fixes for field picker and telemetry
  • Loading branch information
estruyf authored Jan 9, 2018
2 parents a271792 + 104334b commit 1aecc29
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 58 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Thank you for reporting an issue, suggesting an enhancement, or asking a question. We appreciate your feedback - to help the team understand your
needs please complete the below template to ensure we have the details to help. Thanks!

**Please check out the [documentation](https://github.com/SharePoint/sp-dev-fx-property-controls/wiki) to see if your question is already addressed there. This will help us ensure our documentation is up to date.**
**Please check out the [documentation](https://sharepoint.github.io/sp-dev-fx-property-controls/) to see if your question is already addressed there. This will help us ensure our documentation is up to date.**

#### Category
[ ] Enhancement
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Releases

## 1.1.2

**Enhancements**

- Added the option to the people picker to allow you to specify single or multi-selection

**Fixes**

- People picker accidentally picked the wrong person
- Improved telemetry with some object checks

## 1.1.1

- Removed operation name from telemetry
Expand Down
11 changes: 11 additions & 0 deletions docs/documentation/docs/about/release-notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Releases

## 1.1.2

**Enhancements**

- Added the option to the people picker to allow you to specify single or multi-selection

**Fixes**

- People picker accidentally picked the wrong person
- Improved telemetry with some object checks

## 1.1.1

- Removed operation name from telemetry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export interface IPropertyControlsTestWebPartProps {
4. Add the custom property control to the `groupFields` of the web part property pane configuration:

```TypeScript
PropertyFieldListPicker('singleList', {
PropertyFieldListPicker('lists', {
label: 'Select a list',
selectedList: this.properties.lists,
includeHidden: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ The `PropertyFieldPeoplePicker` control can be configured with the following pro
| context | WebPartContext | yes | Context of the current web part. |
| initialData | IPropertyFieldGroupOrPerson[] | no | Intial data to load in the people picker (optional). |
| allowDuplicate | boolean | no | Defines if the People Picker allows to select duplicated users (optional). |
| multiSelect | boolean | no | Define if you want to allow multi user / group selection. (optional, true by default). |
| principalType | PrincipalType[] | no | Define which type of data you want to retrieve: User, SharePoint groups, Security groups. Multiple are possible. |
| onPropertyChange | function | yes | Defines a onPropertyChange function to raise when the date gets changed. |
| properties | any | yes | Parent web part properties, this object is use to update the property value. |
Expand Down Expand Up @@ -91,4 +92,4 @@ The `PrincipalType` enum can be used to specify the types of information you wan
| Security | To specify if you want to retrieve security groups. |
| SharePoint | To specify if you want to retrieve SharePoint groups. |

![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyFieldPeoplePicker)
![](https://telemetry.sharepointpnp.com/sp-dev-fx-property-controls/wiki/PropertyFieldPeoplePicker)
6 changes: 3 additions & 3 deletions docs/guides/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ We appreciate that you're interested in helping with moving the project forward.

Sharing is caring!

## You have an idea for a new command
## You have an idea for a new control

Awesome! Good ideas are invaluable for every product. Before you start hacking away, please check if there is no similar idea already listed in the [issue list](https://github.com/SharePoint/sp-dev-fx-property-controls/issues). If not, please create a new issue describing your idea. Once we agree on the feature scope and architecture, the feature will be ready for building. Don't hesitate to mention in the issue if you'd like to build the feature yourself.

When building a new control, try to add your control to the default provided web part so that everyone can test it out. Please also provide the documentation for your controls in the [documentation section](../documentation).

## You have a suggestion for improving an existing command
## You have a suggestion for improving an existing control

Nothing is perfect. If you have an idea how to improve an existing command or the CLI, let us know by submitting an issue in the [issue list](https://github.com/SharePoint/sp-dev-fx-property-controls/issues). Some things are done for a reason, but some are not. Let's discuss what you think and see how the project could be improved for everyone.
Nothing is perfect. If you have an idea how to improve an existing control, let us know by submitting an issue in the [issue list](https://github.com/SharePoint/sp-dev-fx-property-controls/issues). Some things are done for a reason, but some are not. Let's discuss what you think and see how the project could be improved for everyone.

## You've found a bug

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/mpa.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The shortest way to prepare your local copy of the project for development and t

Before you start contributing to this project, you will need Node.js. This project has been tested with the LTS version of Node.js and the version of NPM that comes with it.

## Get the local version of the CLI
## Get the local version of the project

- fork this repository
- clone your fork
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@pnp/spfx-property-controls",
"description": "Reusable property pane controls for SharePoint Framework solutions",
"version": "1.1.1",
"version": "1.2.0",
"engines": {
"node": ">=0.10.0"
},
Expand Down
4 changes: 3 additions & 1 deletion src/common/appInsights/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {Environment,EnvironmentType} from "@microsoft/sp-core-library";
AppInsights.downloadAndSetup({ instrumentationKey: "9f59b81e-d2ed-411e-a961-8bcf3f7f04d0" });

// Remove operation name from the telemetry
AppInsights.context.operation.name = null;
if (AppInsights.context && AppInsights.context.operation && AppInsights.context.operation.name) {
AppInsights.context.operation.name = null;
}

export function track(componentName: string, properties: any = {}): void {
AppInsights.trackEvent(componentName, {
Expand Down
2 changes: 1 addition & 1 deletion src/common/appInsights/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const version: string = "1.1.1";
export const version: string = "1.2.0";
4 changes: 4 additions & 0 deletions src/propertyFields/peoplePicker/IPropertyFieldPeoplePicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ export interface IPropertyFieldPeoplePickerProps {
* Define which type of data you want to retrieve: User, SharePoint groups, Security groups
*/
principalType?: PrincipalType[];
/**
* Define if you want to allow multi user / group selection. True by default.
*/
multiSelect?: boolean;
/**
* Defines a onPropertyChange function to raise when the selected value changed.
* Normally this function must be always defined with the 'this.onPropertyChange'
Expand Down
6 changes: 6 additions & 0 deletions src/propertyFields/peoplePicker/PropertyFieldPeoplePicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PropertyFieldPeoplePickerBuilder implements IPropertyPaneField<IPropertyFi
private context: IWebPartContext;
private initialData: IPropertyFieldGroupOrPerson[];
private allowDuplicate: boolean = true;
private multiSelect: boolean = true;
private principalType: PrincipalType[] = [];
private onPropertyChange: (propertyPath: string, oldValue: any, newValue: any) => void;
private customProperties: any;
Expand Down Expand Up @@ -58,6 +59,10 @@ class PropertyFieldPeoplePickerBuilder implements IPropertyPaneField<IPropertyFi
if (_properties.deferredValidationTime) {
this.deferredValidationTime = _properties.deferredValidationTime;
}

if (typeof _properties.multiSelect !== "undefined") {
this.multiSelect = _properties.multiSelect;
}
}

/**
Expand All @@ -71,6 +76,7 @@ class PropertyFieldPeoplePickerBuilder implements IPropertyPaneField<IPropertyFi
targetProperty: this.targetProperty,
initialData: this.initialData,
allowDuplicate: this.allowDuplicate,
multiSelect: this.multiSelect,
principalType: this.principalType,
onDispose: this.dispose,
onRender: this.render,
Expand Down
110 changes: 62 additions & 48 deletions src/propertyFields/peoplePicker/PropertyFieldPeoplePickerHost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { IPropertyFieldPeoplePickerHostProps, IPeoplePickerState } from './IProp
import SPPeopleSearchService from '../../services/SPPeopleSearchService';
import FieldErrorMessage from '../errorMessage/FieldErrorMessage';
import * as appInsights from '../../common/appInsights';
import { isEqual } from '@microsoft/sp-lodash-subset';

/**
* Renders the controls for PropertyFieldPeoplePicker component
Expand All @@ -32,8 +33,6 @@ export default class PropertyFieldPeoplePickerHost extends React.Component<IProp
constructor(props: IPropertyFieldPeoplePickerHostProps) {
super(props);

appInsights.track('PropertyFieldPeoplePicker');

appInsights.track('PropertyFieldPeoplePicker', {
allowDuplicate: props.allowDuplicate,
principalType: props.principalType ? props.principalType.toString() : '',
Expand All @@ -58,47 +57,6 @@ export default class PropertyFieldPeoplePickerHost extends React.Component<IProp
this.delayedValidate = this.async.debounce(this.validate, this.props.deferredValidationTime);
}

/**
* Renders the PeoplePicker controls with Office UI Fabric
*/
public render(): JSX.Element {
const suggestionProps: IBasePickerSuggestionsProps = {
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) {
let userType = this.props.principalType.indexOf(PrincipalType.Users) !== -1;
let groupType = this.props.principalType.indexOf(PrincipalType.SharePoint) !== -1 || this.props.principalType.indexOf(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 (
<div>
<Label>{this.props.label}</Label>
<NormalPeoplePicker
disabled={this.props.disabled}
pickerSuggestionsProps={suggestionProps}
onResolveSuggestions={this.onSearchFieldChanged}
onChange={this.onItemChanged}
defaultSelectedItems={this.intialPersonas} />

<FieldErrorMessage errorMessage={this.state.errorMessage} />
</div>
);
}

/**
* A search field change occured
*/
Expand All @@ -114,7 +72,7 @@ export default class PropertyFieldPeoplePickerHost extends React.Component<IProp
if (this.props.allowDuplicate === false) {
response = this.removeDuplicates(response);
}
response.map((element: IPropertyFieldGroupOrPerson, index: number) => {
response.forEach((element: IPropertyFieldGroupOrPerson, index: number) => {
// Fill the results Array
this.resultsPeople.push(element);
// Transform the response in IPersonaProps object
Expand All @@ -140,7 +98,7 @@ export default class PropertyFieldPeoplePickerHost extends React.Component<IProp
}

const res: IPropertyFieldGroupOrPerson[] = [];
responsePeople.map((element: IPropertyFieldGroupOrPerson) => {
responsePeople.forEach((element: IPropertyFieldGroupOrPerson) => {
let found: boolean = false;

for (let i: number = 0; i < this.selectedPeople.length; i++) {
Expand All @@ -165,7 +123,7 @@ export default class PropertyFieldPeoplePickerHost extends React.Component<IProp
return;
}

this.props.initialData.map((element: IPropertyFieldGroupOrPerson, index: number) => {
this.props.initialData.forEach((element: IPropertyFieldGroupOrPerson, index: number) => {
const persona: IPersonaProps = this.getPersonaFromPeople(element, index);
this.intialPersonas.push(persona);
this.selectedPersonas.push(persona);
Expand Down Expand Up @@ -245,21 +203,35 @@ export default class PropertyFieldPeoplePickerHost extends React.Component<IProp
this.async.dispose();
}

/**
* Find the index of the selected person
* @param selectedItem
*/
private _findIndex(selectedItem: IPersonaProps): number {
for (let i = 0; i < this.resultsPersonas.length; i++) {
const crntPersona = this.resultsPersonas[i];
if (isEqual(crntPersona, selectedItem)) {
return i;
}
}
return -1;
}

/**
* Event raises when the user changed people from the PeoplePicker component
*/
private onItemChanged(selectedItems: IPersonaProps[]): void {
if (selectedItems.length > 0) {
if (selectedItems.length > this.selectedPersonas.length) {
const index: number = this.resultsPersonas.indexOf(selectedItems[selectedItems.length - 1]);
const index: number = this._findIndex(selectedItems[selectedItems.length - 1]);
if (index > -1) {
const people: IPropertyFieldGroupOrPerson = this.resultsPeople[index];
this.selectedPeople.push(people);
this.selectedPersonas.push(this.resultsPersonas[index]);
this.refreshWebPartProperties();
}
} else {
this.selectedPersonas.map((person, index2) => {
this.selectedPersonas.forEach((person, index2) => {
const selectedItemIndex: number = selectedItems.indexOf(person);
if (selectedItemIndex === -1) {
this.selectedPersonas.splice(index2, 1);
Expand Down Expand Up @@ -299,4 +271,46 @@ export default class PropertyFieldPeoplePickerHost extends React.Component<IProp
default: return PersonaInitialsColor.blue;
}
}

/**
* Renders the PeoplePicker controls with Office UI Fabric
*/
public render(): JSX.Element {
const suggestionProps: IBasePickerSuggestionsProps = {
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) {
let userType = this.props.principalType.indexOf(PrincipalType.Users) !== -1;
let groupType = this.props.principalType.indexOf(PrincipalType.SharePoint) !== -1 || this.props.principalType.indexOf(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 (
<div>
<Label>{this.props.label}</Label>
<NormalPeoplePicker
disabled={this.props.disabled}
pickerSuggestionsProps={suggestionProps}
onResolveSuggestions={this.onSearchFieldChanged}
onChange={this.onItemChanged}
defaultSelectedItems={this.intialPersonas}
itemLimit={this.props.multiSelect ? undefined : 1} />

<FieldErrorMessage errorMessage={this.state.errorMessage} />
</div>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export default class PropertyControlsTestWebPart extends BaseClientSideWebPart<I
allowDuplicate: true,
principalType: [PrincipalType.Users, PrincipalType.SharePoint, PrincipalType.Security],
// principalType: [IPrincipalType.SharePoint],
multiSelect: false,
onPropertyChange: this.onPropertyPaneFieldChanged,
context: this.context,
properties: this.properties,
Expand Down

0 comments on commit 1aecc29

Please sign in to comment.