diff --git a/src/config/settings.ts b/src/config/settings.ts index 81ad4ae2..8f24b432 100644 --- a/src/config/settings.ts +++ b/src/config/settings.ts @@ -1,4 +1,4 @@ -export const HEADER_HEIGHT = 56; +export const HEADER_HEIGHT = 48; export const DEFAULT_ENTER_PAGE = { adminForNormal: '/dashboard', diff --git a/src/config/theme/light.ts b/src/config/theme/light.ts index dfd98922..1df7b622 100644 --- a/src/config/theme/light.ts +++ b/src/config/theme/light.ts @@ -4,6 +4,9 @@ export default { 'root-entry-name': 'variable', hashed: false, components: { + Layout: { + headerHeight: 48 + }, Input: { inputFontSize: 14, inputFontSizeLG: 14 diff --git a/src/global.less b/src/global.less index 8806b59b..1c7346c8 100644 --- a/src/global.less +++ b/src/global.less @@ -4,6 +4,8 @@ @import url('./overrides.less'); html { + --page-header-height: 56px; + --page-content-padding: 8px; --color-text-light-1: rgba(255, 255, 255, 90%); --color-fill-1: var(--ant-color-bg-container); --color-scrollbar-thumb: rgba(193, 193, 193, 80%); @@ -22,8 +24,8 @@ html { --color-fill-3: #f3f6fa; --color-logs-bg: #1e1e1e; --color-logs-text: #d4d4d4; - --layout-content-blockpadding: 32px; - --layout-content-inlinepadding: 32px; + --layout-content-blockpadding: 24px; + --layout-content-inlinepadding: 24px; --layout-content-header-inlinepadding: 40px; --border-radius-modal: 12px; --menu-border-radius-base: 4px; @@ -120,6 +122,8 @@ html[data-theme='light'] { background-color: #fff !important; transition: none !important; } + + background-color: #f5f5f5; } body { @@ -275,7 +279,7 @@ body { } .ant-pro-sider .ant-layout-sider-children { - border-right: 1px solid var(--ant-color-split); + // border-right: 1px solid var(--ant-color-split); } } @@ -336,7 +340,7 @@ body { .ant-pro-layout-container { overflow-x: auto; min-height: 100vh; - background-color: var(--ant-color-bg-container); + // background-color: var(--ant-color-bg-container); } .ant-pro-sider { @@ -819,3 +823,7 @@ body { .ant-drawer .ant-drawer-mask.ant-drawer-mask-blur { backdrop-filter: blur(2px); } + +.ant-pro-grid-content { + padding-right: 8px; +} diff --git a/src/layouts/extraRender.tsx b/src/layouts/extraRender.tsx index 0dcb3829..001957f0 100644 --- a/src/layouts/extraRender.tsx +++ b/src/layouts/extraRender.tsx @@ -60,7 +60,7 @@ const Wrapper = styled.div` display: flex; align-items: center; gap: 24px; - height: 40px; + height: 32px; `; const DropdownWrapper = styled.div` min-width: 160px; diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index ad8be339..db649467 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -215,10 +215,28 @@ export default (props: any) => { }, [matchedRoute]); useEffect(() => { - const body = document.querySelector('body'); - if (body) { - const ins = initialize(body); - window.__GPUSTACK_BODY_SCROLLER__ = ins; + const initializeScroller = () => { + // const body = document.querySelector('.ant-pro-grid-content-children'); + // if (body) { + // const ins = initialize(body); + // window.__GPUSTACK_BODY_SCROLLER__ = ins; + // return true; + // } + // return false; + return true; + }; + + // Try to initialize immediately + if (!initializeScroller()) { + // If element not found, retry with requestAnimationFrame + const rafId = requestAnimationFrame(() => { + if (!initializeScroller()) { + // If still not found, retry after a short delay + const timeoutId = setTimeout(initializeScroller, 100); + return () => clearTimeout(timeoutId); + } + }); + return () => cancelAnimationFrame(rafId); } }, [initialize]); @@ -312,6 +330,8 @@ export default (props: any) => { }); }; + console.log('userConfig==========title', userConfig.title); + return ( { { ) : ( - +
+ +
)} diff --git a/src/pages/_components/page-box.tsx b/src/pages/_components/page-box.tsx index f31900ca..2fd989ad 100644 --- a/src/pages/_components/page-box.tsx +++ b/src/pages/_components/page-box.tsx @@ -1,44 +1,67 @@ +import useOverlayScroller from '@/hooks/use-overlay-scroller'; import { PageContainer, + RouteContext, type PageContainerProps } from '@ant-design/pro-components'; -import styled from 'styled-components'; +import classNames from 'classnames'; +import { useContext, useEffect, useRef } from 'react'; +import pageBoxCss from './styles/page-box.less'; -const paddingInlinePageContainerContent = 32; +const paddingInlinePageContainerContent = 24; -const StyledPageContainer = styled(PageContainer)` - .ant-affix { - top: 0 !important; - height: auto; +export const PageContainerInner: React.FC< + PageContainerProps & { + leftContent?: React.ReactNode; + rightContent?: React.ReactNode; + styles?: { + containerWrapper?: React.CSSProperties; + }; } - .ant-page-header { - padding-block-end: 8px; - .ant-page-header-heading { - padding-block-start: 0; +> = ({ children, styles, title, leftContent, rightContent, ...rest }) => { + const { initialize: initialize } = useOverlayScroller({ + defer: false + }); + const pageContext = useContext(RouteContext); + const contentWrapperRef = useRef(null); + + useEffect(() => { + if (contentWrapperRef.current) { + const ins = initialize(contentWrapperRef.current); + window.__GPUSTACK_BODY_SCROLLER__ = ins; } - } - .ant-pro-page-container-warp-page-header { - padding-inline: ${paddingInlinePageContainerContent}px; - } - .ant-page-header-heading-title { - font-size: 16px; - } -`; + }, [initialize, contentWrapperRef]); -export const PageContainerInner: React.FC = ({ - children, - ...rest -}) => { return ( - - {children} - +
+ +
+
+ {leftContent || pageContext.title} +
+ {rightContent && ( +
{rightContent}
+ )} +
+
+ {children} +
+
+
); }; diff --git a/src/pages/_components/styles/page-box.less b/src/pages/_components/styles/page-box.less new file mode 100644 index 00000000..470aa966 --- /dev/null +++ b/src/pages/_components/styles/page-box.less @@ -0,0 +1,62 @@ +.containerWrapper { + :global { + .ant-affix { + top: 0 !important; + height: auto; + } + + .ant-page-header { + padding-block-end: 8px; + + .ant-page-header-heading { + padding-block-start: 0; + } + } + + .ant-page-header-heading-title { + font-size: 16px; + } + + .ant-pro-page-container-children-container { + height: calc(100vh - 56px); + display: flex; + flex-direction: column; + border: 1px solid rgb(237, 237, 237); + border-radius: 8px; + overflow: hidden; + background-color: var(--ant-color-bg-container); + padding: 0; + } + } + + .contentWrapper { + flex: 1; + overflow-y: auto; + padding-block: var(--layout-content-blockpadding); + padding-inline: var(--layout-content-inlinepadding); + } + + .title { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + padding-inline: var(--layout-content-inlinepadding); + font-size: 16px; + color: var(--ant-color-text); + font-weight: 600; + padding-block: 9px 8px; + height: 56px; + border-bottom: 1px solid var(--ant-color-split); + + .left { + display: flex; + align-items: center; + } + + .right { + display: flex; + align-items: center; + } + } +} diff --git a/src/pages/llmodels/index.tsx b/src/pages/llmodels/index.tsx index 378230fd..896359f0 100644 --- a/src/pages/llmodels/index.tsx +++ b/src/pages/llmodels/index.tsx @@ -46,34 +46,36 @@ const LLModels: React.FC = () => { setActiveKey(key); }); - const header = useMemo(() => { - return { - title: ( -
- - {intl.formatMessage({ id: 'menu.models.deployment' })} - - - }, - { - label: intl.formatMessage({ id: 'models.table.instanceView' }), - value: TabsValueMap.InstanceView, - icon: - } - ]} - size="middle" - className="m-l-24 font-600" - value={activeKey} - onChange={handleTabChange} - > -
- ) - }; + const title = useMemo(() => { + return ( +
+ + {intl.formatMessage({ id: 'menu.models.deployment' })} + + + }, + { + label: intl.formatMessage({ id: 'models.table.instanceView' }), + value: TabsValueMap.InstanceView, + icon: + } + ]} + value={activeKey} + onChange={handleTabChange} + > +
+ ); }, [activeKey, intl]); useEffect(() => { @@ -103,7 +105,7 @@ const LLModels: React.FC = () => { }, [activeKey]); return ( - + ( {text @@ -157,6 +157,7 @@ const useProviderColumns = (options: { title: intl.formatMessage({ id: 'models.table.vram.allocated' }), dataIndex: 'allocated_vram', sorter: tableSorter(6), + width: 160, render: (text, record) => ( {convertFileSize( diff --git a/src/pages/playground/chat/index.tsx b/src/pages/playground/chat/index.tsx index 406a9055..88e3cbe0 100644 --- a/src/pages/playground/chat/index.tsx +++ b/src/pages/playground/chat/index.tsx @@ -1,12 +1,11 @@ import breakpoints from '@/config/breakpoints'; import HotKeys from '@/config/hotkeys'; import useWindowResize from '@/hooks/use-window-resize'; -import { ExtraContent } from '@/layouts/extraRender'; import { modelCategoriesMap } from '@/pages/llmodels/config'; import { MessageOutlined, OneToOneOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { useMemoizedFn } from 'ahooks'; -import { Divider, Segmented, Tabs, TabsProps } from 'antd'; +import { Segmented, Tabs, TabsProps } from 'antd'; import classNames from 'classnames'; import _ from 'lodash'; import { useEffect, useMemo, useRef, useState } from 'react'; @@ -109,11 +108,11 @@ const Playground: React.FC = () => { fetchData(); }, []); - const header = useMemo(() => { - return { - title: ( + const title = useMemo(() => { + return ( +
- + {intl.formatMessage({ id: 'menu.playground.chat' })} { @@ -126,8 +125,14 @@ const Playground: React.FC = () => { > }
- ) - }; + +
+ ); }, [activeKey, optionsList, intl]); useHotkeys( @@ -148,25 +153,39 @@ const Playground: React.FC = () => { compare: activeKey === 'compare', chat: activeKey !== 'compare' })} - header={header} - extra={[ + styles={{ + containerWrapper: { + padding: 0 + } + }} + leftContent={ +
+ + {intl.formatMessage({ id: 'menu.playground.chat' })} + + { + setActiveKey(key)} + > + } +
+ } + rightContent={ , -
- {activeKey === 'chat' && ( - - )} -
, - - ]} + /> + } >
diff --git a/src/pages/playground/components/view-code-buttons.tsx b/src/pages/playground/components/view-code-buttons.tsx index 03c31cb8..dd82c13a 100644 --- a/src/pages/playground/components/view-code-buttons.tsx +++ b/src/pages/playground/components/view-code-buttons.tsx @@ -15,7 +15,7 @@ const ViewCodeButtons: React.FC<{ } return ( - +