diff --git a/manifest/backend.ai-brand-simple-black.svg b/manifest/backend.ai-brand-simple-black.svg new file mode 100644 index 0000000000..3f72bb321d --- /dev/null +++ b/manifest/backend.ai-brand-simple-black.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/manifest/backend.ai-brand-simple-white.svg b/manifest/backend.ai-brand-simple-white.svg new file mode 100644 index 0000000000..d9b4cf77ad --- /dev/null +++ b/manifest/backend.ai-brand-simple-white.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/manifest/backend.ai-webui-black.svg b/manifest/backend.ai-webui-black.svg new file mode 100644 index 0000000000..be625647bc --- /dev/null +++ b/manifest/backend.ai-webui-black.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/manifest/backend.ai-webui-white.svg b/manifest/backend.ai-webui-white.svg new file mode 100644 index 0000000000..431c69c6d6 --- /dev/null +++ b/manifest/backend.ai-webui-white.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/react/src/App.tsx b/react/src/App.tsx index 646663fae6..123b595931 100644 --- a/react/src/App.tsx +++ b/react/src/App.tsx @@ -296,7 +296,7 @@ const router = createBrowserRouter([ }, { path: '/agent', - handle: { labelKey: 'webui.menu.ComputationResources' }, + handle: { labelKey: 'webui.menu.Resources' }, Component: ResourcesPage, }, { @@ -310,7 +310,7 @@ const router = createBrowserRouter([ }, { path: '/maintenance', - handle: { labelKey: 'webui.menu.Environments&Presets' }, + handle: { labelKey: 'webui.menu.Maintenance' }, }, { path: '/storage-settings/:hostname', diff --git a/react/src/components/BAIIcons/BatchSession.svg b/react/src/components/BAIIcons/BatchSession.svg new file mode 100644 index 0000000000..0ee4d92034 --- /dev/null +++ b/react/src/components/BAIIcons/BatchSession.svg @@ -0,0 +1,4 @@ + + + + diff --git a/react/src/components/BAIIcons/BatchSessionIcon.tsx b/react/src/components/BAIIcons/BatchSessionIcon.tsx new file mode 100644 index 0000000000..a624b5243b --- /dev/null +++ b/react/src/components/BAIIcons/BatchSessionIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './BatchSession.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface BatchSessionIconProps + extends Omit {} + +const BatchSessionIcon: React.FC = (props) => { + return ; +}; + +export default BatchSessionIcon; diff --git a/react/src/components/BAIIcons/Endpoints.svg b/react/src/components/BAIIcons/Endpoints.svg new file mode 100644 index 0000000000..c6b70c8f47 --- /dev/null +++ b/react/src/components/BAIIcons/Endpoints.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/react/src/components/BAIIcons/EndpointsIcon.tsx b/react/src/components/BAIIcons/EndpointsIcon.tsx new file mode 100644 index 0000000000..e3d23f95a9 --- /dev/null +++ b/react/src/components/BAIIcons/EndpointsIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './Endpoints.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface EndpointsIconProps + extends Omit {} + +const EndpointsIcon: React.FC = (props) => { + return ; +}; + +export default EndpointsIcon; diff --git a/react/src/components/BAIIcons/ExampleStart.svg b/react/src/components/BAIIcons/ExampleStart.svg new file mode 100644 index 0000000000..6d206300a8 --- /dev/null +++ b/react/src/components/BAIIcons/ExampleStart.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/react/src/components/BAIIcons/ExampleStart.tsx b/react/src/components/BAIIcons/ExampleStart.tsx new file mode 100644 index 0000000000..9dbe2cc24c --- /dev/null +++ b/react/src/components/BAIIcons/ExampleStart.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './ExampleStart.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface ExampleStartIconProps + extends Omit {} + +const ExampleStartIcon: React.FC = (props) => { + return ; +}; + +export default ExampleStartIcon; diff --git a/react/src/components/BAIIcons/Examples.svg b/react/src/components/BAIIcons/Examples.svg new file mode 100644 index 0000000000..6194efc9ee --- /dev/null +++ b/react/src/components/BAIIcons/Examples.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/react/src/components/BAIIcons/ExamplesIcon.tsx b/react/src/components/BAIIcons/ExamplesIcon.tsx new file mode 100644 index 0000000000..0aded39924 --- /dev/null +++ b/react/src/components/BAIIcons/ExamplesIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './Examples.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface ExamplesIconProps + extends Omit {} + +const ExamplesIcon: React.FC = (props) => { + return ; +}; + +export default ExamplesIcon; diff --git a/react/src/components/BAIIcons/InteractiveSession.svg b/react/src/components/BAIIcons/InteractiveSession.svg new file mode 100644 index 0000000000..27dbd7f669 --- /dev/null +++ b/react/src/components/BAIIcons/InteractiveSession.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/react/src/components/BAIIcons/InteractiveSession.tsx b/react/src/components/BAIIcons/InteractiveSession.tsx new file mode 100644 index 0000000000..4aeecb0cc1 --- /dev/null +++ b/react/src/components/BAIIcons/InteractiveSession.tsx @@ -0,0 +1,14 @@ +import { ReactComponent as logo } from './InteractiveSession.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface InteractiveSessionIconProps + extends Omit {} + +const InteractiveSessionIcon: React.FC = ( + props, +) => { + return ; +}; + +export default InteractiveSessionIcon; diff --git a/react/src/components/BAIIcons/ModelService.svg b/react/src/components/BAIIcons/ModelService.svg new file mode 100644 index 0000000000..d848b2d2f9 --- /dev/null +++ b/react/src/components/BAIIcons/ModelService.svg @@ -0,0 +1,4 @@ + + + + diff --git a/react/src/components/BAIIcons/ModelServiceIcon.tsx b/react/src/components/BAIIcons/ModelServiceIcon.tsx new file mode 100644 index 0000000000..f1bf206df9 --- /dev/null +++ b/react/src/components/BAIIcons/ModelServiceIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './ModelService.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface ModelServiceIconProps + extends Omit {} + +const ModelServiceIcon: React.FC = (props) => { + return ; +}; + +export default ModelServiceIcon; diff --git a/react/src/components/BAIIcons/Models.svg b/react/src/components/BAIIcons/Models.svg new file mode 100644 index 0000000000..dcf7e0d414 --- /dev/null +++ b/react/src/components/BAIIcons/Models.svg @@ -0,0 +1,4 @@ + + + + diff --git a/react/src/components/BAIIcons/ModelsIcon.tsx b/react/src/components/BAIIcons/ModelsIcon.tsx new file mode 100644 index 0000000000..0f9d078226 --- /dev/null +++ b/react/src/components/BAIIcons/ModelsIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './Models.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface ModelsIconProps + extends Omit {} + +const ModelsIcon: React.FC = (props) => { + return ; +}; + +export default ModelsIcon; diff --git a/react/src/components/BAIIcons/MyEnvironments.svg b/react/src/components/BAIIcons/MyEnvironments.svg new file mode 100644 index 0000000000..b24f3f94e5 --- /dev/null +++ b/react/src/components/BAIIcons/MyEnvironments.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/react/src/components/BAIIcons/MyEnvironmentsIcon.tsx b/react/src/components/BAIIcons/MyEnvironmentsIcon.tsx new file mode 100644 index 0000000000..30c0d52e5f --- /dev/null +++ b/react/src/components/BAIIcons/MyEnvironmentsIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './MyEnvironments.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface MyEnvironmentsIconProps + extends Omit {} + +const MyEnvironmentsIcon: React.FC = (props) => { + return ; +}; + +export default MyEnvironmentsIcon; diff --git a/react/src/components/BAIIcons/Pipelines.svg b/react/src/components/BAIIcons/Pipelines.svg new file mode 100644 index 0000000000..63cc50da3a --- /dev/null +++ b/react/src/components/BAIIcons/Pipelines.svg @@ -0,0 +1,3 @@ + + + diff --git a/react/src/components/BAIIcons/PipelinesIcon.tsx b/react/src/components/BAIIcons/PipelinesIcon.tsx new file mode 100644 index 0000000000..18dce3c5ba --- /dev/null +++ b/react/src/components/BAIIcons/PipelinesIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './Pipelines.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface PipelinesIconProps + extends Omit {} + +const PipelinesIcon: React.FC = (props) => { + return ; +}; + +export default PipelinesIcon; diff --git a/react/src/components/BAIIcons/RecalculateResources.svg b/react/src/components/BAIIcons/RecalculateResources.svg new file mode 100644 index 0000000000..f9487e2c85 --- /dev/null +++ b/react/src/components/BAIIcons/RecalculateResources.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/react/src/components/BAIIcons/RecalculateResourcesIcon.tsx b/react/src/components/BAIIcons/RecalculateResourcesIcon.tsx new file mode 100644 index 0000000000..859522d769 --- /dev/null +++ b/react/src/components/BAIIcons/RecalculateResourcesIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './RecalculateResources.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface MyEnvironmentsIconProps + extends Omit {} + +const MyEnvironmentsIcon: React.FC = (props) => { + return ; +}; + +export default MyEnvironmentsIcon; diff --git a/react/src/components/BAIIcons/Sessions.svg b/react/src/components/BAIIcons/Sessions.svg new file mode 100644 index 0000000000..b53e566ef8 --- /dev/null +++ b/react/src/components/BAIIcons/Sessions.svg @@ -0,0 +1,3 @@ + + + diff --git a/react/src/components/BAIIcons/SessionsIcon.tsx b/react/src/components/BAIIcons/SessionsIcon.tsx new file mode 100644 index 0000000000..efad5cb57b --- /dev/null +++ b/react/src/components/BAIIcons/SessionsIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './Sessions.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface SessionsIconProps + extends Omit {} + +const SessionsIcon: React.FC = (props) => { + return ; +}; + +export default SessionsIcon; diff --git a/react/src/components/BAIIcons/Trails.svg b/react/src/components/BAIIcons/Trails.svg new file mode 100644 index 0000000000..62b10100bb --- /dev/null +++ b/react/src/components/BAIIcons/Trails.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/react/src/components/BAIIcons/TrailsIcon.tsx b/react/src/components/BAIIcons/TrailsIcon.tsx new file mode 100644 index 0000000000..95de4ad5c0 --- /dev/null +++ b/react/src/components/BAIIcons/TrailsIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './Trails.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface TrailsIconProps + extends Omit {} + +const TrailsIcon: React.FC = (props) => { + return ; +}; + +export default TrailsIcon; diff --git a/react/src/components/BAIIcons/URLStart.svg b/react/src/components/BAIIcons/URLStart.svg new file mode 100644 index 0000000000..c580825c00 --- /dev/null +++ b/react/src/components/BAIIcons/URLStart.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/react/src/components/BAIIcons/URLStartIcon.tsx b/react/src/components/BAIIcons/URLStartIcon.tsx new file mode 100644 index 0000000000..10e7bcf47d --- /dev/null +++ b/react/src/components/BAIIcons/URLStartIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './URLStart.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface URLStartIconProps + extends Omit {} + +const URLStartIcon: React.FC = (props) => { + return ; +}; + +export default URLStartIcon; diff --git a/react/src/components/BAIIcons/UpdateEnvironmentImageIcon.tsx b/react/src/components/BAIIcons/UpdateEnvironmentImageIcon.tsx new file mode 100644 index 0000000000..a053976cfb --- /dev/null +++ b/react/src/components/BAIIcons/UpdateEnvironmentImageIcon.tsx @@ -0,0 +1,14 @@ +import { ReactComponent as logo } from './UpdateEnvironmentImages.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface UpdateEnvironmentImageIconProps + extends Omit {} + +const UpdateEnvironmentImageIcon: React.FC = ( + props, +) => { + return ; +}; + +export default UpdateEnvironmentImageIcon; diff --git a/react/src/components/BAIIcons/UpdateEnvironmentImages.svg b/react/src/components/BAIIcons/UpdateEnvironmentImages.svg new file mode 100644 index 0000000000..658a1aa61a --- /dev/null +++ b/react/src/components/BAIIcons/UpdateEnvironmentImages.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/react/src/components/BAIIcons/UserOutlined.svg b/react/src/components/BAIIcons/UserOutlined.svg new file mode 100644 index 0000000000..88039559cd --- /dev/null +++ b/react/src/components/BAIIcons/UserOutlined.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/react/src/components/BAIIcons/UserOutlinedIcon.tsx b/react/src/components/BAIIcons/UserOutlinedIcon.tsx new file mode 100644 index 0000000000..bdaabd78e0 --- /dev/null +++ b/react/src/components/BAIIcons/UserOutlinedIcon.tsx @@ -0,0 +1,12 @@ +import { ReactComponent as logo } from './UserOutlined.svg'; +import Icon from '@ant-design/icons'; +import { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon'; + +interface UserOutlinedIconProps + extends Omit {} + +const UserOutlinedIcon: React.FC = (props) => { + return ; +}; + +export default UserOutlinedIcon; diff --git a/react/src/components/BAIMenu.tsx b/react/src/components/BAIMenu.tsx index 480d50cce7..810885bb14 100644 --- a/react/src/components/BAIMenu.tsx +++ b/react/src/components/BAIMenu.tsx @@ -1,14 +1,49 @@ -import { ConfigProvider, Menu, MenuProps } from 'antd'; +import { ConfigProvider, Menu, MenuProps, theme } from 'antd'; +import { createStyles } from 'antd-style'; +import classNames from 'classnames'; import React from 'react'; -const BAIMenu: React.FC = ({ ...props }) => { +const useStyle = createStyles(({ css, token }) => ({ + baiMenu: css` + &.expanded ul.ant-menu-item-group-list li.ant-menu-item { + padding-inline: ${token.padding}px !important; + } + + &.expanded li div.ant-menu-item-group-title { + padding-top: ${token.paddingMD}px; + padding-left: ${token.paddingXL}px; + } + + &.expanded li div.ant-menu-item-group-title div { + border-bottom-width: 0 !important; + } + li div.ant-menu-item-group-title div span { + font-weight: 500; + } + `, +})); + +interface BAIMenuProps extends MenuProps { + collapsed?: boolean; +} + +const BAIMenu: React.FC = ({ collapsed, ...props }) => { + const { styles } = useStyle(); + const { token } = theme.useToken(); + const colorPrimaryWithAlpha = `rgba(${parseInt(token.colorPrimary.slice(1, 3), 16)}, ${parseInt(token.colorPrimary.slice(3, 5), 16)}, ${parseInt(token.colorPrimary.slice(5, 7), 16)}, 0.15)`; + return ( = ({ ...props }) => { style={{ backgroundColor: 'transparent', borderRight: 'none', - paddingRight: 4, + // paddingRight: 4, }} // mode="" {...props} - className="bai-menu" + className={classNames( + 'bai-menu', + styles.baiMenu, + collapsed ? 'collapsed' : 'expanded', + )} /> ); diff --git a/react/src/components/BAISider.tsx b/react/src/components/BAISider.tsx index 568a899a62..3406263261 100644 --- a/react/src/components/BAISider.tsx +++ b/react/src/components/BAISider.tsx @@ -56,7 +56,7 @@ const BAISider: React.FC = ({ `} = ({ position: 'sticky', top: 0, left: 0, - borderRight: '1px solid', - borderColor: token.colorBorder, - paddingTop: token.paddingContentVerticalSM, scrollbarColor: 'auto', }} {...otherProps} @@ -88,15 +85,16 @@ const BAISider: React.FC = ({ > @@ -108,7 +106,7 @@ const BAISider: React.FC = ({ {logoCollapsed} -
+ {/*
= ({ > {otherProps.collapsed ? logoTitleCollapsed : logoTitle} -
+
*/}
{children} {bottomText && ( @@ -130,7 +128,7 @@ const BAISider: React.FC = ({ direction="column" style={{ width: '100%', - padding: 20, + padding: 30, textAlign: 'center', }} > diff --git a/react/src/components/MainLayout/WebUISider.tsx b/react/src/components/MainLayout/WebUISider.tsx index 94b5e3479b..09bc19a3fb 100644 --- a/react/src/components/MainLayout/WebUISider.tsx +++ b/react/src/components/MainLayout/WebUISider.tsx @@ -3,16 +3,19 @@ import { useCustomThemeConfig } from '../../helper/customThemeConfig'; import { useSuspendedBackendaiClient, useWebUINavigate } from '../../hooks'; import { useCurrentUserRole } from '../../hooks/backendai'; import { useThemeMode } from '../../hooks/useThemeMode'; +import EndpointsIcon from '../BAIIcons/EndpointsIcon'; +import MyEnvironmentsIcon from '../BAIIcons/MyEnvironmentsIcon'; +import SessionsIcon from '../BAIIcons/SessionsIcon'; import BAIMenu from '../BAIMenu'; import BAISider, { BAISiderProps } from '../BAISider'; import Flex from '../Flex'; +import ReverseThemeProvider from '../ReverseThemeProvider'; import SignoutModal from '../SignoutModal'; import WebUILink from '../WebUILink'; import { PluginPage, WebUIPluginType } from './MainLayout'; import { ApiOutlined, BarChartOutlined, - BarsOutlined, CloudUploadOutlined, ControlOutlined, DashboardOutlined, @@ -20,17 +23,22 @@ import { FileDoneOutlined, HddOutlined, InfoCircleOutlined, - RocketOutlined, SolutionOutlined, ToolOutlined, UserOutlined, } from '@ant-design/icons'; import { useToggle } from 'ahooks'; -import { theme, MenuProps, Typography } from 'antd'; +import { + theme, + MenuProps, + Typography, + ConfigProvider, + Divider, +} from 'antd'; import { ItemType } from 'antd/lib/menu/interface'; import _ from 'lodash'; import { PlayIcon } from 'lucide-react'; -import React from 'react'; +import React, { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { useLocation } from 'react-router-dom'; @@ -47,12 +55,10 @@ const WebUISider: React.FC = (props) => { const { t } = useTranslation(); const { token } = theme.useToken(); const themeConfig = useCustomThemeConfig(); - const { isDarkMode } = useThemeMode(); - const mergedSiderTheme = themeConfig?.sider?.theme - ? themeConfig.sider.theme - : isDarkMode - ? 'dark' - : 'light'; + + const config = useContext(ConfigProvider.ConfigContext); + const currentSiderTheme = + config.theme?.algorithm === theme.darkAlgorithm ? 'dark' : 'light'; const currentUserRole = useCurrentUserRole(); const webuiNavigate = useWebUINavigate(); @@ -73,27 +79,27 @@ const WebUISider: React.FC = (props) => { const generalMenu = filterEmptyItem([ { label: {t('webui.menu.Summary')}, - icon: , + icon: , key: 'summary', }, { label: {t('webui.menu.Sessions')}, - icon: , + icon: , key: 'job', }, supportServing && { label: {t('webui.menu.Serving')}, - icon: , + icon: , key: 'serving', }, { label: {t('webui.menu.Import&Run')}, - icon: , + icon: , key: 'import', }, { label: {t('webui.menu.Data&Storage')}, - icon: , + icon: , key: 'data', }, supportUserCommittedImage && { @@ -102,7 +108,7 @@ const WebUISider: React.FC = (props) => { {t('webui.menu.MyEnvironments')} ), - icon: , + icon: , key: 'my-environment', }, !isHideAgents && { @@ -111,19 +117,19 @@ const WebUISider: React.FC = (props) => { {t('webui.menu.AgentSummary')} ), - icon: , + icon: , key: 'agent-summary', }, { label: ( {t('webui.menu.Statistics')} ), - icon: , + icon: , key: 'statistics', }, !!fasttrackEndpoint && { label: t('webui.menu.FastTrack'), - icon: , + icon: , key: 'pipeline', onClick: () => { window.open(fasttrackEndpoint, '_blank', 'noopener noreferrer'); @@ -134,14 +140,14 @@ const WebUISider: React.FC = (props) => { const adminMenu: MenuProps['items'] = [ { label: {t('webui.menu.Users')}, - icon: , + icon: , key: 'credential', }, { label: ( {t('webui.menu.Environments')} ), - icon: , + icon: , key: 'environment', }, { @@ -150,7 +156,7 @@ const WebUISider: React.FC = (props) => { {t('webui.menu.ResourcePolicy')} ), - icon: , + icon: , key: 'resource-policy', }, ]; @@ -158,28 +164,28 @@ const WebUISider: React.FC = (props) => { const superAdminMenu: MenuProps['items'] = [ { label: {t('webui.menu.Resources')}, - icon: , + icon: , key: 'agent', }, { label: ( {t('webui.menu.Configurations')} ), - icon: , + icon: , key: 'settings', }, { label: ( {t('webui.menu.Maintenance')} ), - icon: , + icon: , key: 'maintenance', }, { label: ( {t('webui.menu.Information')} ), - icon: , + icon: , key: 'information', }, ]; @@ -230,34 +236,34 @@ const WebUISider: React.FC = (props) => { className="logo-wide" alt={themeConfig?.logo?.alt || 'Backend.AI Logo'} src={ - mergedSiderTheme === 'dark' && themeConfig?.logo?.srcDark + currentSiderTheme === 'dark' && themeConfig?.logo?.srcDark ? themeConfig?.logo?.srcDark || - '/manifest/backend.ai-text-bgdark.svg' - : themeConfig?.logo?.src || '/manifest/backend.ai-text.svg' + '/manifest/backend.ai-white-text.svg' + : themeConfig?.logo?.src || '/manifest/backend.ai-white-text.svg' } style={{ - width: themeConfig?.logo?.size?.width || 191, - height: themeConfig?.logo?.size?.height || 32, + width: themeConfig?.logo?.size?.width || 159, + height: themeConfig?.logo?.size?.height || 24, cursor: 'pointer', }} onClick={() => webuiNavigate(themeConfig?.logo?.href || '/summary')} /> } - theme={mergedSiderTheme} + theme={currentSiderTheme} logoCollapsed={ {themeConfig?.logo?.alt webuiNavigate(themeConfig?.logo?.href || '/summary')} @@ -271,6 +277,7 @@ const WebUISider: React.FC = (props) => { props.collapsed ? null : ( <>
+ = (props) => { {...props} > = (props) => { // and change 'job' key to 'session' location.pathname.split('/')[1] === 'session' ? 'job' : '', ]} - items={ - // TODO: add plugin menu - currentUserRole === 'superadmin' - ? [ - ...generalMenu, - { - type: 'group', - label: ( - - {!props.collapsed && ( - - {t('webui.menu.Administration')} - - )} - - ), - children: [...adminMenu, ...superAdminMenu], - }, - ] - : currentUserRole === 'admin' - ? [ - ...generalMenu, - { - type: 'group', - label: ( - - {!props.collapsed && ( - - {t('webui.menu.Administration')} - - )} - - ), - children: [...adminMenu], - }, - ] - : [...generalMenu] - } - /** - * Etc menu - */ - // { - // label: '404', - // icon: , - // key: '404', - // }, - // ]} - onClick={({ key, keyPath }) => { - webuiNavigate('/' + keyPath.join('/')); - }} + items={generalMenu} /> + {(currentUserRole === 'superadmin' || currentUserRole === 'admin') && ( + + + {!props.collapsed && ( + + {t('webui.menu.Administration')} + + )} + + ), + children: [...adminMenu, ...superAdminMenu], + }, + ] + : currentUserRole === 'admin' + ? [ + { + type: 'group', + label: ( + + {!props.collapsed && ( + + {t('webui.menu.Administration')} + + )} + + ), + children: [...adminMenu], + }, + ] + : [] + } + /> + + )} ); }; -export default WebUISider; + +const WebUISiderWithCustomTheme: React.FC = (props) => { + const themeConfig = useCustomThemeConfig(); + const config = useContext(ConfigProvider.ConfigContext); + const isParentDark = config.theme?.algorithm === theme.darkAlgorithm; + + const shouldReverse = + (isParentDark && themeConfig.sider?.theme === 'light') || + (!isParentDark && themeConfig.sider?.theme === 'dark'); + + return shouldReverse ? ( + + + + ) : ( + + ); +}; + +export default WebUISiderWithCustomTheme; diff --git a/resources/theme.json b/resources/theme.json index 252f4e58df..1b2c28a8b9 100644 --- a/resources/theme.json +++ b/resources/theme.json @@ -5,7 +5,9 @@ "fontFamily": "'Ubuntu', Roboto, sans-serif", "colorPrimary": "#FF7A00", "colorLink": "#FF7A00", - "colorText": "#141414" + "colorText": "#141414", + "colorInfo": "#028DF2", + "colorError": "#FF4D4F" }, "components": { "Tag": { @@ -18,6 +20,9 @@ "lightSiderBg": "#FFF", "siderBg": "#141414", "headerBg": "#FF9729" + }, + "Divider": { + "colorSplit": "#D9D9D9" } } }, @@ -26,7 +31,9 @@ "fontFamily": "'Ubuntu', Roboto, sans-serif", "colorPrimary": "#DC6B03", "colorLink": "#DC6B03", - "colorText": "#FFF" + "colorText": "#FFF", + "colorInfo": "#009BDD", + "colorError": "#DC4446" }, "components": { "Tag": { @@ -43,21 +50,17 @@ } }, "logo": { - "src": "/manifest/backend.ai-text.svg", - "srcCollapsed": "/manifest/backend.ai-brand-simple.svg", - "srcDark": "/manifest/backend.ai-text-bgdark.svg", - "srcCollapsedDark": "/manifest/backend.ai-brand-simple-bgdark.svg", + "src": "/manifest/backend.ai-webui-white.svg", + "srcCollapsed": "/manifest/backend.ai-brand-simple-white.svg", + "srcDark": "/manifest/backend.ai-webui-black.svg", + "srcCollapsedDark": "/manifest/backend.ai-brand-simple-black.svg", "logoTitle": "WebUI", "logoTitleCollapsed": "WebUI", "alt": "Backend.AI Logo", "href": "/summary", - "size": { - "width": 191, - "height": 32 - }, "sizeCollapsed": { - "width": 48, - "height": 32 + "width": 34, + "height": 34 } }, "sider": {