Skip to content

Commit

Permalink
feat: WebUILink and WebUINavigate component
Browse files Browse the repository at this point in the history
  • Loading branch information
yomybaby committed Nov 19, 2024
1 parent 9fc59ae commit d89a170
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 81 deletions.
136 changes: 70 additions & 66 deletions react/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
import Flex from './components/Flex';
import LocationStateBreadCrumb from './components/LocationStateBreadCrumb';
import MainLayout from './components/MainLayout/MainLayout';
import { useSuspendedBackendaiClient } from './hooks';
import WebUINavigate from './components/WebUINavigate';
import { useBAISettingUserState } from './hooks/useBAISetting';
import Page401 from './pages/Page401';
import Page404 from './pages/Page404';
Expand All @@ -16,7 +16,7 @@ import { Skeleton, theme } from 'antd';
import React, { Suspense } from 'react';
import { FC } from 'react';
import {
Navigate,
IndexRouteObject,
RouterProvider,
createBrowserRouter,
} from 'react-router-dom';
Expand All @@ -35,7 +35,6 @@ const StorageHostSettingPage = React.lazy(
() => import('./pages/StorageHostSettingPage'),
);
const UserSettingsPage = React.lazy(() => import('./pages/UserSettingsPage'));
const SessionListPage = React.lazy(() => import('./pages/SessionListPage'));
const SessionLauncherPage = React.lazy(
() => import('./pages/SessionLauncherPage'),
);
Expand All @@ -61,19 +60,13 @@ const ComputeSessionList = React.lazy(
() => import('./components/ComputeSessionList'),
);

const RedirectToSummary = () => {
useSuspendedBackendaiClient();
const pathName = '/summary';
document.dispatchEvent(
new CustomEvent('move-to-from-react', {
detail: {
path: pathName,
// params: options?.params,
},
}),
);
return <Navigate to="/summary" replace />;
};
interface CustomHandle {
title?: string;
labelKey?: string;
}
export interface WebUIRouteObject extends IndexRouteObject {
handle: CustomHandle;
}

