добавлен комментарий
This commit is contained in:
@@ -785,6 +785,93 @@ export async function getOwnRequestsByStatus(
|
||||
};
|
||||
}
|
||||
|
||||
// Список согласования по типу заявки: Title списка данных → Title списка
|
||||
// согласования по конвенции имён (та же логика, что в indexApprovalsForType).
|
||||
// undefined — список заведён не по конвенции, маршрута для него не найти.
|
||||
async function approvalListFor(
|
||||
context: WebPartContext,
|
||||
type: IRequestType
|
||||
): Promise<IList | undefined> {
|
||||
const sp = spForSite(type.siteUrl as string, context);
|
||||
const info = (await sp.web.getList(type.listId as string).select('Title')()) as { Title?: string };
|
||||
const dataTitle = info.Title || '';
|
||||
if (!DATA_LIST_SUFFIX.test(dataTitle)) return undefined;
|
||||
return sp.web.lists.getByTitle(`${dataTitle.replace(DATA_LIST_SUFFIX, '')} — согласование`);
|
||||
}
|
||||
|
||||
// Сколько строк маршрута максимум забираем за раз при дочитывании комментариев:
|
||||
// на странице ≤20 заявок, у каждой обычно единицы шагов — запас многократный.
|
||||
const RETURN_COMMENT_ROW_LIMIT = 2000;
|
||||
|
||||
/**
|
||||
* Проставляет returnComment — комментарий согласующего, вернувшего заявку на
|
||||
* доработку. Причина возврата хранится в СТРОКЕ МАРШРУТА (колонка Comment
|
||||
* списка «— согласование»), а не в самой заявке, поэтому её нельзя получить
|
||||
* тем же запросом, что и список: нужен отдельный проход по спискам согласования.
|
||||
*
|
||||
* Вызывается ТОЛЬКО там, где причина показывается (см. RequestsTableView) —
|
||||
* счётчику в меню, например, она не нужна, и лишние запросы ему ни к чему.
|
||||
* Мутирует переданные строки — как и hydrateAuthors рядом.
|
||||
*/
|
||||
export async function hydrateReturnComments(
|
||||
context: WebPartContext,
|
||||
types: IRequestType[],
|
||||
rows: IMyRequest[]
|
||||
): Promise<void> {
|
||||
if (rows.length === 0) return;
|
||||
|
||||
const typeById = new Map<number, IRequestType>();
|
||||
types.forEach((t) => typeById.set(t.id, t));
|
||||
|
||||
const rowsByType = new Map<number, IMyRequest[]>();
|
||||
rows.forEach((r) => {
|
||||
const list = rowsByType.get(r.requestTypeId) || [];
|
||||
list.push(r);
|
||||
rowsByType.set(r.requestTypeId, list);
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
Array.from(rowsByType.entries()).map(async ([requestTypeId, typeRows]) => {
|
||||
const type = typeById.get(requestTypeId);
|
||||
if (!type) return;
|
||||
try {
|
||||
const approvalList = await approvalListFor(context, type);
|
||||
if (!approvalList) return;
|
||||
|
||||
// Фильтруем только по TicketId (числовое поле), статус сравниваем в JS:
|
||||
// кириллица в $filter по Choice-колонке молча возвращает 0 строк —
|
||||
// ровно та же причина, что и в indexApprovalsForType.
|
||||
const stepRows = (await approvalList.items
|
||||
.filter(typeRows.map((r) => `TicketId eq ${r.id}`).join(' or '))
|
||||
.select('TicketId', 'ApprovalStatus', 'Comment')
|
||||
.top(RETURN_COMMENT_ROW_LIMIT)()) as Array<Record<string, unknown>>;
|
||||
|
||||
const commentByTicket = new Map<number, string>();
|
||||
stepRows.forEach((r) => {
|
||||
if (r.ApprovalStatus !== REQUEST_STATUS.returned) return;
|
||||
const ticketId = r.TicketId as number | undefined;
|
||||
const comment = ((r.Comment as string) || '').trim();
|
||||
// Возврат по заявке один (при переотправке маршрут переписывается
|
||||
// целиком, см. writeRoute) — но если строк вдруг несколько, берём
|
||||
// первую непустую, а не последнюю пустую.
|
||||
if (ticketId && comment && !commentByTicket.has(ticketId)) {
|
||||
commentByTicket.set(ticketId, comment);
|
||||
}
|
||||
});
|
||||
|
||||
typeRows.forEach((r) => {
|
||||
r.returnComment = commentByTicket.get(r.id);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`[Текущие заявки] «${type.name}»: не удалось прочитать причину возврата:`,
|
||||
(e as Error).message
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// «На согласовании»: список заявок уже отобран по строкам согласования
|
||||
// (getPendingApprovalIndex — там же определяется, чья сейчас очередь,
|
||||
// обычным REST). Здесь среди НИХ фильтруем по тексту — только через Search
|
||||
|
||||
Reference in New Issue
Block a user