Feature/request type access all requests (#22)
Tests / frontend-test (push) Successful in 1m24s

Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/22
This commit was merged in pull request #22.
This commit is contained in:
2026-09-25 11:48:09 +00:00
parent ebc74dc46d
commit 98be3980cb
15 changed files with 590 additions and 56 deletions
@@ -1140,7 +1140,7 @@ interface ISearchEntry {
* компромиссом — searchOwnRequests и раньше не подмешивал REST-подстраховку
* (в отличие от getOwnRequests, где её явно добавляет getFreshOwnRowsForType).
*/
function toMyRequestFromSearch(entry: ISearchEntry): IMyRequest {
function toMyRequestFromSearch(entry: ISearchEntry, kind: 'own' | 'other' = 'own'): IMyRequest {
const r = entry.raw;
const author = parseAuthorOwsUser(r[MP_AUTHOR]);
return {
@@ -1157,7 +1157,7 @@ function toMyRequestFromSearch(entry: ISearchEntry): IMyRequest {
requestTypeName: entry.type.name,
section: entry.type.section,
formKey: entry.type.pageUrl,
kind: 'own',
kind,
listId: entry.target.listId,
siteUrl: entry.target.siteUrl,
};
@@ -1370,11 +1370,48 @@ export async function searchOwnRequests(
const totalRows = results.TotalRows || 0;
// Поля — прямо из ответа индекса (см. toMyRequestFromSearch), REST-дочитывания
// здесь больше нет. Порядок задаёт релевантность поиска.
const rows = hitsToEntries(results, types).map(toMyRequestFromSearch);
const rows = hitsToEntries(results, types).map((e) => toMyRequestFromSearch(e));
return { rows, totalRows };
}
// «Все заявки» ОДНОГО типа — для пользователей, которым в админке
// approval-route выдан доступ видеть заявки этого типа целиком, а не только
// свои (см. shared/approval/requestTypeAccess.ts). В отличие от
// searchOwnRequests — без фильтра по автору, и только ОДИН тип (раздел уже
// показывает конкретный выбранный тип, а не все связанные разом). Только
// Search, без REST-подстраховки на свежесть — как и у searchOwnRequests.
//
// Весь найденный срез целиком (fetchAllSearchRows), а не постранично через
// Search RowLimit/StartRow: totalRows там был бы сырым счётчиком индекса ДО
// дедупа по (тип, Id) (см. hitsToEntries — TrimDuplicates:false намеренно, и
// индекс может вернуть один и тот же элемент несколькими хитами), и на
// странице оказывалось МЕНЬШЕ строк, чем показывал счётчик над таблицей.
// Тип здесь только один — набор в разумных пределах, дедуп и сортировка идут
// по всему сразу, страница нарезается уже в памяти.
export async function getAllRequestsForType(
context: WebPartContext,
type: IRequestType,
page: number,
query: string
): Promise<IOwnRequestsPage> {
const sp = spForSite(type.siteUrl as string, context);
const clauses = [pathClauseForTypes([type])];
const text = freeTextClause(query);
if (text) clauses.push(text);
const kql = clauses.join(' AND ');
const hits = await traced('Search: все заявки типа', () =>
fetchAllSearchRows(sp, kql, OWN_SELECT_PROPERTIES, 'Все заявки типа', [{ Property: 'Created', Direction: 1 }])
);
// kind: 'other' — заявка не обязательно текущего пользователя, открывается
// только на просмотр (см. IMyRequest.kind, openRequest в RequestPortal.tsx).
const rows = hitsToEntries({ PrimarySearchResults: hits }, [type]).map((e) => toMyRequestFromSearch(e, 'other'));
return { rows: rows.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE), totalRows: rows.length };
}
// Свои заявки с конкретным статусом ЗАЯВКИ (не строки маршрута) — «Доработка»
// и фильтр по статусу на вкладке «Инициированные».
//
@@ -1446,7 +1483,7 @@ async function ownRequestsByStatus(
SortList: [{ Property: 'Created', Direction: 1 }],
})
).then((results) => ({
rows: hitsToEntries(results, types).map(toMyRequestFromSearch),
rows: hitsToEntries(results, types).map((e) => toMyRequestFromSearch(e)),
totalRows: results.TotalRows || 0,
}));
@@ -1672,7 +1709,7 @@ export async function searchOwnAll(
traceSearchHits('Свои заявки', kql, types, results, listAbsUrl);
const entries = hitsToEntries(results, types);
const rows = entries.map(toMyRequestFromSearch);
const rows = entries.map((e) => toMyRequestFromSearch(e));
traceResultRows('Свои заявки', types, entries, rows);
return rows;