fix: поиск сотрудника не находил, если после имени или фамилии стоит пробел
PeoplePicker шлёт введённый текст в SharePoint как есть. Теперь в запросе поиска пробелы по краям обрезаются, а двойные внутри схлопываются. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
import { trimPickerQuery } from './pickerContext';
|
||||||
|
|
||||||
|
const body = (q: unknown): string => JSON.stringify({ queryParams: { QueryString: q, PrincipalType: 1 } });
|
||||||
|
const query = (b: unknown): unknown => (JSON.parse(b as string) as { queryParams: { QueryString: unknown } }).queryParams.QueryString;
|
||||||
|
|
||||||
|
describe('trimPickerQuery', () => {
|
||||||
|
it('убирает пробел в конце и в начале', () => {
|
||||||
|
expect(query(trimPickerQuery(body('Иван ')))).toBe('Иван');
|
||||||
|
expect(query(trimPickerQuery(body(' Иван Петров ')))).toBe('Иван Петров');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('схлопывает двойные пробелы внутри', () => {
|
||||||
|
expect(query(trimPickerQuery(body('Иван Петров')))).toBe('Иван Петров');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('не трогает остальные поля запроса', () => {
|
||||||
|
const parsed = JSON.parse(trimPickerQuery(body('a ')) as string) as { queryParams: { PrincipalType: number } };
|
||||||
|
expect(parsed.queryParams.PrincipalType).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('чужие тела возвращает как есть', () => {
|
||||||
|
expect(trimPickerQuery('не json QueryString')).toBe('не json QueryString');
|
||||||
|
expect(trimPickerQuery(undefined)).toBeUndefined();
|
||||||
|
const other = JSON.stringify({ a: 1 });
|
||||||
|
expect(trimPickerQuery(other)).toBe(other);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -18,6 +18,43 @@ export function pickedLogin(user: IPickedUser): string {
|
|||||||
return user.secondaryText || user.loginName || user.id || '';
|
return user.secondaryText || user.loginName || user.id || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Убирает пробелы по краям (и схлопывает внутренние) у QueryString в теле запроса
|
||||||
|
* поиска сотрудника. PeoplePicker из @pnp/spfx-controls-react шлёт введённый
|
||||||
|
* текст как есть, а SharePoint с «Иван » (пробел в конце, обычное дело при вводе
|
||||||
|
* «имя фамилия») ничего не находит. Тело не JSON или без QueryString — возвращается как было.
|
||||||
|
*/
|
||||||
|
export function trimPickerQuery(body: unknown): unknown {
|
||||||
|
if (typeof body !== 'string' || body.indexOf('QueryString') < 0) return body;
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(body) as { queryParams?: { QueryString?: unknown } };
|
||||||
|
const query = parsed.queryParams?.QueryString;
|
||||||
|
if (typeof query !== 'string') return body;
|
||||||
|
parsed.queryParams!.QueryString = query.trim().replace(/\s+/g, ' ');
|
||||||
|
return JSON.stringify(parsed);
|
||||||
|
} catch {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spHttpClient с подчисткой запроса поиска (см. trimPickerQuery): прокси, чтобы
|
||||||
|
* остальные методы клиента работали как прежде, подменяется только post.
|
||||||
|
*/
|
||||||
|
function withTrimmedSearch(client: WebPartContext['spHttpClient']): WebPartContext['spHttpClient'] {
|
||||||
|
return new Proxy(client, {
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
if (prop !== 'post') return Reflect.get(target, prop, receiver);
|
||||||
|
return (url: string, config: unknown, options?: { body?: unknown }) =>
|
||||||
|
(target.post as (u: string, c: unknown, o?: unknown) => unknown)(
|
||||||
|
url,
|
||||||
|
config,
|
||||||
|
options ? { ...options, body: trimPickerQuery(options.body) } : options
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Контекст для PeoplePicker из WebPartContext.
|
* Контекст для PeoplePicker из WebPartContext.
|
||||||
* as unknown: @pnp/spfx-controls-react тянет свою копию sp-http-msgraph,
|
* as unknown: @pnp/spfx-controls-react тянет свою копию sp-http-msgraph,
|
||||||
@@ -27,6 +64,6 @@ export function buildPickerContext(context: WebPartContext): IPeoplePickerContex
|
|||||||
return {
|
return {
|
||||||
absoluteUrl: context.pageContext.web.absoluteUrl,
|
absoluteUrl: context.pageContext.web.absoluteUrl,
|
||||||
msGraphClientFactory: context.msGraphClientFactory,
|
msGraphClientFactory: context.msGraphClientFactory,
|
||||||
spHttpClient: context.spHttpClient
|
spHttpClient: withTrimmedSearch(context.spHttpClient)
|
||||||
} as unknown as IPeoplePickerContext;
|
} as unknown as IPeoplePickerContext;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user