feat(super-admin): перенести справочник Стран в системную консоль
Country — глобальный справочник (Entity, не TenantEntity), магазины- клиенты выбирают страны из готового списка но не управляют ими. Управление переносится в SuperAdmin консоль. Изменения: - API: POST/PUT /api/catalog/countries теперь Authorize(Roles=SuperAdmin) (раньше был SuperAdmin,Admin). DELETE и так был SuperAdmin. - GET остаётся [Authorize] без роли — нужен tenant'у для селектов в формах создания орги/контрагентов/товаров. - Tenant AppLayout: убран блок «Справочники» с пунктом «Страны». Иконка Globe больше не импортируется в tenant-меню. - Tenant роут /catalog/countries удалён из App.tsx. - В OrganizationSettingsPage ссылка «откройте справочник Страны» заменена на текст «обратитесь к администратору платформы». - SuperAdminLayout: новый блок «Справочники» с пунктом «Страны» (/super-admin/countries). Иконка Globe. - Роут /super-admin/countries использует существующий CountriesPage — компонент unchanged, страница теперь рендерится в SuperAdminLayout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
61cb97a1b7
commit
8d72e9da2d
|
|
@ -57,7 +57,7 @@ public async Task<ActionResult<CountryDto>> Get(Guid id, CancellationToken ct)
|
|||
return c is null ? NotFound() : Project(c);
|
||||
}
|
||||
|
||||
[HttpPost, Authorize(Roles = "SuperAdmin,Admin")]
|
||||
[HttpPost, Authorize(Roles = "SuperAdmin")]
|
||||
public async Task<ActionResult<CountryDto>> Create([FromBody] CountryInput input, CancellationToken ct)
|
||||
{
|
||||
var e = new Country
|
||||
|
|
@ -73,7 +73,7 @@ public async Task<ActionResult<CountryDto>> Create([FromBody] CountryInput input
|
|||
return CreatedAtAction(nameof(Get), new { id = e.Id }, Project(e));
|
||||
}
|
||||
|
||||
[HttpPut("{id:guid}"), Authorize(Roles = "SuperAdmin,Admin")]
|
||||
[HttpPut("{id:guid}"), Authorize(Roles = "SuperAdmin")]
|
||||
public async Task<IActionResult> Update(Guid id, [FromBody] CountryInput input, CancellationToken ct)
|
||||
{
|
||||
var e = await _db.Countries.FirstOrDefaultAsync(x => x.Id == id, ct);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ export default function App() {
|
|||
<Route path="organizations" element={<SuperAdminOrganizationsPage />} />
|
||||
<Route path="organizations/new" element={<SuperAdminOrgCreatePage />} />
|
||||
<Route path="audit-log" element={<SuperAdminAuditLogPage />} />
|
||||
<Route path="countries" element={<CountriesPage />} />
|
||||
</Route>
|
||||
|
||||
{/* Tenant-роуты — обычный AppLayout, но с TenantRouteGuard:
|
||||
|
|
@ -73,7 +74,6 @@ export default function App() {
|
|||
<Route path="/catalog/counterparties" element={<CounterpartiesPage />} />
|
||||
<Route path="/catalog/stores" element={<StoresPage />} />
|
||||
<Route path="/catalog/retail-points" element={<RetailPointsPage />} />
|
||||
<Route path="/catalog/countries" element={<CountriesPage />} />
|
||||
<Route path="/inventory/stock" element={<StockPage />} />
|
||||
<Route path="/inventory/movements" element={<StockMovementsPage />} />
|
||||
<Route path="/purchases/supplies" element={<SuppliesPage />} />
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { logout } from '@/lib/auth'
|
|||
import { cn } from '@/lib/utils'
|
||||
import {
|
||||
LayoutDashboard, Package, FolderTree, Ruler, Tag,
|
||||
Users, Warehouse, Store as StoreIcon, Globe, LogOut, Download, UserCog, Shield, ShieldCheck,
|
||||
Users, Warehouse, Store as StoreIcon, LogOut, Download, UserCog, Shield, ShieldCheck,
|
||||
Boxes, History, TruckIcon, ShoppingCart, Settings, Menu, X,
|
||||
} from 'lucide-react'
|
||||
import { Logo } from './Logo'
|
||||
|
|
@ -49,9 +49,8 @@ function buildNav(isSuperAdmin: boolean): NavSection[] {
|
|||
{ group: 'Продажи', items: [
|
||||
{ to: '/sales/retail', icon: ShoppingCart, label: 'Розничные чеки' },
|
||||
]},
|
||||
{ group: 'Справочники', items: [
|
||||
{ to: '/catalog/countries', icon: Globe, label: 'Страны' },
|
||||
]},
|
||||
// Справочники типа «Страны» — глобальные, управляются SuperAdmin'ом
|
||||
// в системной консоли. В tenant-меню их больше нет.
|
||||
{ group: 'Импорт', items: [
|
||||
{ to: '/admin/import/moysklad', icon: Download, label: 'МойСклад' },
|
||||
]},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { NavLink, Outlet, useLocation, useNavigate } from 'react-router-dom'
|
|||
import { useQuery } from '@tanstack/react-query'
|
||||
import {
|
||||
ShieldCheck, Building, FileClock, HeartPulse, HardDriveDownload,
|
||||
Settings, Users, LayoutDashboard, LogOut, Menu, X, ChevronDown,
|
||||
Settings, Users, LayoutDashboard, LogOut, Menu, X, ChevronDown, Globe,
|
||||
} from 'lucide-react'
|
||||
import { api, getOrgOverride, setOrgOverride } from '@/lib/api'
|
||||
import { logout } from '@/lib/auth'
|
||||
|
|
@ -20,6 +20,9 @@ const NAV: NavSection[] = [
|
|||
{ to: '/super-admin/organizations', icon: Building, label: 'Организации' },
|
||||
{ to: '/super-admin/users', icon: Users, label: 'Пользователи', soon: true },
|
||||
]},
|
||||
{ group: 'Справочники', items: [
|
||||
{ to: '/super-admin/countries', icon: Globe, label: 'Страны' },
|
||||
]},
|
||||
{ group: 'Аудит', items: [
|
||||
{ to: '/super-admin/audit-log', icon: FileClock, label: 'Журнал действий' },
|
||||
]},
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ export function OrganizationSettingsPage() {
|
|||
</div>
|
||||
<p className="text-xs text-slate-500 -mt-2">
|
||||
Валюта и ставка НДС берутся из страны (<strong>{form.countryCode}</strong>) —
|
||||
чтобы изменить, откройте справочник <a className="underline" href="/catalog/countries">Страны</a>.
|
||||
чтобы изменить — обратитесь к администратору платформы (справочник стран управляется в системной консоли).
|
||||
</p>
|
||||
|
||||
<Checkbox
|
||||
|
|
|
|||
Loading…
Reference in a new issue