const router = createBrowserRouter([
{
Expand Down Expand Up @@ -105,21 +98,20 @@ const router = createBrowserRouter([
</Suspense>
</QueryParamProvider>
),
handle: { labelKey: 'webui.menu.Summary' },
children: [
{
path: '/',
element: <RedirectToSummary />,
element: <WebUINavigate to="/summary" replace />,
},
{
//for electron dev mode
path: '/build/electron-app/app/index.html',
element: <RedirectToSummary />,
element: <WebUINavigate to="/summary" replace />,
},
{
//for electron prod mode
path: '/app/index.html',
element: <RedirectToSummary />,
element: <WebUINavigate to="/summary" replace />,
},
{
path: '/summary',
Expand Down Expand Up @@ -150,30 +142,73 @@ const router = createBrowserRouter([
),
},
{
path: '/serving',
element: (
<BAIErrorBoundary>
<ServingPage />
</BAIErrorBoundary>
),
handle: { labelKey: 'webui.menu.Serving' },
path: '/session',
handle: { labelKey: 'webui.menu.Sessions' },
children: [
{
path: '',
element: <WebUINavigate to="/job" replace />,
},
{
path: '/session/start',
// handle: { labelKey: 'session.launcher.StartNewSession' },
Component: () => {
const { token } = theme.useToken();
return (
<Flex
direction="column"
gap={token.paddingContentVerticalLG}
align="stretch"
style={{ paddingBottom: token.paddingContentVerticalLG }}
>
<LocationStateBreadCrumb />
<Suspense
fallback={
<Flex direction="column" style={{ maxWidth: 700 }}>
<Skeleton active />
</Flex>
}
>
<SessionLauncherPage />
</Suspense>
</Flex>
);
},
handle: { labelKey: 'session.launcher.StartNewSession' },
},
],
},
{
path: '/serving/:serviceId',
element: (
<BAIErrorBoundary>
<EndpointDetailPage />
</BAIErrorBoundary>
),
handle: { labelKey: 'modelService.RoutingInfo' },
path: '/serving',

handle: { labelKey: 'webui.menu.Serving' },
children: [
{
path: '',
element: (
<BAIErrorBoundary>
<ServingPage />
</BAIErrorBoundary>
),
},
{
path: '/serving/:serviceId',
element: (
<BAIErrorBoundary>
<EndpointDetailPage />
</BAIErrorBoundary>
),
handle: { labelKey: 'modelService.RoutingInfo' },
},
],
},
{
path: '/service',
handle: { labelKey: 'webui.menu.Serving' },
children: [
{
path: '',
element: <Navigate to="/serving" replace />,
element: <WebUINavigate to="/serving" replace />,
},
{
path: 'start',
Expand Down Expand Up @@ -305,37 +340,6 @@ const router = createBrowserRouter([
handle: { labelKey: 'webui.UNAUTHORIZEDACCESS' },
Component: Page401,
},
{
path: '/session',
handle: { labelKey: 'webui.menu.Sessions' },
Component: SessionListPage,
},
{
path: '/session/start',
// handle: { labelKey: 'session.launcher.StartNewSession' },
Component: () => {
const { token } = theme.useToken();
return (
<Flex
direction="column"
gap={token.paddingContentVerticalLG}
align="stretch"
style={{ paddingBottom: token.paddingContentVerticalLG }}
>
<LocationStateBreadCrumb />
<Suspense
fallback={
<Flex direction="column" style={{ maxWidth: 700 }}>
<Skeleton active />
</Flex>
}
>
<SessionLauncherPage />
</Suspense>
</Flex>
);
},
},
// Leave empty tag for plugin pages.
{
path: '*',
Expand Down
53 changes: 38 additions & 15 deletions react/src/components/MainLayout/WebUISider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import BAIMenu from '../BAIMenu';
import BAISider, { BAISiderProps } from '../BAISider';
import Flex from '../Flex';
import SignoutModal from '../SignoutModal';
import WebUILink from '../WebUILink';
import { PluginPage, WebUIPluginType } from './MainLayout';
import {
ApiOutlined,
Expand Down Expand Up @@ -71,42 +72,52 @@ const WebUISider: React.FC<WebUISiderProps> = (props) => {

const generalMenu = filterEmptyItem<ItemType>([
{
label: t('webui.menu.Summary'),
label: <WebUILink to="/summary">{t('webui.menu.Summary')}</WebUILink>,
icon: <DashboardOutlined />,
key: 'summary',
},
{
label: t('webui.menu.Sessions'),
label: <WebUILink to="/job">{t('webui.menu.Sessions')}</WebUILink>,
icon: <BarsOutlined />,
key: 'job',
},
supportServing && {
label: t('webui.menu.Serving'),
label: <WebUILink to="/serving">{t('webui.menu.Serving')}</WebUILink>,
icon: <RocketOutlined />,
key: 'serving',
},
{
label: t('webui.menu.Import&Run'),
label: <WebUILink to="/import">{t('webui.menu.Import&Run')}</WebUILink>,
icon: <PlayIcon />,
key: 'import',
},
{
label: t('webui.menu.Data&Storage'),
label: <WebUILink to="/data">{t('webui.menu.Data&Storage')}</WebUILink>,
icon: <CloudUploadOutlined />,
key: 'data',
},
supportUserCommittedImage && {
label: t('webui.menu.MyEnvironments'),
label: (
<WebUILink to="/my-environment">
{t('webui.menu.MyEnvironments')}
</WebUILink>
),
icon: <FileDoneOutlined />,
key: 'my-environment',
},
!isHideAgents && {
label: t('webui.menu.AgentSummary'),
label: (
<WebUILink to="/agent-summary">
{t('webui.menu.AgentSummary')}
</WebUILink>
),
icon: <HddOutlined />,
key: 'agent-summary',
},
{
label: t('webui.menu.Statistics'),
label: (
<WebUILink to="/statistics">{t('webui.menu.Statistics')}</WebUILink>
),
icon: <BarChartOutlined />,
key: 'statistics',
},
Expand All @@ -122,40 +133,52 @@ const WebUISider: React.FC<WebUISiderProps> = (props) => {

const adminMenu: MenuProps['items'] = [
{
label: t('webui.menu.Users'),
label: <WebUILink to="/credential">{t('webui.menu.Users')}</WebUILink>,
icon: <UserOutlined />,
key: 'credential',
},
{
label: t('webui.menu.Environments'),
label: (
<WebUILink to="/environment">{t('webui.menu.Environments')}</WebUILink>
),
icon: <FileDoneOutlined />,
key: 'environment',
},
{
label: t('webui.menu.ResourcePolicy'),
label: (
<WebUILink to="/resource-policy">
{t('webui.menu.ResourcePolicy')}
</WebUILink>
),
icon: <SolutionOutlined />,
key: 'resource-policy',
},
];

const superAdminMenu: MenuProps['items'] = [
{
label: t('webui.menu.Resources'),
label: <WebUILink to="/agent">{t('webui.menu.Resources')}</WebUILink>,
icon: <HddOutlined />,
key: 'agent',
},
{
label: t('webui.menu.Configurations'),
label: (
<WebUILink to="/settings">{t('webui.menu.Configurations')}</WebUILink>
),
icon: <ControlOutlined />,
key: 'settings',
},
{
label: t('webui.menu.Maintenance'),
label: (
<WebUILink to="/maintenance">{t('webui.menu.Maintenance')}</WebUILink>
),
icon: <ToolOutlined />,
key: 'maintenance',
},
{
label: t('webui.menu.Information'),
label: (
<WebUILink to="/information">{t('webui.menu.Information')}</WebUILink>
),
icon: <InfoCircleOutlined />,
key: 'information',
},
Expand Down
33 changes: 33 additions & 0 deletions react/src/components/WebUILink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import _ from 'lodash';
import React from 'react';
import { Link, LinkProps } from 'react-router-dom';

interface WebUILinkProps extends LinkProps {
options?: {
params?: any;
};
}

const WebUILink: React.FC<WebUILinkProps> = ({ options, ...props }) => {
return (
<Link
{...props}
onClick={(e) => {
props.onClick?.(e);
const pathName = _.isString(props.to)
? props.to
: props.to.pathname || '';
document.dispatchEvent(
new CustomEvent('move-to-from-react', {
detail: {
path: pathName,
params: options?.params,
},
}),
);
}}
/>
);
};

export default WebUILink;
29 changes: 29 additions & 0 deletions react/src/components/WebUINavigate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useSuspendedBackendaiClient } from '../hooks';
import _ from 'lodash';
import React, { useEffect } from 'react';
import { Navigate, NavigateProps } from 'react-router-dom';

interface WebUINavigateProps extends NavigateProps {
options?: {
params?: any;
};
}
const WebUINavigate: React.FC<WebUINavigateProps> = ({ options, ...props }) => {
useSuspendedBackendaiClient();
const pathName = _.isString(props.to) ? props.to : props.to.pathname || '';
useEffect(() => {
document.dispatchEvent(
new CustomEvent('move-to-from-react', {
detail: {
path: pathName,
params: options?.params,
},
}),
);
// Don't need to consider options.params
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathName]);
return <Navigate {...props} />;
};

export default WebUINavigate;

0 comments on commit d89a170

Please sign in to comment.