раздел «Отчёты» в боковом меню — скачивание отчёта по вакансиям (#17)
Tests / frontend-test (push) Successful in 1m15s
Tests / frontend-test (push) Successful in 1m15s
Пункт меню виден только заданному списку почт (Тришина, Городецкий, Горбенко) — группы HR в SharePoint пока нет, добавили TODO завести проверку по ней отдельно (reportsAccess.ts). Скрыт из меню совсем, а не показан неактивным, и прямой переход по ?rpnav=reports у остальных редиректит на «Новую заявку». Раздел — форма периода (С/По) и кнопка «Скачать xlsx», дергает GET api/reports/vacancies через тот же AadHttpClient, что и остальные вызовы approval-route API. Имя файла собирается на фронте по формату бэкенда (VacancyReportWorkbook.FileName), а не читается из Content-Disposition — approval-route не объявляет заголовок в Access-Control-Expose-Headers, браузер бы его не отдал. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/17
This commit was merged in pull request #17.
This commit is contained in:
@@ -36,6 +36,8 @@ import { SearchView } from '../features/myRequests/SearchView';
|
||||
import { getNavCounts, INavCounts } from '../features/myRequests/myRequests.service';
|
||||
import { IMyRequest } from '../features/myRequests/models/IMyRequest';
|
||||
import { isEditableStatus } from '../shared/approval';
|
||||
import { hasReportsAccess } from '../shared/reports/reportsAccess';
|
||||
import { ReportsFeature } from '../features/reports/ReportsFeature';
|
||||
|
||||
// Оболочка портала: тёмное боковое меню (разделы) + основная область.
|
||||
// Логики фич тут нет — файл общий, меняется редко.
|
||||
@@ -70,6 +72,22 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
const [mobileNavOpen, setMobileNavOpen] = React.useState<boolean>(false);
|
||||
const [navCounts, setNavCounts] = React.useState<INavCounts | undefined>(undefined);
|
||||
|
||||
// Раздел «Отчёты» — точечный список почт, пока в SharePoint нет группы HR
|
||||
// (см. reportsAccess.ts). Пересчитывается на каждый рендер намеренно: сам
|
||||
// hasReportsAccess — синхронная проверка без сети, а input (effectiveUserEmail)
|
||||
// меняется только по подмене личности в property pane, что и так вызывает
|
||||
// ререндер всей веб-части.
|
||||
const canSeeReports = hasReportsAccess(context);
|
||||
|
||||
// Прямой переход по ссылке (?rpnav=reports) в обход бокового меню — тот же
|
||||
// раздел, что скрыт из навигации, должен быть недоступен и так: без этого
|
||||
// редиректа он открылся бы у любого, кто угадает или сохранит такую ссылку.
|
||||
React.useEffect(() => {
|
||||
if (route.nav === 'reports' && !canSeeReports) {
|
||||
navigate({ mode: 'submit', nav: 'new' }, { replace: true });
|
||||
}
|
||||
}, [route.nav, canSeeReports]);
|
||||
|
||||
// Уникальный код заявки для заголовка Drawer (approve/edit) — сама форма
|
||||
// узнаёт его только после загрузки (см. onCodeLoaded в ApproveFeature/
|
||||
// EditFeature), поэтому не берём route.itemId (это RowID в SharePoint, а не
|
||||
@@ -278,6 +296,8 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
};
|
||||
|
||||
// Разделы бокового меню для пакетного Sidebar (счётчики — из navCounts).
|
||||
// «Отчёты» — только у тех, кому разрешено (см. canSeeReports выше): скрыт из
|
||||
// меню совсем, а не показан неактивным, — раздела для остальных как бы не существует.
|
||||
const navItems: ISidebarItem[] = [
|
||||
{ id: 'new', title: 'Новая заявка', icon: 'plus' },
|
||||
{ id: 'approvals', title: 'На согласовании', icon: 'user-check', count: navCounts?.approvals },
|
||||
@@ -285,6 +305,7 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
{ id: 'rework', title: 'Доработка', icon: 'edit', count: navCounts?.rework },
|
||||
{ id: 'own', title: 'Мои заявки', icon: 'clipboard' },
|
||||
{ id: 'search', title: 'Поиск', icon: 'search' },
|
||||
...(canSeeReports ? [{ id: 'reports', title: 'Отчёты', icon: 'chart' } as ISidebarItem] : []),
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -375,6 +396,8 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
<OwnTabs activeId={route.ownTab ?? 'created'} onChange={gotoOwnTab} />
|
||||
)}
|
||||
|
||||
{route.nav === 'reports' && canSeeReports && <ReportsFeature context={context} />}
|
||||
|
||||
{LIST_VIEWS[route.nav] !== undefined && (
|
||||
<RequestsTableView
|
||||
context={context}
|
||||
|
||||
Reference in New Issue
Block a user