Skip to content

Commit 020d17d

Browse files
authored
Merge pull request #1164 from SherpasGroup/people-picker-multiple-group-ids
Enable multiple groupId's
2 parents be6e1c0 + 0b5840b commit 020d17d

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

docs/documentation/docs/controls/PeoplePicker.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ The People picker control can be configured with the following properties:
6161
| context | BaseComponentContext | yes | Context of the current web part. | |
6262
| titleText | string | no | Text to be displayed on the control | |
6363
| groupName | string | no | Group from which users are fetched. Leave it blank if need to filter all users. When both groupName and groupId specified groupName takes precedence. | _none_ |
64-
| groupId | number \| string | no | Group from which users are fetched. Leave it blank if need to filter all users. When both groupId and groupName specified groupName takes precedence. If string is specified, Microsoft 365 Group is used | _none_ |
64+
| groupId | number \| string \| (string\|number)[] | no | Group from which users are fetched. Leave it blank if need to filter all users. When both groupId and groupName specified groupName takes precedence. If string is specified, Microsoft 365 Group is used. If array is used, fetch results from multiple groups | _none_ |
6565
| personSelectionLimit | number | no | Defines the limit of people that can be selected in the control | 1 |
6666
| required | boolean | no | Set if the control is required or not | false |
6767
| disabled | boolean | no | Set if the control is disabled or not | false |

src/controls/peoplepicker/IPeoplePicker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export interface IPeoplePickerProps {
3232
/**
3333
* Id of SharePoint Group (Number) or Office365 Group (String)
3434
*/
35-
groupId?: number | string;
35+
groupId?: number | string | (string|number)[];
3636
/**
3737
* Maximum number of suggestions to show in the full suggestion list. (default: 5)
3838
*/

src/controls/peoplepicker/PeoplePickerComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import uniqBy from 'lodash/uniqBy';
1919
export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePickerState> {
2020
private peopleSearchService: SPPeopleSearchService;
2121
private suggestionsLimit: number;
22-
private groupId: number | string;
22+
private groupId: number | string | (string | number)[];
2323

2424
constructor(props: IPeoplePickerProps) {
2525
super(props);

src/services/PeopleSearchService.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,26 +69,54 @@ export default class SPPeopleSearchService {
6969
/**
7070
* Search person by its email or login name
7171
*/
72-
public async searchPersonByEmailOrLogin(email: string, principalTypes: PrincipalType[], siteUrl: string = null, groupId: number | string = null, ensureUser: boolean = false): Promise<IPeoplePickerUserItem> {
72+
public async searchPersonByEmailOrLogin(email: string, principalTypes: PrincipalType[], siteUrl: string = null, groupId: number | string | (string|number)[] = null, ensureUser: boolean = false): Promise<IPeoplePickerUserItem> {
7373
if (Environment.type === EnvironmentType.Local) {
7474
// If the running environment is local, load the data from the mock
7575
const mockUsers = await this.searchPeopleFromMock(email);
7676
return (mockUsers && mockUsers.length > 0) ? mockUsers[0] : null;
7777
} else {
78-
const userResults = await this.searchTenant(siteUrl, email, 1, principalTypes, ensureUser, groupId);
79-
return (userResults && userResults.length > 0) ? userResults[0] : null;
78+
// If groupId is array, load data from all groups
79+
if (Array.isArray(groupId)) {
80+
let userResults: IPeoplePickerUserItem[] = [];
81+
for (const id of groupId) {
82+
let tmpResults = await this.searchTenant(siteUrl, email, 1, principalTypes, ensureUser, id);
83+
userResults = userResults.concat(tmpResults);
84+
}
85+
86+
// Remove duplicate results in case user is present in multiple groups
87+
let logins = userResults.map(u => u.loginName);
88+
let filteredUserResults = userResults.filter(({loginName}, index) => !logins.includes(loginName, index + 1));
89+
return (filteredUserResults && filteredUserResults.length > 0) ? filteredUserResults[0] : null;
90+
} else {
91+
const userResults = await this.searchTenant(siteUrl, email, 1, principalTypes, ensureUser, groupId);
92+
return (userResults && userResults.length > 0) ? userResults[0] : null;
93+
}
8094
}
8195
}
8296

8397
/**
8498
* Search All Users from the SharePoint People database
8599
*/
86-
public async searchPeople(query: string, maximumSuggestions: number, principalTypes: PrincipalType[], siteUrl: string = null, groupId: number | string = null, ensureUser: boolean = false): Promise<IPeoplePickerUserItem[]> {
100+
public async searchPeople(query: string, maximumSuggestions: number, principalTypes: PrincipalType[], siteUrl: string = null, groupId: number | string | (string|number)[] = null, ensureUser: boolean = false): Promise<IPeoplePickerUserItem[]> {
87101
if (Environment.type === EnvironmentType.Local) {
88102
// If the running environment is local, load the data from the mock
89103
return this.searchPeopleFromMock(query);
90104
} else {
91-
return await this.searchTenant(siteUrl, query, maximumSuggestions, principalTypes, ensureUser, groupId);
105+
// If groupId is array, load data from all groups
106+
if (Array.isArray(groupId)) {
107+
let userResults: IPeoplePickerUserItem[] = [];
108+
for (const id of groupId) {
109+
let tmpResults = await this.searchTenant(siteUrl, query, maximumSuggestions, principalTypes, ensureUser, id);
110+
userResults = userResults.concat(tmpResults);
111+
}
112+
113+
// Remove duplicate results in case user is present in multiple groups
114+
let logins = userResults.map(u => u.loginName);
115+
let filteredUserResults = userResults.filter(({loginName}, index) => !logins.includes(loginName, index + 1));
116+
return filteredUserResults;
117+
} else {
118+
return await this.searchTenant(siteUrl, query, maximumSuggestions, principalTypes, ensureUser, groupId);
119+
}
92120
}
93121
}
94122

0 commit comments

Comments
 (0)