Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/8
This commit was merged in pull request #8.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
import { SPHttpClient } from '@microsoft/sp-http';
|
||||
|
||||
/**
|
||||
* ОТЛАДОЧНАЯ подмена «текущего пользователя»: портал ведёт себя так, будто им
|
||||
@@ -22,10 +23,12 @@ import { WebPartContext } from '@microsoft/sp-webpart-base';
|
||||
*/
|
||||
|
||||
let impersonatedEmail = '';
|
||||
let impersonatedDisplayName = '';
|
||||
|
||||
/** Вызывается веб-частью на каждый render — свойство могли поменять в панели. */
|
||||
export function setImpersonatedEmail(email: string | undefined): void {
|
||||
export function setImpersonatedIdentity(email: string | undefined, displayName?: string): void {
|
||||
impersonatedEmail = (email || '').trim();
|
||||
impersonatedDisplayName = (displayName || '').trim();
|
||||
}
|
||||
|
||||
/** Заданная подмена ('' — подмены нет). Для предупреждающей полосы в интерфейсе. */
|
||||
@@ -33,7 +36,89 @@ export function getImpersonatedEmail(): string {
|
||||
return impersonatedEmail;
|
||||
}
|
||||
|
||||
/** ФИО подменённого сотрудника, если его удалось найти поиском по имени ('' — для e-mail, введённого напрямую). */
|
||||
export function getImpersonatedDisplayName(): string {
|
||||
return impersonatedDisplayName;
|
||||
}
|
||||
|
||||
/** Email, под которым портал работает: подменённый, если задан, иначе — из токена. */
|
||||
export function effectiveUserEmail(context: WebPartContext): string {
|
||||
return impersonatedEmail || context.pageContext.user.email || '';
|
||||
}
|
||||
|
||||
export interface IResolvedDebugUser {
|
||||
email: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
interface IPeopleSearchHit {
|
||||
displayName: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
/** Сырой ответ ClientPeoplePickerSearchUser — value внутри двойного JSON. */
|
||||
interface IPeoplePickerEntity {
|
||||
DisplayText?: string;
|
||||
Description?: string;
|
||||
EntityData?: { Email?: string };
|
||||
}
|
||||
|
||||
async function searchPeopleByText(context: WebPartContext, queryText: string): Promise<IPeopleSearchHit[]> {
|
||||
const url = `${context.pageContext.web.absoluteUrl}/_api/SP.UI.ApplicationPages.ClientPeoplePickerWebServiceInterface.clientPeoplePickerSearchUser`;
|
||||
const body = JSON.stringify({
|
||||
queryParams: {
|
||||
AllowEmailAddresses: true,
|
||||
AllowMultipleEntities: false,
|
||||
MaximumEntitySuggestions: 5,
|
||||
PrincipalSource: 15, // All
|
||||
PrincipalType: 1, // User
|
||||
QueryString: queryText
|
||||
}
|
||||
});
|
||||
|
||||
const response = await context.spHttpClient.post(url, SPHttpClient.configurations.v1, {
|
||||
headers: {
|
||||
Accept: 'application/json;odata=nometadata',
|
||||
'Content-Type': 'application/json;odata=nometadata'
|
||||
},
|
||||
body
|
||||
});
|
||||
|
||||
if (!response.ok) return [];
|
||||
|
||||
const json: { value?: string } = await response.json();
|
||||
if (!json.value) return [];
|
||||
|
||||
let entries: IPeoplePickerEntity[];
|
||||
try {
|
||||
entries = JSON.parse(json.value);
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
|
||||
return entries
|
||||
.map((e) => ({ displayName: e.DisplayText || '', email: e.EntityData?.Email || e.Description || '' }))
|
||||
.filter((e) => !!e.email);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ищет сотрудника по имени для отладочной подмены (см. property pane —
|
||||
* PropertyPaneDebugUser/DebugUserField). Порядок «Фамилия Имя» или «Имя
|
||||
* Фамилия» не важен: если прямой запрос ничего не находит, пробуем с
|
||||
* переставленными первыми двумя словами.
|
||||
*/
|
||||
export async function resolveDebugUser(context: WebPartContext, nameQuery: string): Promise<IResolvedDebugUser | undefined> {
|
||||
const text = nameQuery.trim();
|
||||
if (!text) return undefined;
|
||||
|
||||
let hits = await searchPeopleByText(context, text);
|
||||
if (hits.length === 0) {
|
||||
const tokens = text.split(/\s+/).filter(Boolean);
|
||||
if (tokens.length >= 2) {
|
||||
const swapped = [tokens[1], tokens[0], ...tokens.slice(2)].join(' ');
|
||||
hits = await searchPeopleByText(context, swapped);
|
||||
}
|
||||
}
|
||||
|
||||
return hits[0];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user