@kwiz/common 1.0.107 → 1.0.109

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.github/workflows/npm-publish.yml +24 -24
  2. package/.madgerc +2 -2
  3. package/LICENSE +21 -21
  4. package/fix-folder-imports.js +26 -26
  5. package/lib/cjs/helpers/browser.js +9 -5
  6. package/lib/cjs/helpers/browser.js.map +1 -1
  7. package/lib/cjs/types/libs/msal.types.js +26 -26
  8. package/lib/cjs/types/libs/msal.types.js.map +1 -1
  9. package/lib/cjs/types/sharepoint.utils.types.js +9 -1
  10. package/lib/cjs/types/sharepoint.utils.types.js.map +1 -1
  11. package/lib/cjs/utils/sharepoint.rest/file.folder.js +4 -4
  12. package/lib/cjs/utils/sharepoint.rest/file.folder.js.map +1 -1
  13. package/lib/cjs/utils/sharepoint.rest/list.js +60 -1
  14. package/lib/cjs/utils/sharepoint.rest/list.js.map +1 -1
  15. package/lib/cjs/utils/sharepoint.rest/user.js +11 -11
  16. package/lib/esm/helpers/browser.js +9 -5
  17. package/lib/esm/helpers/browser.js.map +1 -1
  18. package/lib/esm/types/libs/msal.types.js +26 -26
  19. package/lib/esm/types/libs/msal.types.js.map +1 -1
  20. package/lib/esm/types/sharepoint.utils.types.js +8 -0
  21. package/lib/esm/types/sharepoint.utils.types.js.map +1 -1
  22. package/lib/esm/utils/sharepoint.rest/file.folder.js +4 -4
  23. package/lib/esm/utils/sharepoint.rest/file.folder.js.map +1 -1
  24. package/lib/esm/utils/sharepoint.rest/list.js +57 -0
  25. package/lib/esm/utils/sharepoint.rest/list.js.map +1 -1
  26. package/lib/esm/utils/sharepoint.rest/user.js +11 -11
  27. package/lib/types/types/libs/msal.types.d.ts +8 -3
  28. package/lib/types/types/sharepoint.utils.types.d.ts +17 -0
  29. package/lib/types/utils/sharepoint.rest/list.d.ts +7 -1
  30. package/package.json +81 -81
  31. package/readme.md +17 -17
  32. package/src/_dependencies.ts +12 -12
  33. package/src/config.ts +17 -17
  34. package/src/helpers/Guid.ts +181 -181
  35. package/src/helpers/base64.ts +173 -173
  36. package/src/helpers/browser.test.js +13 -13
  37. package/src/helpers/browser.ts +1448 -1448
  38. package/src/helpers/browserinfo.ts +292 -292
  39. package/src/helpers/collections.base.test.js +25 -25
  40. package/src/helpers/collections.base.ts +437 -437
  41. package/src/helpers/collections.ts +107 -107
  42. package/src/helpers/color.ts +54 -54
  43. package/src/helpers/cookies.ts +59 -59
  44. package/src/helpers/date.test.js +119 -119
  45. package/src/helpers/date.ts +188 -188
  46. package/src/helpers/debug.ts +186 -186
  47. package/src/helpers/diagrams.ts +43 -43
  48. package/src/helpers/emails.ts +6 -6
  49. package/src/helpers/eval.ts +5 -5
  50. package/src/helpers/file.test.js +50 -50
  51. package/src/helpers/file.ts +63 -63
  52. package/src/helpers/flatted.ts +149 -149
  53. package/src/helpers/functions.ts +16 -16
  54. package/src/helpers/graph/calendar.types.ts +10 -10
  55. package/src/helpers/http.ts +69 -69
  56. package/src/helpers/images.ts +22 -22
  57. package/src/helpers/json.ts +44 -44
  58. package/src/helpers/md5.ts +189 -189
  59. package/src/helpers/objects.test.js +33 -33
  60. package/src/helpers/objects.ts +274 -274
  61. package/src/helpers/promises.test.js +37 -37
  62. package/src/helpers/promises.ts +165 -165
  63. package/src/helpers/random.ts +27 -27
  64. package/src/helpers/scheduler/scheduler.test.js +103 -103
  65. package/src/helpers/scheduler/scheduler.ts +131 -131
  66. package/src/helpers/sharepoint.ts +785 -785
  67. package/src/helpers/strings.test.js +122 -122
  68. package/src/helpers/strings.ts +337 -337
  69. package/src/helpers/typecheckers.test.js +34 -34
  70. package/src/helpers/typecheckers.ts +266 -266
  71. package/src/helpers/url.test.js +43 -43
  72. package/src/helpers/url.ts +207 -207
  73. package/src/helpers/urlhelper.ts +111 -111
  74. package/src/index.ts +6 -6
  75. package/src/types/auth.ts +54 -54
  76. package/src/types/common.types.ts +15 -15
  77. package/src/types/flatted.types.ts +59 -59
  78. package/src/types/globals.types.ts +6 -6
  79. package/src/types/graph/calendar.types.ts +80 -80
  80. package/src/types/knownscript.types.ts +18 -18
  81. package/src/types/libs/datajs.types.ts +28 -28
  82. package/src/types/libs/ics.types.ts +30 -30
  83. package/src/types/libs/msal.types.ts +57 -49
  84. package/src/types/locales.ts +125 -125
  85. package/src/types/localstoragecache.types.ts +8 -8
  86. package/src/types/location.types.ts +27 -27
  87. package/src/types/moment.ts +11 -11
  88. package/src/types/regex.types.ts +16 -16
  89. package/src/types/rest.types.ts +95 -95
  90. package/src/types/sharepoint.types.ts +1466 -1466
  91. package/src/types/sharepoint.utils.types.ts +306 -287
  92. package/src/utils/auth/common.ts +74 -74
  93. package/src/utils/auth/discovery.test.js +12 -12
  94. package/src/utils/auth/discovery.ts +132 -132
  95. package/src/utils/base64.ts +27 -27
  96. package/src/utils/consolelogger.ts +320 -320
  97. package/src/utils/date.ts +172 -172
  98. package/src/utils/emails.ts +24 -24
  99. package/src/utils/knownscript.ts +286 -286
  100. package/src/utils/localstoragecache.ts +446 -446
  101. package/src/utils/rest.ts +501 -501
  102. package/src/utils/script.ts +170 -170
  103. package/src/utils/sharepoint.rest/common.ts +154 -154
  104. package/src/utils/sharepoint.rest/date.ts +62 -62
  105. package/src/utils/sharepoint.rest/file.folder.ts +598 -598
  106. package/src/utils/sharepoint.rest/item.ts +547 -547
  107. package/src/utils/sharepoint.rest/list.ts +1548 -1482
  108. package/src/utils/sharepoint.rest/listutils/GetListItemsByCaml.ts +774 -774
  109. package/src/utils/sharepoint.rest/listutils/GetListItemsById.ts +275 -275
  110. package/src/utils/sharepoint.rest/listutils/common.ts +206 -206
  111. package/src/utils/sharepoint.rest/location.ts +141 -141
  112. package/src/utils/sharepoint.rest/navigation-links.ts +86 -86
  113. package/src/utils/sharepoint.rest/user-search.ts +252 -252
  114. package/src/utils/sharepoint.rest/user.ts +491 -491
  115. package/src/utils/sharepoint.rest/web.ts +1384 -1384
  116. package/src/utils/sod.ts +194 -194
