Files
request-portal/src/webparts/requestPortal/features/myRequests/pageCache.ts
T
Тимур Городецкий be8177e8ae feat: столбец «Исполнитель» в таблицах заявок
Показывает, у кого заявка сейчас: ФИО и почта согласующего или
исполнителя текущего шага (несколько — параллельный шаг, при
делегировании — делегат), при доработке — инициатор. Есть в
«Инициированных», «Согласованных», «Выполненных мной» и «Все заявки»;
в очередях и «Доработке» держатель всегда сам пользователь.

Дочитывается только для видимой страницы, одним запросом на список
согласования. Группировка по партициям вынесена в approvalPartitionsFor
и общая с комментарием к решению.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 16:28:48 +05:00

61 lines
3.3 KiB
TypeScript

import { IMyRequest } from './models/IMyRequest';
// Загруженная страница таблицы — то, что кладётся в кеш вкладки
// (см. RequestsTableView/SearchView).
export interface IPage {
rows: IMyRequest[];
totalRows: number;
}
// Хранилище на уровне МОДУЛЯ, а не внутри компонента (useRef), потому что
// компоненты таблиц размонтируются при переключении разделов: RequestPortal
// рендерит либо SubmitFeature, либо SearchView, либо RequestsTableView — уход
// на «Поиск» или «Новая заявка» уничтожает экземпляр таблицы вместе со всем его
// состоянием. С useRef кеш переживал только переключение «Мои заявки» ↔ «На
// согласовании» (там экземпляр один, меняется лишь проп kind), а после захода
// на «Поиск» терялся. Здесь он живёт до перезагрузки страницы.
//
// Ключ формирует вызывающая сторона и обязательно начинает с префикса раздела
// (см. pageKey), иначе ключи двух таблиц пересеклись бы.
const store = new Map<string, IPage>();
// Ключ кеша: раздел + всё, от чего зависит содержимое страницы.
export function pageKey(view: string, parts: Array<string | number>): string {
return [view, ...parts].join('|');
}
export function readPage(key: string): IPage | undefined {
return store.get(key);
}
export function writePage(key: string, page: IPage): void {
store.set(key, page);
}
// Слепок страницы для сравнения «изменилось ли что-нибудь». Сравниваем поля,
// которые видны в таблице: если они совпали, перерисовывать нечего — иначе при
// каждом возврате на вкладку и при каждом фоновом обновлении таблица моргала бы,
// перерисовываясь тем же самым содержимым.
// code — тоже видимое поле (колонка «Код»), и его обязательно учитывать: он
// проставляется ВТОРЫМ запросом, уже после создания элемента (см.
// saveRequestItem), поэтому первая выдача может прийти без него. Без code в
// слепке подъехавший позже код совпал бы с прежней подписью, перерисовки не
// случилось бы, и в таблице до перезагрузки страницы висело бы «#5».
export function pageSignature(page: IPage): string {
return `${page.totalRows}|${page.rows
.map((r) =>
[
r.requestTypeId,
r.id,
r.code,
r.title,
r.status,
r.created,
r.authorName,
r.decisionComment ?? '',
(r.currentAssignees ?? []).map((a) => `${a.name}/${a.email}`).join(','),
].join('~')
)
.join(';')}`;
}