Маршрут /admin (вкладки «Пользователи» и «Матрица прав») и пункт «Система → Пользователи и роли» в меню; без USERS_ADMIN в /me — экран «Нет доступа», таблицы не монтируются и запросов к /admin/* нет, пункт меню скрыт. Почему без Redux: данные экрана нужны только ему, после каждой правки перечитываются с сервера — хватает локального state и маленького хука useAsyncData (отбрасывает устаревшие ответы и ответы после ухода со страницы). Клиент один — api/client.ts (Bearer из sessionStorage, ошибки сервера -> ApiError с кодом и текстом); ошибки показываются через App.useApp().message (корень обёрнут в antd App). Экран показывает только серверное состояние: при отказе (409 LAST_ADMIN и др.) — уведомление и перечитывание, матрица сохраняет роли по очереди. РАИСА появится в auth/: токен даст SSO вместо dev-входа; этот экран и клиент не меняются. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
33 lines
1.7 KiB
TypeScript
33 lines
1.7 KiB
TypeScript
import { Result, Tabs } from 'antd';
|
||
import { useCurrentUser } from '../auth/MeContext';
|
||
import { USERS_ADMIN } from '../auth/permissions';
|
||
import { PermissionMatrix } from '../widgets/Admin/PermissionMatrix';
|
||
import { UsersTable } from '../widgets/Admin/UsersTable';
|
||
|
||
/**
|
||
* Экран администратора `/admin`: пользователи и роли, матрица прав.
|
||
*
|
||
* Профиль берём из `AuthGate` (`useCurrentUser`), а не новым запросом `/me`. Без права `USERS_ADMIN` таблицы даже не
|
||
* создаются — значит, их эффекты не запускаются и запросов к `/admin/*` нет. Проверка здесь — только удобство
|
||
* интерфейса: доступ на самом деле решает сервер (403 на `/admin/*` без права).
|
||
*/
|
||
export function Admin() {
|
||
const me = useCurrentUser();
|
||
|
||
if (!me.permissions.includes(USERS_ADMIN)) {
|
||
return <Result status='403' title='Нет доступа' subTitle='Раздел доступен пользователям с правом администрирования' />;
|
||
}
|
||
|
||
return (
|
||
<div style={{ margin: 10, padding: 16, background: 'white', borderRadius: 10, height: 'calc(100% - 20px)', overflow: 'auto' }}>
|
||
{/* вкладка «Матрица прав» создаётся (и грузит данные) только при первом открытии */}
|
||
<Tabs
|
||
items={[
|
||
{ key: 'users', label: 'Пользователи', children: <UsersTable /> },
|
||
{ key: 'matrix', label: 'Матрица прав', children: <PermissionMatrix /> },
|
||
]}
|
||
/>
|
||
</div>
|
||
);
|
||
}
|