@@ -1,253 +1,253 @@
1
- import { firstIndexOf } from "../../helpers/collections.base";
2
- import { contentTypes, jsonTypes } from "../../types/rest.types";
3
- import { PrincipalType } from "../../types/sharepoint.types";
4
- import { IUserInfo } from "../../types/sharepoint.utils.types";
5
- import { GetJson } from "../rest";
6
- import { EnsureUser } from "./user";
7
-
8
- export interface iPeoplePickerUserItem {
9
- /** LoginName or Id of the principal in the site. */
10
- id: string;
11
- /** LoginName of the principal. */
12
- loginName: string;
13
- imageUrl: string;
14
- imageInitials: string;
15
- text: string; // name
16
- secondaryText: string; // role
17
- tertiaryText: string; // status
18
- optionalText: string; // anything
19
- }
20
- /**
21
- * Service implementation to search people in SharePoint
22
- */
23
- export class SPPeopleSearchService {
24
- private cachedLocalUsers: { [siteUrl: string]: IUserInfo[] };
25
-
26
- /**
27
- * Service constructor
28
- */
29
- constructor(private context: { siteUrl }) {
30
- this.cachedLocalUsers = {};
31
- this.cachedLocalUsers[this.context.siteUrl] = [];
32
- }
33
-
34
- /**
35
- * Generate the user photo link using SharePoint user photo endpoint.
36
- *
37
- * @param value
38
- */
39
- public generateUserPhotoLink(value: string, size: "S" | "M" = "M"): string {
40
- return `${this.context.siteUrl}/_layouts/15/userphoto.aspx?accountname=${encodeURIComponent(value)}&size=M`;
41
- }
42
-
43
- /**
44
- * Generate sum of principal types
45
- *
46
- * PrincipalType controls the type of entities that are returned in the results.
47
- * Choices are All - 15, Distribution List - 2 , Security Groups - 4, SharePoint Groups - 8, User - 1.
48
- * These values can be combined (example: 13 is security + SP groups + users)
49
- *
50
- * @param principalTypes
51
- */
52
- public getSumOfPrincipalTypes(principalTypes: PrincipalType[]) {
53
- return !!principalTypes && principalTypes.length > 0 ? principalTypes.reduce((a, b) => a + b, 0) : 1;
54
- }
55
-
56
- /**
57
- * Retrieve the specified group
58
- *
59
- * @param groupName
60
- * @param siteUrl
61
- */
62
- public async getGroupId(groupName: string, siteUrl: string = null): Promise<number | null> {
63
- // if (Environment.type === EnvironmentType.Local) {
64
- // return 1;
65
- // } else {
66
- const groups = await this.searchTenant(siteUrl, groupName, 1, [PrincipalType.SharePointGroup], false, 0);
67
- return (groups && groups.length > 0) ? parseInt(groups[0].id) : null;
68
- //}
69
- }
70
-
71
- /**
72
- * Search person by its email or login name
73
- */
74
- public async searchPersonByEmailOrLogin(email: string, principalTypes: PrincipalType[], siteUrl: string = null, groupId: number = null, ensureUser: boolean = false): Promise<iPeoplePickerUserItem> {
75
- // if (Environment.type === EnvironmentType.Local) {
76
- // // If the running environment is local, load the data from the mock
77
- // const mockUsers = await this.searchPeopleFromMock(email);
78
- // return (mockUsers && mockUsers.length > 0) ? mockUsers[0] : null;
79
- // } else {
80
- const userResults = await this.searchTenant(siteUrl, email, 1, principalTypes, ensureUser, groupId);
81
- return (userResults && userResults.length > 0) ? userResults[0] : null;
82
- //}
83
- }
84
-
85
- /**
86
- * Search All Users from the SharePoint People database
87
- */
88
- public async searchPeople(query: string, maximumSuggestions: number, principalTypes: PrincipalType[], siteUrl: string = null, groupId: number = null, ensureUser: boolean = false): Promise<iPeoplePickerUserItem[]> {
89
- // if (Environment.type === EnvironmentType.Local) {
90
- // // If the running environment is local, load the data from the mock
91
- // return this.searchPeopleFromMock(query);
92
- // } else {
93
- return await this.searchTenant(siteUrl, query, maximumSuggestions, principalTypes, ensureUser, groupId);
94
- //}
95
- }
96
-
97
- /**
98
- * Tenant search
99
- */
100
- private async searchTenant(siteUrl: string, query: string, maximumSuggestions: number, principalTypes: PrincipalType[], ensureUser: boolean, groupId: number): Promise<iPeoplePickerUserItem[]> {
101
- try {
102
- // If the running env is SharePoint, loads from the peoplepicker web service
103
- const userRequestUrl: string = `${siteUrl || this.context.siteUrl}/_api/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser`;
104
- const searchBody = {
105
- queryParams: {
106
- AllowEmailAddresses: true,
107
- AllowMultipleEntities: false,
108
- AllUrlZones: false,
109
- MaximumEntitySuggestions: maximumSuggestions,
110
- PrincipalSource: 15,
111
- PrincipalType: this.getSumOfPrincipalTypes(principalTypes),
112
- QueryString: query
113
- }
114
- };
115
-
116
- // Search on the local site when "0"
117
- if (siteUrl) {
118
- searchBody.queryParams["SharePointGroupID"] = 0;
119
- }
120
-
121
- // Check if users need to be searched in a specific group
122
- if (groupId) {
123
- searchBody.queryParams["SharePointGroupID"] = groupId;
124
- }
125
-
126
- // Do the call against the People REST API endpoint
127
- const userDataResp = await GetJson<{ value: string; }>(
128
- userRequestUrl,
129
- JSON.stringify(searchBody),
130
- {
131
- headers: {
132
- Accept: jsonTypes.standard,
133
- "content-type": contentTypes.json
134
- }
135
- })
136
-
137
- if (userDataResp && userDataResp.value && userDataResp.value.length > 0) {
138
- let values: any = userDataResp.value;
139
-
140
- if (typeof userDataResp.value === "string") {
141
- values = JSON.parse(userDataResp.value);
142
- }
143
-
144
- // Filter out "UNVALIDATED_EMAIL_ADDRESS"
145
- values = values.filter(v => !(v.EntityData && v.EntityData.PrincipalType && v.EntityData.PrincipalType === "UNVALIDATED_EMAIL_ADDRESS"));
146
-
147
- // Check if local user IDs need to be retrieved
148
- if (ensureUser) {
149
- for (const value of values) {
150
- // Only ensure the user if it is not a SharePoint group
151
- if (!value.EntityData || (value.EntityData && typeof value.EntityData.SPGroupID === "undefined")) {
152
- const id = await this.ensureUser(value.Key);
153
- value.LoginName = value.Key;
154
- value.Key = id;
155
- }
156
- }
157
- }
158
-
159
- // Filter out NULL keys
160
- values = values.filter(v => v.Key !== null);
161
- const userResults = values.map(element => {
162
- switch (element.EntityType) {
163
- case 'User':
164
- return {
165
- id: element.Key,
166
- loginName: element.LoginName ? element.LoginName : element.Key,
167
- imageUrl: this.generateUserPhotoLink(element.Description || ""),
168
- imageInitials: this.getFullNameInitials(element.DisplayText),
169
- text: element.DisplayText, // name
170
- secondaryText: element.EntityData.Email || element.Description, // email
171
- tertiaryText: "", // status
172
- optionalText: "" // anything
173
- } as iPeoplePickerUserItem;
174
- case 'SecGroup':
175
- return {
176
- id: element.Key,
177
- loginName: element.LoginName ? element.LoginName : element.Key,
178
- imageInitials: this.getFullNameInitials(element.DisplayText),
179
- text: element.DisplayText,
180
- secondaryText: element.ProviderName
181
- } as iPeoplePickerUserItem;
182
- case 'FormsRole':
183
- return {
184
- id: element.Key,
185
- loginName: element.LoginName ? element.LoginName : element.Key,
186
- imageInitials: this.getFullNameInitials(element.DisplayText),
187
- text: element.DisplayText,
188
- secondaryText: element.ProviderName
189
- } as iPeoplePickerUserItem;
190
- default:
191
- return {
192
- id: element.EntityData.SPGroupID,
193
- loginName: element.EntityData.AccountName,
194
- imageInitials: this.getFullNameInitials(element.DisplayText),
195
- text: element.DisplayText,
196
- secondaryText: element.EntityData.AccountName
197
- } as iPeoplePickerUserItem;
198
- }
199
- });
200
-
201
- return userResults;
202
- }
203
-
204
-
205
- // Nothing to return
206
- return [];
207
- } catch (e) {
208
- console.error("PeopleSearchService::searchTenant: error occured while fetching the users.");
209
- return [];
210
- }
211
- }
212
-
213
- /**
214
- * Retrieves the local user ID
215
- *
216
- * @param userId
217
- */
218
- private async ensureUser(userId: string): Promise<number> {
219
- const siteUrl = this.context.siteUrl;
220
- if (this.cachedLocalUsers && this.cachedLocalUsers[siteUrl]) {
221
- const users = this.cachedLocalUsers[siteUrl];
222
- const userIdx = firstIndexOf(users, u => u.LoginName === userId);
223
- if (userIdx !== -1) {
224
- return users[userIdx].Id;
225
- }
226
- }
227
-
228
- const user = await EnsureUser(siteUrl, userId)
229
- if (user && user.Id) {
230
- this.cachedLocalUsers[siteUrl].push(user);
231
- return user.Id;
232
- }
233
- return null;
234
- }
235
-
236
- /**
237
- * Generates Initials from a full name
238
- */
239
- private getFullNameInitials(fullName: string): string {
240
- if (fullName === null) {
241
- return fullName;
242
- }
243
-
244
- const words: string[] = fullName.split(' ');
245
- if (words.length === 0) {
246
- return '';
247
- } else if (words.length === 1) {
248
- return words[0].charAt(0);
249
- } else {
250
- return (words[0].charAt(0) + words[1].charAt(0));
251
- }
252
- }
1
+ import { firstIndexOf } from "../../helpers/collections.base";
2
+ import { contentTypes, jsonTypes } from "../../types/rest.types";
3
+ import { PrincipalType } from "../../types/sharepoint.types";
4
+ import { IUserInfo } from "../../types/sharepoint.utils.types";
5
+ import { GetJson } from "../rest";
6
+ import { EnsureUser } from "./user";
7
+
8
+ export interface iPeoplePickerUserItem {
9
+ /** LoginName or Id of the principal in the site. */
10
+ id: string;
11
+ /** LoginName of the principal. */
12
+ loginName: string;
13
+ imageUrl: string;
14
+ imageInitials: string;
15
+ text: string; // name
16
+ secondaryText: string; // role
17
+ tertiaryText: string; // status
18
+ optionalText: string; // anything
19
+ }
20
+ /**
21
+ * Service implementation to search people in SharePoint
22
+ */
23
+ export class SPPeopleSearchService {
24
+ private cachedLocalUsers: { [siteUrl: string]: IUserInfo[] };
25
+
26
+ /**
27
+ * Service constructor
28
+ */
29
+ constructor(private context: { siteUrl }) {
30
+ this.cachedLocalUsers = {};
31
+ this.cachedLocalUsers[this.context.siteUrl] = [];
32
+ }
33
+
34
+ /**
35
+ * Generate the user photo link using SharePoint user photo endpoint.
36
+ *
37
+ * @param value
38
+ */
39
+ public generateUserPhotoLink(value: string, size: "S" | "M" = "M"): string {
40
+ return `${this.context.siteUrl}/_layouts/15/userphoto.aspx?accountname=${encodeURIComponent(value)}&size=M`;
41
+ }
42
+
43
+ /**
44
+ * Generate sum of principal types
45
+ *
46
+ * PrincipalType controls the type of entities that are returned in the results.
47
+ * Choices are All - 15, Distribution List - 2 , Security Groups - 4, SharePoint Groups - 8, User - 1.
48
+ * These values can be combined (example: 13 is security + SP groups + users)
49
+ *
50
+ * @param principalTypes
51
+ */
52
+ public getSumOfPrincipalTypes(principalTypes: PrincipalType[]) {
53
+ return !!principalTypes && principalTypes.length > 0 ? principalTypes.reduce((a, b) => a + b, 0) : 1;
54
+ }
55
+
56
+ /**
57
+ * Retrieve the specified group
58
+ *
59
+ * @param groupName
60
+ * @param siteUrl
61
+ */
62
+ public async getGroupId(groupName: string, siteUrl: string = null): Promise<number | null> {
63
+ // if (Environment.type === EnvironmentType.Local) {
64
+ // return 1;
65
+ // } else {
66
+ const groups = await this.searchTenant(siteUrl, groupName, 1, [PrincipalType.SharePointGroup], false, 0);
67
+ return (groups && groups.length > 0) ? parseInt(groups[0].id) : null;
68
+ //}
69
+ }
70
+
71
+ /**
72
+ * Search person by its email or login name
73
+ */
74
+ public async searchPersonByEmailOrLogin(email: string, principalTypes: PrincipalType[], siteUrl: string = null, groupId: number = null, ensureUser: boolean = false): Promise<iPeoplePickerUserItem> {
75
+ // if (Environment.type === EnvironmentType.Local) {
76
+ // // If the running environment is local, load the data from the mock
77
+ // const mockUsers = await this.searchPeopleFromMock(email);
78
+ // return (mockUsers && mockUsers.length > 0) ? mockUsers[0] : null;
79
+ // } else {
80
+ const userResults = await this.searchTenant(siteUrl, email, 1, principalTypes, ensureUser, groupId);
81
+ return (userResults && userResults.length > 0) ? userResults[0] : null;
82
+ //}
83
+ }
84
+
85
+ /**
86
+ * Search All Users from the SharePoint People database
87
+ */
88
+ public async searchPeople(query: string, maximumSuggestions: number, principalTypes: PrincipalType[], siteUrl: string = null, groupId: number = null, ensureUser: boolean = false): Promise<iPeoplePickerUserItem[]> {
89
+ // if (Environment.type === EnvironmentType.Local) {
90
+ // // If the running environment is local, load the data from the mock
91
+ // return this.searchPeopleFromMock(query);
92
+ // } else {
93
+ return await this.searchTenant(siteUrl, query, maximumSuggestions, principalTypes, ensureUser, groupId);
94
+ //}
95
+ }
96
+
97
+ /**
98
+ * Tenant search
99
+ */
100
+ private async searchTenant(siteUrl: string, query: string, maximumSuggestions: number, principalTypes: PrincipalType[], ensureUser: boolean, groupId: number): Promise<iPeoplePickerUserItem[]> {
101
+ try {
102
+ // If the running env is SharePoint, loads from the peoplepicker web service
103
+ const userRequestUrl: string = `${siteUrl || this.context.siteUrl}/_api/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser`;
104
+ const searchBody = {
105
+ queryParams: {
106
+ AllowEmailAddresses: true,
107
+ AllowMultipleEntities: false,
108
+ AllUrlZones: false,
109
+ MaximumEntitySuggestions: maximumSuggestions,
110
+ PrincipalSource: 15,
111
+ PrincipalType: this.getSumOfPrincipalTypes(principalTypes),
112
+ QueryString: query
113
+ }
114
+ };
115
+
116
+ // Search on the local site when "0"
117
+ if (siteUrl) {
118
+ searchBody.queryParams["SharePointGroupID"] = 0;
119
+ }
120
+
121
+ // Check if users need to be searched in a specific group
122
+ if (groupId) {
123
+ searchBody.queryParams["SharePointGroupID"] = groupId;
124
+ }
125
+
126
+ // Do the call against the People REST API endpoint
127
+ const userDataResp = await GetJson<{ value: string; }>(
128
+ userRequestUrl,
129
+ JSON.stringify(searchBody),
130
+ {
131
+ headers: {
132
+ Accept: jsonTypes.standard,
133
+ "content-type": contentTypes.json
134
+ }
135
+ })
136
+
137
+ if (userDataResp && userDataResp.value && userDataResp.value.length > 0) {
138
+ let values: any = userDataResp.value;
139
+
140
+ if (typeof userDataResp.value === "string") {
141
+ values = JSON.parse(userDataResp.value);
142
+ }
143
+
144
+ // Filter out "UNVALIDATED_EMAIL_ADDRESS"
145
+ values = values.filter(v => !(v.EntityData && v.EntityData.PrincipalType && v.EntityData.PrincipalType === "UNVALIDATED_EMAIL_ADDRESS"));
146
+
147
+ // Check if local user IDs need to be retrieved
148
+ if (ensureUser) {
149
+ for (const value of values) {
150
+ // Only ensure the user if it is not a SharePoint group
151
+ if (!value.EntityData || (value.EntityData && typeof value.EntityData.SPGroupID === "undefined")) {
152
+ const id = await this.ensureUser(value.Key);
153
+ value.LoginName = value.Key;
154
+ value.Key = id;
155
+ }
156
+ }
157
+ }
158
+
159
+ // Filter out NULL keys
160
+ values = values.filter(v => v.Key !== null);
161
+ const userResults = values.map(element => {
162
+ switch (element.EntityType) {
163
+ case 'User':
164
+ return {
165
+ id: element.Key,
166
+ loginName: element.LoginName ? element.LoginName : element.Key,
167
+ imageUrl: this.generateUserPhotoLink(element.Description || ""),
168
+ imageInitials: this.getFullNameInitials(element.DisplayText),
169
+ text: element.DisplayText, // name
170
+ secondaryText: element.EntityData.Email || element.Description, // email
171
+ tertiaryText: "", // status
172
+ optionalText: "" // anything
173
+ } as iPeoplePickerUserItem;
174
+ case 'SecGroup':
175
+ return {
176
+ id: element.Key,
177
+ loginName: element.LoginName ? element.LoginName : element.Key,
178
+ imageInitials: this.getFullNameInitials(element.DisplayText),
179
+ text: element.DisplayText,
180
+ secondaryText: element.ProviderName
181
+ } as iPeoplePickerUserItem;
182
+ case 'FormsRole':
183
+ return {
184
+ id: element.Key,
185
+ loginName: element.LoginName ? element.LoginName : element.Key,
186
+ imageInitials: this.getFullNameInitials(element.DisplayText),
187
+ text: element.DisplayText,
188
+ secondaryText: element.ProviderName
189
+ } as iPeoplePickerUserItem;
190
+ default:
191
+ return {
192
+ id: element.EntityData.SPGroupID,
193
+ loginName: element.EntityData.AccountName,
194
+ imageInitials: this.getFullNameInitials(element.DisplayText),
195
+ text: element.DisplayText,
196
+ secondaryText: element.EntityData.AccountName
197
+ } as iPeoplePickerUserItem;
198
+ }
199
+ });
200
+
201
+ return userResults;
202
+ }
203
+
204
+
205
+ // Nothing to return
206
+ return [];
207
+ } catch (e) {
208
+ console.error("PeopleSearchService::searchTenant: error occured while fetching the users.");
209
+ return [];
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Retrieves the local user ID
215
+ *
216
+ * @param userId
217
+ */
218
+ private async ensureUser(userId: string): Promise<number> {
219
+ const siteUrl = this.context.siteUrl;
220
+ if (this.cachedLocalUsers && this.cachedLocalUsers[siteUrl]) {
221
+ const users = this.cachedLocalUsers[siteUrl];
222
+ const userIdx = firstIndexOf(users, u => u.LoginName === userId);
223
+ if (userIdx !== -1) {
224
+ return users[userIdx].Id;
225
+ }
226
+ }
227
+
228
+ const user = await EnsureUser(siteUrl, userId)
229
+ if (user && user.Id) {
230
+ this.cachedLocalUsers[siteUrl].push(user);
231
+ return user.Id;
232
+ }
233
+ return null;
234
+ }
235
+
236
+ /**
237
+ * Generates Initials from a full name
238
+ */
239
+ private getFullNameInitials(fullName: string): string {
240
+ if (fullName === null) {
241
+ return fullName;
242
+ }
243
+
244
+ const words: string[] = fullName.split(' ');
245
+ if (words.length === 0) {
246
+ return '';
247
+ } else if (words.length === 1) {
248
+ return words[0].charAt(0);
249
+ } else {
250
+ return (words[0].charAt(0) + words[1].charAt(0));
251
+ }
252
+ }
253
253
  }