From 58682e4e3e6b5daabfb8b74497f7b69cff3b920b Mon Sep 17 00:00:00 2001 From: "gorbenko.pavel" Date: Wed, 19 Aug 2026 17:56:42 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D1=81=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D1=82=D1=81=D1=8F=20=D0=B2=D0=BA=D0=BB=D0=B0=D0=B4=D0=BA?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../approvalAdmin/components/app/AdminApp.tsx | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/frontend/src/webparts/approvalAdmin/components/app/AdminApp.tsx b/frontend/src/webparts/approvalAdmin/components/app/AdminApp.tsx index df02a0e..0db5ee1 100644 --- a/frontend/src/webparts/approvalAdmin/components/app/AdminApp.tsx +++ b/frontend/src/webparts/approvalAdmin/components/app/AdminApp.tsx @@ -9,8 +9,9 @@ import { PortalDictionaryClient } from '../../services/portalDictionary'; import { SharePointListsClient } from '../../services/sharePointLists'; import { RequestManageService } from '../../services/requestManageService'; import { RequestType, TemplateRoute } from '../../models'; -import { navigate, useRoute } from '../../routing'; +import { navigate, replaceRoute, useRoute } from '../../routing'; import { texts } from '../../texts'; +import { useLocalStorageState } from '../../hooks/useLocalStorageState'; import { DashboardScreen } from '../screens/DashboardScreen'; import { RequestTypesScreen } from '../screens/RequestTypesScreen'; import { RoutesScreen } from '../screens/RoutesScreen'; @@ -36,6 +37,12 @@ function sidebarActiveId(tab: ScreenKey): string { return tab === 'routeSteps' ? 'routes' : tab; } +// Последняя открытая вкладка. В адресе она и так живёт (aatab, см. routing.ts), +// но веб-часть часто открывают по «чистой» ссылке на страницу SharePoint, без +// query — и тогда пользователь каждый раз приземлялся на дашборд, даже если +// работает всегда в одном разделе. +const TAB_STORAGE_KEY = 'approvalAdmin.activeTab'; + export interface IAdminAppProps { api: ApprovalRouteApi; /** Undefined, пока SPFx выдаёт AAD-клиент для api.tnsu.kz. */ @@ -52,6 +59,24 @@ export const AdminApp: React.FC = ({ api, dictionary, sharePoint const [navCollapsed, setNavCollapsed] = React.useState(false); const [mobileNavOpen, setMobileNavOpen] = React.useState(false); + const [storedTab, setStoredTab] = useLocalStorageState(TAB_STORAGE_KEY, 'dashboard'); + + // Восстанавливаем последнюю вкладку ТОЛЬКО когда в адресе её нет: глубокая + // ссылка (в т.ч. присланная коллегой) всегда важнее запомненного выбора. + // Один раз на монтировании — дальше вкладку меняет только сам пользователь. + React.useEffect(() => { + const explicitTab = new URLSearchParams(window.location.search).get('aatab'); + if (explicitTab || storedTab === 'dashboard') return; + replaceRoute({ tab: storedTab }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // 'routeSteps' сюда не попадёт: useRoute отдаёт только вкладки из TABS, а шаги + // маршрута — состояние вкладки 'routes' (см. routing.ts). + React.useEffect(() => { + setStoredTab(route.tab); + }, [route.tab, setStoredTab]); + const navigateTab = (key: ScreenKey): void => { setMobileNavOpen(false); navigate({ tab: key });