Search requests (#2)

Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/2
Co-authored-by: timur.gorodetskiy <timur.gorodetskiy@tnsu.kz>
Co-committed-by: timur.gorodetskiy <timur.gorodetskiy@tnsu.kz>
This commit was merged in pull request #2.
This commit is contained in:
2026-08-06 09:59:07 +00:00
committed by gorbenko.pavel
parent 571614c031
commit 6acb22dd95
23 changed files with 1622 additions and 459 deletions
@@ -3,7 +3,7 @@ import styles from './RequestPortal.module.scss';
import type { IRequestPortalProps } from './IRequestPortalProps';
import { IconSprite } from '../shared/ui/Icon/IconSprite';
import { navigate, useRoute, NavSection } from '../shared/routing';
import { onRequestsChanged } from '../shared/requestEvents';
import { onRequestsChanged, emitRequestsChanged } from '../shared/requestEvents';
import { SideNav } from './SideNav/SideNav';
import { Drawer } from './Drawer/Drawer';
import { CategoryTabs } from './CategoryTabs/CategoryTabs';
@@ -12,6 +12,7 @@ import { REQUEST_TYPES } from '../data/requests';
import SubmitFeature from '../features/submit/SubmitFeature';
import ApproveFeature from '../features/approve/ApproveFeature';
import { RequestsTableView } from '../features/myRequests/RequestsTableView';
import { SearchView } from '../features/myRequests/SearchView';
import { getPendingApproval } from '../features/myRequests/myRequests.service';
// Оболочка портала: тёмное боковое меню (разделы) + основная область.
@@ -39,14 +40,18 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
});
// Счётчик на пункте «На согласовании». Обновляется по тому же событию, что и
// сами таблицы (создание заявки, решение согласующего).
// сами таблицы (создание заявки, решение согласующего), и на монтировании
// (в т.ч. на обновление страницы). Когда сама вкладка «На согласовании»
// открыта, RequestsTableView сообщает точное число через onMyTurnCountChange
// (ниже) — это перезаписывает значение отсюда, чтобы не было гонки между
// двумя независимыми запросами одних и тех же данных.
React.useEffect(() => {
let cancelled = false;
const load = (): void => {
getPendingApproval(context)
.then((r) => {
if (!cancelled) setApprovalsCount(r.rows.length);
if (!cancelled) setApprovalsCount(r.totalRows);
})
.catch(() => {
if (!cancelled) setApprovalsCount(undefined);
@@ -70,7 +75,14 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
}
}, [route.mode, route.formKey]);
const goto = (nav: NavSection): void => navigate({ mode: 'submit', nav });
const goto = (nav: NavSection): void => {
// Клик по УЖЕ активному пункту меню не меняет маршрут, значит эффект
// загрузки в таблице не перезапустится сам. Шлём событие обновления —
// таблица на него подписана и перечитает данные фоном, не убирая с экрана
// текущие строки (см. RequestsTableView/SearchView).
if (nav === route.nav && route.mode === 'submit') emitRequestsChanged();
navigate({ mode: 'submit', nav });
};
const closeDrawer = (): void => navigate({ mode: 'submit', nav: route.nav });
return (
@@ -84,7 +96,6 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
approvalsCount={approvalsCount}
collapsed={navCollapsed}
onToggleCollapsed={() => setNavCollapsed((v) => !v)}
userName={context.pageContext.user.displayName}
/>
</div>
@@ -108,6 +119,18 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
}
/>
</>
) : route.nav === 'search' ? (
<SearchView
context={context}
onOpen={(request) =>
navigate({
mode: 'approve',
nav: route.nav,
formKey: request.formKey,
itemId: request.id,
})
}
/>
) : (
<RequestsTableView
context={context}
@@ -120,6 +143,7 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
itemId: request.id,
})
}
onMyTurnCountChange={route.nav === 'approvals' ? setApprovalsCount : undefined}
/>
)}
</main>