-
Notifications
You must be signed in to change notification settings - Fork 11.2k
Add Route Manager Hub shadow integration #3485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b2485f9
7cd0b47
0c97acb
edb43ad
5ded9cf
d4db094
8a679f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,15 +17,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. | |
| For commercial licensing, please contact support@quantumnous.com | ||
| */ | ||
|
|
||
| import React, { useEffect, useMemo, useState } from 'react'; | ||
| import React, { useContext, useEffect, useMemo, useState } from 'react'; | ||
| import { Link, useLocation } from 'react-router-dom'; | ||
| import { useTranslation } from 'react-i18next'; | ||
| import { getLucideIcon } from '../../helpers/render'; | ||
| import { ChevronLeft } from 'lucide-react'; | ||
| import { useSidebarCollapsed } from '../../hooks/common/useSidebarCollapsed'; | ||
| import { useSidebar } from '../../hooks/common/useSidebar'; | ||
| import { useMinimumLoadingTime } from '../../hooks/common/useMinimumLoadingTime'; | ||
| import { isAdmin, isRoot, showError } from '../../helpers'; | ||
| import { | ||
| getRouteManagerHubSidebarItems, | ||
| isAdmin, | ||
| isRoot, | ||
| showError, | ||
| shouldShowRouteManagerHubEntry, | ||
| } from '../../helpers'; | ||
| import { StatusContext } from '../../context/Status'; | ||
| import SkeletonWrapper from './components/SkeletonWrapper'; | ||
|
|
||
| import { Nav, Divider, Button } from '@douyinfe/semi-ui'; | ||
|
|
@@ -53,6 +60,7 @@ const routerMap = { | |
|
|
||
| const SiderBar = ({ onNavigate = () => {} }) => { | ||
| const { t } = useTranslation(); | ||
| const [statusState] = useContext(StatusContext); | ||
| const [collapsed, toggleCollapsed] = useSidebarCollapsed(); | ||
| const { | ||
| isModuleVisible, | ||
|
|
@@ -67,6 +75,23 @@ const SiderBar = ({ onNavigate = () => {} }) => { | |
| const [openedKeys, setOpenedKeys] = useState([]); | ||
| const location = useLocation(); | ||
| const [routerMapState, setRouterMapState] = useState(routerMap); | ||
| const routeManagerHubVisible = shouldShowRouteManagerHubEntry( | ||
| statusState?.status?.hub_status, | ||
| ); | ||
| const routeManagerHubSidebarItems = useMemo( | ||
| () => getRouteManagerHubSidebarItems(t), | ||
| [t], | ||
| ); | ||
| const fullReloadRouteMap = useMemo( | ||
| () => | ||
| routeManagerHubVisible | ||
| ? routeManagerHubSidebarItems.reduce((result, item) => { | ||
| result[item.itemKey] = item.to; | ||
| return result; | ||
| }, {}) | ||
| : {}, | ||
| [routeManagerHubSidebarItems, routeManagerHubVisible], | ||
|
Comment on lines
+78
to
+93
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gate Hub navigation on Line 78 uses 💡 Suggested fix- const routeManagerHubVisible = shouldShowRouteManagerHubEntry(
- statusState?.status?.hub_status,
- );
+ const hubStatus = statusState?.status?.hub_status;
+ const routeManagerHubVisible = Boolean(
+ hubStatus?.configured && hubStatus?.reachable,
+ );Also applies to: 133-138 🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
✏️ Learnings added
|
||
| ); | ||
|
|
||
| const workspaceItems = useMemo(() => { | ||
| const items = [ | ||
|
|
@@ -105,6 +130,12 @@ const SiderBar = ({ onNavigate = () => {} }) => { | |
| className: | ||
| localStorage.getItem('enable_task') === 'true' ? '' : 'tableHiddle', | ||
| }, | ||
| { | ||
| text: t('家域中枢'), | ||
| itemKey: 'hub', | ||
| items: routeManagerHubSidebarItems, | ||
| className: routeManagerHubVisible ? '' : 'tableHiddle', | ||
| }, | ||
| ]; | ||
|
|
||
| // 根据配置过滤项目 | ||
|
|
@@ -118,6 +149,8 @@ const SiderBar = ({ onNavigate = () => {} }) => { | |
| localStorage.getItem('enable_data_export'), | ||
| localStorage.getItem('enable_drawing'), | ||
| localStorage.getItem('enable_task'), | ||
| routeManagerHubVisible, | ||
| routeManagerHubSidebarItems, | ||
| t, | ||
| isModuleVisible, | ||
| ]); | ||
|
|
@@ -338,6 +371,8 @@ const SiderBar = ({ onNavigate = () => {} }) => { | |
|
|
||
| // 渲染子菜单项 | ||
| const renderSubItem = (item) => { | ||
| if (item.className === 'tableHiddle') return null; | ||
|
|
||
| if (item.items && item.items.length > 0) { | ||
| const isSelected = selectedKeys.includes(item.itemKey); | ||
| const textColor = isSelected ? SELECTED_COLOR : 'inherit'; | ||
|
|
@@ -361,13 +396,16 @@ const SiderBar = ({ onNavigate = () => {} }) => { | |
| } | ||
| > | ||
| {item.items.map((subItem) => { | ||
| if (subItem.className === 'tableHiddle') return null; | ||
|
|
||
| const isSubSelected = selectedKeys.includes(subItem.itemKey); | ||
| const subTextColor = isSubSelected ? SELECTED_COLOR : 'inherit'; | ||
|
|
||
| return ( | ||
| <Nav.Item | ||
| key={subItem.itemKey} | ||
| itemKey={subItem.itemKey} | ||
| className={subItem.className} | ||
| text={ | ||
| <span | ||
| className='truncate font-medium text-sm' | ||
|
|
@@ -410,6 +448,19 @@ const SiderBar = ({ onNavigate = () => {} }) => { | |
| hoverStyle='sidebar-nav-item:hover' | ||
| selectedStyle='sidebar-nav-item-selected' | ||
| renderWrapper={({ itemElement, props }) => { | ||
| const fullReloadHref = fullReloadRouteMap[props.itemKey]; | ||
| if (fullReloadHref) { | ||
| return ( | ||
| <a | ||
| style={{ textDecoration: 'none' }} | ||
| href={fullReloadHref} | ||
| onClick={onNavigate} | ||
| > | ||
| {itemElement} | ||
| </a> | ||
| ); | ||
| } | ||
|
|
||
| const to = | ||
| routerMapState[props.itemKey] || routerMap[props.itemKey]; | ||
|
|
||
|
|
@@ -457,7 +508,7 @@ const SiderBar = ({ onNavigate = () => {} }) => { | |
| {!collapsed && ( | ||
| <div className='sidebar-group-label'>{t('控制台')}</div> | ||
| )} | ||
| {workspaceItems.map((item) => renderNavItem(item))} | ||
| {workspaceItems.map((item) => renderSubItem(item))} | ||
| </div> | ||
| </> | ||
| )} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This effect can race stale hub responses back into state.
Every availability change now starts a fresh
loadHubData()call, butweb/src/hooks/dashboard/useDashboardData.js:286-390does not cancel or sequence its multi-request pipeline. If an older request resolves after a later “unavailable” update, it can repopulate stale hub nodes/alerts/summary on the dashboard.🤖 Prompt for AI Agents
Respect
console.hubvisibility before fetching or rendering the hub panel.Line 147 loads hub data and Line 183 renders the panel unconditionally, so disabling
SidebarModulesAdmin.console.hubonly hides the sidebar entry. The dashboard still exposes the module and its data.💡 Suggested fix
Based on learnings: The sidebar management system introduced in this codebase uses SidebarModulesAdmin configuration to control admin user permissions. Admin access to console.* modules should be governed by this configuration system, not bypassed with hardcoded allowlists.
Also applies to: 182-196
🤖 Prompt for AI Agents