refactor: page layout
This commit is contained in:
@@ -253,6 +253,10 @@
|
|||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-primary {
|
||||||
|
color: var(--ant-color-text);
|
||||||
|
}
|
||||||
|
|
||||||
.text-secondary {
|
.text-secondary {
|
||||||
color: var(--ant-color-text-secondary);
|
color: var(--ant-color-text-secondary);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,6 @@ export default function useChartConfig() {
|
|||||||
type: 'bar',
|
type: 'bar',
|
||||||
barMaxWidth: 20,
|
barMaxWidth: 20,
|
||||||
barMinWidth: 8,
|
barMinWidth: 8,
|
||||||
// stack: 'total',
|
|
||||||
barGap: '30%',
|
barGap: '30%',
|
||||||
barCategoryGap: '50%'
|
barCategoryGap: '50%'
|
||||||
};
|
};
|
||||||
@@ -154,7 +153,7 @@ export default function useChartConfig() {
|
|||||||
progress: {
|
progress: {
|
||||||
show: true,
|
show: true,
|
||||||
roundCap: false,
|
roundCap: false,
|
||||||
width: 10
|
width: 12
|
||||||
},
|
},
|
||||||
pointer: {
|
pointer: {
|
||||||
length: '80%',
|
length: '80%',
|
||||||
@@ -166,7 +165,7 @@ export default function useChartConfig() {
|
|||||||
axisLine: {
|
axisLine: {
|
||||||
roundCap: false,
|
roundCap: false,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
width: 10,
|
width: 12,
|
||||||
color: [
|
color: [
|
||||||
[0.5, 'rgba(84, 204, 152, 80%)'],
|
[0.5, 'rgba(84, 204, 152, 80%)'],
|
||||||
[0.8, 'rgba(250, 173, 20, 80%)'],
|
[0.8, 'rgba(250, 173, 20, 80%)'],
|
||||||
@@ -175,8 +174,8 @@ export default function useChartConfig() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
axisTick: {
|
axisTick: {
|
||||||
distance: -10,
|
distance: -11,
|
||||||
length: 5,
|
length: 6,
|
||||||
splitNumber: 5,
|
splitNumber: 5,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
width: 1.5,
|
width: 1.5,
|
||||||
@@ -209,13 +208,13 @@ export default function useChartConfig() {
|
|||||||
rich: {
|
rich: {
|
||||||
value: {
|
value: {
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: '600',
|
fontWeight: 500,
|
||||||
color: chartColorMap.titleColor
|
color: chartColorMap.titleColor
|
||||||
},
|
},
|
||||||
unit: {
|
unit: {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: chartColorMap.titleColor,
|
color: chartColorMap.titleColor,
|
||||||
fontWeight: '600',
|
fontWeight: 500,
|
||||||
padding: [0, 0, 0, 2]
|
padding: [0, 0, 0, 2]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ const GaugeChart: React.FC<Omit<ChartProps, 'seriesData' | 'xAxisData'>> = (
|
|||||||
} = useChartConfig();
|
} = useChartConfig();
|
||||||
const { value, height, width, labelFormatter, title, color, gaugeConfig } =
|
const { value, height, width, labelFormatter, title, color, gaugeConfig } =
|
||||||
props;
|
props;
|
||||||
|
const titleText = typeof title === 'string' ? title : title?.text;
|
||||||
|
|
||||||
if (!value && value !== 0) {
|
if (!value && value !== 0) {
|
||||||
return <EmptyData height={height} title={title}></EmptyData>;
|
return <EmptyData height={height} title={titleText}></EmptyData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const setDataOptions = () => {
|
const setDataOptions = () => {
|
||||||
@@ -41,14 +43,15 @@ const GaugeChart: React.FC<Omit<ChartProps, 'seriesData' | 'xAxisData'>> = (
|
|||||||
return {
|
return {
|
||||||
title: {
|
title: {
|
||||||
...titleConfig,
|
...titleConfig,
|
||||||
text: title,
|
text: titleText,
|
||||||
textStyle: {
|
textStyle: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: chartColorMap.colorSecondary,
|
color: chartColorMap.colorSecondary,
|
||||||
fontWeight: 400
|
fontWeight: 400
|
||||||
},
|
},
|
||||||
top: '0',
|
top: 10,
|
||||||
left: 'center'
|
left: 'center',
|
||||||
|
...(typeof title === 'object' ? title : {})
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
@@ -68,6 +71,10 @@ const GaugeChart: React.FC<Omit<ChartProps, 'seriesData' | 'xAxisData'>> = (
|
|||||||
},
|
},
|
||||||
detail: {
|
detail: {
|
||||||
...combineGaugeConfig.detail,
|
...combineGaugeConfig.detail,
|
||||||
|
borderColor: colorValue,
|
||||||
|
lineHeight: 20,
|
||||||
|
height: 18,
|
||||||
|
width: 50,
|
||||||
formatter: labelFormatter || gaugeItemConfig.detail.formatter
|
formatter: labelFormatter || gaugeItemConfig.detail.formatter
|
||||||
},
|
},
|
||||||
data: [{ value }]
|
data: [{ value }]
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export interface ChartProps {
|
|||||||
tooltipValueFormatter?: (val: any) => string;
|
tooltipValueFormatter?: (val: any) => string;
|
||||||
height: string | number;
|
height: string | number;
|
||||||
width?: string | number;
|
width?: string | number;
|
||||||
title?: string;
|
title?: string | TitleComponentOption;
|
||||||
titleOptions?: {
|
titleOptions?: {
|
||||||
[K in keyof TitleComponentOption]?: TitleComponentOption[K];
|
[K in keyof TitleComponentOption]?: TitleComponentOption[K];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { createFromIconfontCN } from '@ant-design/icons';
|
|||||||
// import './iconfont/iconfont.js';
|
// import './iconfont/iconfont.js';
|
||||||
|
|
||||||
const IconFont = createFromIconfontCN({
|
const IconFont = createFromIconfontCN({
|
||||||
scriptUrl: '//at.alicdn.com/t/c/font_4613488_ab78o2vlum.js'
|
scriptUrl: '//at.alicdn.com/t/c/font_4613488_nb1thiz3t9.js'
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IconFont;
|
export default IconFont;
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<PageTools
|
<PageTools
|
||||||
marginBottom={marginBottom}
|
marginBottom={marginBottom}
|
||||||
marginTop={marginTop}
|
marginTop={0}
|
||||||
left={
|
left={
|
||||||
<Space>
|
<Space>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export const HEADER_HEIGHT = 72;
|
export const HEADER_HEIGHT = 56;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -22,7 +22,7 @@ declare namespace Global {
|
|||||||
require_password_change: boolean;
|
require_password_change: boolean;
|
||||||
id: number;
|
id: number;
|
||||||
source: string;
|
source: string;
|
||||||
avatar_url?: string;
|
avatar: string;
|
||||||
}
|
}
|
||||||
type EmptyObject = Record<never, never>;
|
type EmptyObject = Record<never, never>;
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,12 @@ body {
|
|||||||
width: 0;
|
width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-pro-page-container-affix {
|
||||||
|
.ant-affix {
|
||||||
|
top: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.ant-modal-confirm-title {
|
.ant-modal-confirm-title {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,298 @@
|
|||||||
|
import { GPUStackVersionAtom, UpdateCheckAtom } from '@/atoms/user';
|
||||||
|
import DropDownActions from '@/components/drop-down-actions';
|
||||||
|
import IconFont from '@/components/icon-font';
|
||||||
|
import VersionInfo, { modalConfig } from '@/components/version-info';
|
||||||
|
import externalLinks from '@/constants/external-links';
|
||||||
|
import useBodyScroll from '@/hooks/use-body-scroll';
|
||||||
|
import { logout } from '@/pages/login/apis';
|
||||||
|
import { useModel } from '@@/plugin-model';
|
||||||
|
import {
|
||||||
|
DiscordOutlined,
|
||||||
|
GithubOutlined,
|
||||||
|
HomeOutlined,
|
||||||
|
InfoCircleOutlined,
|
||||||
|
LogoutOutlined,
|
||||||
|
ReadOutlined,
|
||||||
|
SettingOutlined
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import { history, useIntl, useNavigate } from '@umijs/max';
|
||||||
|
import { Avatar, Divider, Modal } from 'antd';
|
||||||
|
import { useAtom } from 'jotai';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const IconWrapper = styled.span`
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--ant-color-text-secondary);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
height: 40px;
|
||||||
|
`;
|
||||||
|
const DropdownWrapper = styled.div`
|
||||||
|
min-width: 160px;
|
||||||
|
box-shadow: var(--ant-box-shadow-secondary);
|
||||||
|
background-color: var(--ant-color-bg-elevated);
|
||||||
|
border-radius: var(--ant-border-radius-lg);
|
||||||
|
padding: var(--ant-padding-xs);
|
||||||
|
.ant-dropdown-menu {
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
a {
|
||||||
|
color: var(--ant-color-text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CustomItem = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
height: 32px;
|
||||||
|
justify-content: flex-start;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 var(--ant-padding-xs);
|
||||||
|
cursor: pointer;
|
||||||
|
&.user-info {
|
||||||
|
cursor: default;
|
||||||
|
justify-content: space-between;
|
||||||
|
.user-name {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:not(.user-info):hover {
|
||||||
|
background-color: var(--ant-control-item-bg-hover);
|
||||||
|
}
|
||||||
|
background-color: var(--ant-color-bg-elevated);
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ExtraContent = () => {
|
||||||
|
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
|
||||||
|
const [modal, contextHolder] = Modal.useModal();
|
||||||
|
const [version] = useAtom(GPUStackVersionAtom);
|
||||||
|
const [updateCheck] = useAtom(UpdateCheckAtom);
|
||||||
|
const intl = useIntl();
|
||||||
|
const initialInfo = useModel('@@initialState') || {
|
||||||
|
initialState: undefined,
|
||||||
|
loading: false,
|
||||||
|
setInitialState: null
|
||||||
|
};
|
||||||
|
|
||||||
|
const { initialState } = initialInfo;
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const loginPath = '/login';
|
||||||
|
|
||||||
|
const showUpgrade = useMemo(() => {
|
||||||
|
return (
|
||||||
|
initialState?.currentUser?.is_admin &&
|
||||||
|
updateCheck.latest_version &&
|
||||||
|
updateCheck.latest_version !== version?.version &&
|
||||||
|
updateCheck.latest_version?.indexOf('0.0.0') === -1 &&
|
||||||
|
updateCheck.latest_version?.indexOf('rc') === -1
|
||||||
|
);
|
||||||
|
}, [
|
||||||
|
updateCheck.latest_version,
|
||||||
|
version.version,
|
||||||
|
initialState?.currentUser?.is_admin
|
||||||
|
]);
|
||||||
|
|
||||||
|
const showVersion = () => {
|
||||||
|
saveScrollHeight();
|
||||||
|
modal.info({
|
||||||
|
...modalConfig,
|
||||||
|
width: 460,
|
||||||
|
content: <VersionInfo intl={intl} />,
|
||||||
|
onCancel: restoreScrollHeight
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLogout = async () => {
|
||||||
|
await logout();
|
||||||
|
navigate(loginPath);
|
||||||
|
};
|
||||||
|
|
||||||
|
const helpList = [
|
||||||
|
{
|
||||||
|
key: 'site',
|
||||||
|
icon: <HomeOutlined />,
|
||||||
|
label: 'GPUStack',
|
||||||
|
url: externalLinks.site
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'github',
|
||||||
|
icon: <GithubOutlined />,
|
||||||
|
label: intl.formatMessage({ id: 'common.issue.report' }),
|
||||||
|
url: externalLinks.reportIssue
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'faq',
|
||||||
|
icon: <IconFont type="icon-fankuifaqs"></IconFont>,
|
||||||
|
label: intl.formatMessage({ id: 'common.button.faq' }),
|
||||||
|
url: externalLinks.faq
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'Discord',
|
||||||
|
icon: <DiscordOutlined />,
|
||||||
|
label: 'Discord',
|
||||||
|
url: externalLinks.discord
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'docs',
|
||||||
|
icon: <ReadOutlined />,
|
||||||
|
label: intl.formatMessage({ id: 'common.button.docs' }),
|
||||||
|
url: externalLinks.documentation
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'version',
|
||||||
|
icon: <InfoCircleOutlined />,
|
||||||
|
label: intl.formatMessage({ id: 'common.button.version' })
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const helpMenu = {
|
||||||
|
items: helpList.map((item) => ({
|
||||||
|
key: item.key,
|
||||||
|
label: (
|
||||||
|
<span className="flex flex-center">
|
||||||
|
{item.icon}
|
||||||
|
{item.key === 'version' ? (
|
||||||
|
<>
|
||||||
|
<a className="m-l-8">{item.label}</a>
|
||||||
|
{showUpgrade && (
|
||||||
|
<span className="new-icon">
|
||||||
|
<span className="text">
|
||||||
|
{intl.formatMessage({ id: 'common.text.new' })}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<a
|
||||||
|
className="m-l-8 "
|
||||||
|
href={item.url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
onClick() {
|
||||||
|
if (item.key === 'version') {
|
||||||
|
showVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
|
||||||
|
const userMenu = {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
key: 'apikeys',
|
||||||
|
label: (
|
||||||
|
<span className="flex flex-center">
|
||||||
|
<IconFont type="icon-key" />
|
||||||
|
<span className="m-l-8" style={{ marginLeft: 8 }}>
|
||||||
|
{intl?.formatMessage?.({ id: 'menu.apikeys' })}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
onClick: () => {
|
||||||
|
history.push('/api-keys');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'settings',
|
||||||
|
label: (
|
||||||
|
<span className="flex flex-center">
|
||||||
|
<SettingOutlined />
|
||||||
|
<span className="m-l-8" style={{ marginLeft: 8 }}>
|
||||||
|
{intl?.formatMessage?.({ id: 'common.button.settings' })}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
onClick: () => {
|
||||||
|
history.push('/profile');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const userPopupRender = (originNode: React.ReactNode) => {
|
||||||
|
return (
|
||||||
|
<DropdownWrapper>
|
||||||
|
<CustomItem className="user-info border-bottom">
|
||||||
|
<span className="flex-center gap-8">
|
||||||
|
<Avatar
|
||||||
|
size={24}
|
||||||
|
src={initialState?.currentUser?.avatar}
|
||||||
|
icon={
|
||||||
|
<IconFont type="icon-user-filled" className="font-size-24" />
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<span className="user-name">
|
||||||
|
{initialState?.currentUser?.username}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</CustomItem>
|
||||||
|
<Divider style={{ marginBlock: 4 }} />
|
||||||
|
{originNode}
|
||||||
|
<Divider style={{ marginBlock: 4 }} />
|
||||||
|
<CustomItem onClick={handleLogout} className="border-top">
|
||||||
|
<LogoutOutlined />
|
||||||
|
<span>{intl?.formatMessage?.({ id: 'common.button.logout' })}</span>
|
||||||
|
</CustomItem>
|
||||||
|
</DropdownWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const helpPopupRender = (originNode: React.ReactNode) => {
|
||||||
|
return <DropdownWrapper>{originNode}</DropdownWrapper>;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
{contextHolder}
|
||||||
|
<DropDownActions menu={{ ...helpMenu }} popupRender={helpPopupRender}>
|
||||||
|
<IconWrapper>
|
||||||
|
<IconFont type="icon-help" className="font-size-20" />
|
||||||
|
{showUpgrade && (
|
||||||
|
<span
|
||||||
|
className="m-l-5"
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
width: 8,
|
||||||
|
height: 8,
|
||||||
|
borderRadius: 4,
|
||||||
|
backgroundColor: 'var(--ant-orange-5)'
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
)}
|
||||||
|
</IconWrapper>
|
||||||
|
</DropDownActions>
|
||||||
|
<DropDownActions menu={{ ...userMenu }} popupRender={userPopupRender}>
|
||||||
|
<IconWrapper>
|
||||||
|
<Avatar
|
||||||
|
size={24}
|
||||||
|
src={initialState?.currentUser?.avatar}
|
||||||
|
icon={<IconFont type="icon-user-filled" className="font-size-24" />}
|
||||||
|
/>
|
||||||
|
</IconWrapper>
|
||||||
|
</DropDownActions>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
+33
-32
@@ -33,14 +33,26 @@ import 'driver.js/dist/driver.css';
|
|||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import 'overlayscrollbars/overlayscrollbars.css';
|
import 'overlayscrollbars/overlayscrollbars.css';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
import { PageContainerInner } from '../pages/_components/page-box';
|
||||||
import Exception from './Exception';
|
import Exception from './Exception';
|
||||||
import './Layout.css';
|
import './Layout.css';
|
||||||
import { LogoIcon, SLogoIcon } from './Logo';
|
import { LogoIcon, SLogoIcon } from './Logo';
|
||||||
import ErrorBoundary from './error-boundary';
|
import ErrorBoundary from './error-boundary';
|
||||||
|
import { ExtraContent } from './extraRender';
|
||||||
import { getRightRenderContent } from './rightRender';
|
import { getRightRenderContent } from './rightRender';
|
||||||
import { patchRoutes } from './runtime';
|
import { patchRoutes } from './runtime';
|
||||||
import SiderMenu from './sider-menu';
|
import SiderMenu from './sider-menu';
|
||||||
|
|
||||||
|
const NO_CONTAINER_PAGES = [
|
||||||
|
'chat',
|
||||||
|
'rerank',
|
||||||
|
'embedding',
|
||||||
|
'speech',
|
||||||
|
'image',
|
||||||
|
'clusterDetail',
|
||||||
|
'clusterCreate'
|
||||||
|
];
|
||||||
|
|
||||||
const loginPath = '/login';
|
const loginPath = '/login';
|
||||||
|
|
||||||
type InitialStateType = {
|
type InitialStateType = {
|
||||||
@@ -205,8 +217,6 @@ export default (props: any) => {
|
|||||||
const role = initialState?.currentUser?.is_admin ? 'admin' : 'user';
|
const role = initialState?.currentUser?.is_admin ? 'admin' : 'user';
|
||||||
const [route] = useAccessMarkedRoutes(mapRoutes(newRoutes, role));
|
const [route] = useAccessMarkedRoutes(mapRoutes(newRoutes, role));
|
||||||
|
|
||||||
console.log('route============', route);
|
|
||||||
|
|
||||||
patchRoutes({
|
patchRoutes({
|
||||||
routes: route.children,
|
routes: route.children,
|
||||||
initialState: initialInfo.initialState
|
initialState: initialInfo.initialState
|
||||||
@@ -217,6 +227,12 @@ export default (props: any) => {
|
|||||||
[location.pathname]
|
[location.pathname]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isNoContainerPage = useMemo(() => {
|
||||||
|
return NO_CONTAINER_PAGES.includes(matchedRoute?.name);
|
||||||
|
}, [matchedRoute]);
|
||||||
|
|
||||||
|
console.log('matchedRoute=========', matchedRoute, route);
|
||||||
|
|
||||||
const allRouteKeys = useMemo(() => {
|
const allRouteKeys = useMemo(() => {
|
||||||
const keys = new Set<string>();
|
const keys = new Set<string>();
|
||||||
const childrenRoutes = route?.children || [];
|
const childrenRoutes = route?.children || [];
|
||||||
@@ -257,27 +273,6 @@ export default (props: any) => {
|
|||||||
}
|
}
|
||||||
}, [initialize]);
|
}, [initialize]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const checkAndInitialize = () => {
|
|
||||||
const menuWrap = window.document.querySelector(
|
|
||||||
'.ant-menu.ant-menu-root'
|
|
||||||
)?.parentElement;
|
|
||||||
if (menuWrap) {
|
|
||||||
try {
|
|
||||||
initializeMenu(menuWrap);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to initialize menu:', error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.warn('Menu wrapper not found.');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const timeout = setTimeout(checkAndInitialize, 500);
|
|
||||||
|
|
||||||
return () => clearTimeout(timeout);
|
|
||||||
}, [initializeMenu, matchedRoute, location]);
|
|
||||||
|
|
||||||
const collapsed = useMemo(() => {
|
const collapsed = useMemo(() => {
|
||||||
return userSettings.collapsed || false;
|
return userSettings.collapsed || false;
|
||||||
}, [userSettings.collapsed]);
|
}, [userSettings.collapsed]);
|
||||||
@@ -326,7 +321,6 @@ export default (props: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const actionRender = (layoutProps) => {
|
const actionRender = (layoutProps) => {
|
||||||
console.log('actionRender', layoutProps);
|
|
||||||
const dom = getRightRenderContent({
|
const dom = getRightRenderContent({
|
||||||
runtimeConfig,
|
runtimeConfig,
|
||||||
loading,
|
loading,
|
||||||
@@ -334,8 +328,8 @@ export default (props: any) => {
|
|||||||
setInitialState,
|
setInitialState,
|
||||||
intl,
|
intl,
|
||||||
isDarkTheme: userSettings.isDarkTheme,
|
isDarkTheme: userSettings.isDarkTheme,
|
||||||
siderWidth: layoutProps.siderWidth,
|
siderWidth: layoutProps?.siderWidth,
|
||||||
collapsed: layoutProps.collapsed,
|
collapsed: layoutProps?.collapsed,
|
||||||
showUpgrade
|
showUpgrade
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -479,6 +473,12 @@ export default (props: any) => {
|
|||||||
return data;
|
return data;
|
||||||
}, [userSettings.isDarkTheme, themeData]);
|
}, [userSettings.isDarkTheme, themeData]);
|
||||||
|
|
||||||
|
const outlet = runtimeConfig.childrenRender ? (
|
||||||
|
runtimeConfig.childrenRender(<Outlet />, props)
|
||||||
|
) : (
|
||||||
|
<Outlet />
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigProvider
|
<ConfigProvider
|
||||||
componentSize="large"
|
componentSize="large"
|
||||||
@@ -492,6 +492,9 @@ export default (props: any) => {
|
|||||||
>
|
>
|
||||||
<DarkMask></DarkMask>
|
<DarkMask></DarkMask>
|
||||||
<ProLayout
|
<ProLayout
|
||||||
|
fixSiderbar
|
||||||
|
fixedHeader
|
||||||
|
breadcrumbRender={false}
|
||||||
route={route}
|
route={route}
|
||||||
location={location}
|
location={location}
|
||||||
title={userConfig.title}
|
title={userConfig.title}
|
||||||
@@ -510,6 +513,7 @@ export default (props: any) => {
|
|||||||
onCollapse={onCollapse}
|
onCollapse={onCollapse}
|
||||||
onMenuHeaderClick={onMenuHeaderClick}
|
onMenuHeaderClick={onMenuHeaderClick}
|
||||||
menuHeaderRender={renderMenuHeader}
|
menuHeaderRender={renderMenuHeader}
|
||||||
|
extra={[<ExtraContent key="extra-content" />]}
|
||||||
collapsed={userSettings.collapsed}
|
collapsed={userSettings.collapsed}
|
||||||
onPageChange={onPageChange}
|
onPageChange={onPageChange}
|
||||||
formatMessage={formatMessage}
|
formatMessage={formatMessage}
|
||||||
@@ -521,10 +525,7 @@ export default (props: any) => {
|
|||||||
logo={collapsed ? SLogoIcon : LogoIcon}
|
logo={collapsed ? SLogoIcon : LogoIcon}
|
||||||
menuContentRender={menuContentRender}
|
menuContentRender={menuContentRender}
|
||||||
disableContentMargin
|
disableContentMargin
|
||||||
fixSiderbar
|
|
||||||
fixedHeader
|
|
||||||
{...runtimeConfig}
|
{...runtimeConfig}
|
||||||
actionsRender={actionRender}
|
|
||||||
ErrorBoundary={ErrorBoundary}
|
ErrorBoundary={ErrorBoundary}
|
||||||
>
|
>
|
||||||
<Exception
|
<Exception
|
||||||
@@ -534,10 +535,10 @@ export default (props: any) => {
|
|||||||
unAccessible={runtimeConfig?.unAccessible}
|
unAccessible={runtimeConfig?.unAccessible}
|
||||||
noAccessible={runtimeConfig?.noAccessible}
|
noAccessible={runtimeConfig?.noAccessible}
|
||||||
>
|
>
|
||||||
{runtimeConfig.childrenRender ? (
|
{isNoContainerPage ? (
|
||||||
runtimeConfig.childrenRender(<Outlet />, props)
|
outlet
|
||||||
) : (
|
) : (
|
||||||
<Outlet />
|
<PageContainerInner>{outlet}</PageContainerInner>
|
||||||
)}
|
)}
|
||||||
</Exception>
|
</Exception>
|
||||||
</ProLayout>
|
</ProLayout>
|
||||||
|
|||||||
@@ -280,14 +280,8 @@ export const getRightRenderContent = (opts: {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Menu {...helpMenu} style={getMenuStyle(collapsed, siderWidth)} />
|
<Menu {...helpMenu} mode="vertical" />
|
||||||
<Menu
|
<Menu {...userMenu} mode="vertical" />
|
||||||
{...userMenu}
|
|
||||||
style={getMenuStyle(collapsed, siderWidth, {
|
|
||||||
marginTop: 8,
|
|
||||||
marginBottom: 0
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import {
|
||||||
|
PageContainer,
|
||||||
|
type PageContainerProps
|
||||||
|
} from '@ant-design/pro-components';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const paddingInlinePageContainerContent = 32;
|
||||||
|
|
||||||
|
const StyledPageContainer = styled(PageContainer)`
|
||||||
|
.ant-affix {
|
||||||
|
top: 0 !important;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.ant-page-header {
|
||||||
|
padding-block-end: 8px;
|
||||||
|
.ant-page-header-heading {
|
||||||
|
padding-block-start: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ant-pro-page-container-warp-page-header {
|
||||||
|
padding-inline: ${paddingInlinePageContainerContent}px;
|
||||||
|
}
|
||||||
|
.ant-page-header-heading-title {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const PageContainerInner: React.FC<PageContainerProps> = ({
|
||||||
|
children,
|
||||||
|
...rest
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<StyledPageContainer
|
||||||
|
{...rest}
|
||||||
|
fixedHeader
|
||||||
|
token={{
|
||||||
|
paddingInlinePageContainerContent: paddingInlinePageContainerContent
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</StyledPageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PageBox: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||||
|
return <div>{children}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PageBox;
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import IconFont from '@/components/icon-font';
|
||||||
|
import { Breadcrumb, type BreadcrumbProps } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledBreadcrumb = styled(Breadcrumb)`
|
||||||
|
.ant-breadcrumb-link {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
a {
|
||||||
|
background: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ant-breadcrumb-separator {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const App: React.FC<BreadcrumbProps> = ({ items }) => (
|
||||||
|
<StyledBreadcrumb
|
||||||
|
separator={<IconFont type="icon-down2" rotate={-90} />}
|
||||||
|
items={items}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default App;
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { PageContainerProps } from '@ant-design/pro-components';
|
||||||
|
import { createContext, useContext } from 'react';
|
||||||
|
|
||||||
|
interface PageContainerContextProps extends Partial<PageContainerProps> {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PageContainerContext = createContext<PageContainerContextProps>(
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
export function usePageContainerContext() {
|
||||||
|
const context = useContext(PageContainerContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error(
|
||||||
|
'usePageContainerContext must be used within a PageContainerProvider'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
@@ -4,12 +4,12 @@ import { FilterBar } from '@/components/page-tools';
|
|||||||
import { PageAction } from '@/config';
|
import { PageAction } from '@/config';
|
||||||
import type { PageActionType } from '@/config/types';
|
import type { PageActionType } from '@/config/types';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
||||||
import { Button, ConfigProvider, Table } from 'antd';
|
import { Button, ConfigProvider, Table } from 'antd';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import NoResult from '../_components/no-result';
|
import NoResult from '../_components/no-result';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import { deleteApisKey, queryApisKeysList } from './apis';
|
import { deleteApisKey, queryApisKeysList } from './apis';
|
||||||
import AddAPIKeyModal from './components/add-apikey-modal';
|
import AddAPIKeyModal from './components/add-apikey-modal';
|
||||||
import { ListItem } from './config/types';
|
import { ListItem } from './config/types';
|
||||||
@@ -123,17 +123,7 @@ const APIKeys: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'apikeys.title' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<FilterBar
|
<FilterBar
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
marginTop={30}
|
marginTop={30}
|
||||||
@@ -163,7 +153,7 @@ const APIKeys: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
></Table>
|
></Table>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
<AddAPIKeyModal
|
<AddAPIKeyModal
|
||||||
open={openAddModal.open}
|
open={openAddModal.open}
|
||||||
action={openAddModal.action}
|
action={openAddModal.action}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import IconFont from '@/components/icon-font';
|
|||||||
import { FilterBar } from '@/components/page-tools';
|
import { FilterBar } from '@/components/page-tools';
|
||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
@@ -11,6 +10,7 @@ import _ from 'lodash';
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ScrollerContext } from '../_components/infinite-scroller/use-scroller-context';
|
import { ScrollerContext } from '../_components/infinite-scroller/use-scroller-context';
|
||||||
import NoResult from '../_components/no-result';
|
import NoResult from '../_components/no-result';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import {
|
import {
|
||||||
createBackend,
|
createBackend,
|
||||||
createBackendFromYAML,
|
createBackendFromYAML,
|
||||||
@@ -170,17 +170,7 @@ const BackendList = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'menu.resources.backendsList' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<FilterBar
|
<FilterBar
|
||||||
showDeleteButton={false}
|
showDeleteButton={false}
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
@@ -255,7 +245,7 @@ const BackendList = () => {
|
|||||||
}
|
}
|
||||||
></VersionInfoModal>
|
></VersionInfoModal>
|
||||||
<DeleteModal ref={modalRef}></DeleteModal>
|
<DeleteModal ref={modalRef}></DeleteModal>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import { PageAction } from '@/config';
|
import { PageAction } from '@/config';
|
||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
import PageBreadcrumb from '@/pages/_components/page-breadcrumb';
|
||||||
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
|
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { PageContainerInner } from '../_components/page-box';
|
||||||
import { createCluster, queryClusterToken, queryCredentialList } from './apis';
|
import { createCluster, queryClusterToken, queryCredentialList } from './apis';
|
||||||
import ClusterSteps from './components/cluster-steps';
|
import ClusterSteps from './components/cluster-steps';
|
||||||
import FooterButtons from './components/footer-buttons';
|
import FooterButtons from './components/footer-buttons';
|
||||||
@@ -25,7 +26,6 @@ const Container = styled.div`
|
|||||||
const Nav = styled.div`
|
const Nav = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 72px;
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: var(--ant-color-text-tertiary);
|
color: var(--ant-color-text-tertiary);
|
||||||
@@ -280,9 +280,18 @@ const ClusterCreate = () => {
|
|||||||
navigate(-1);
|
navigate(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const breadcrumbItems = [
|
||||||
|
{
|
||||||
|
title: <a>{intl.formatMessage({ id: 'clusters.title' })}</a>,
|
||||||
|
onClick: () => navigate(-1)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: intl.formatMessage({ id: 'common.button.create' })
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainerInner
|
||||||
ghost
|
|
||||||
footer={[
|
footer={[
|
||||||
<FooterButtons
|
<FooterButtons
|
||||||
key="buttons"
|
key="buttons"
|
||||||
@@ -294,38 +303,14 @@ const ClusterCreate = () => {
|
|||||||
/>
|
/>
|
||||||
]}
|
]}
|
||||||
header={{
|
header={{
|
||||||
title: false,
|
title: <PageBreadcrumb items={breadcrumbItems} />
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
}}
|
||||||
pageHeaderRender={() => (
|
|
||||||
<HeaderContainer>
|
|
||||||
<Nav>
|
|
||||||
<span className="level-1">
|
|
||||||
{intl.formatMessage({ id: 'clusters.title' })}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
marginInline: 20,
|
|
||||||
color: 'var(--ant-color-split)'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
/
|
|
||||||
</span>
|
|
||||||
<span className="level-2">
|
|
||||||
{intl.formatMessage({ id: 'common.button.create' })}
|
|
||||||
</span>
|
|
||||||
</Nav>
|
|
||||||
<ClusterSteps
|
|
||||||
steps={steps}
|
|
||||||
currentStep={currentStep}
|
|
||||||
onChange={handleStepChange}
|
|
||||||
></ClusterSteps>
|
|
||||||
</HeaderContainer>
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
|
<ClusterSteps
|
||||||
|
steps={steps}
|
||||||
|
currentStep={currentStep}
|
||||||
|
onChange={handleStepChange}
|
||||||
|
></ClusterSteps>
|
||||||
{currentStep === startStep && (
|
{currentStep === startStep && (
|
||||||
<ProviderCatalog
|
<ProviderCatalog
|
||||||
dataList={providerList}
|
dataList={providerList}
|
||||||
@@ -339,7 +324,7 @@ const ClusterCreate = () => {
|
|||||||
<Container>
|
<Container>
|
||||||
<Content>{renderForms()}</Content>
|
<Content>{renderForms()}</Content>
|
||||||
</Container>
|
</Container>
|
||||||
</PageContainer>
|
</PageContainerInner>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,33 @@
|
|||||||
import { PageContainer } from '@ant-design/pro-components';
|
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
|
||||||
import { useSearchParams } from '@umijs/max';
|
import { PageContainerInner } from '../_components/page-box';
|
||||||
|
import PageBreadcrumb from '../_components/page-breadcrumb';
|
||||||
import ClusterMetrics from './components/cluster-metrics';
|
import ClusterMetrics from './components/cluster-metrics';
|
||||||
|
|
||||||
const ClusterDetailModal = () => {
|
const ClusterDetailModal = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const intl = useIntl();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const provider = searchParams.get('provider');
|
const provider = searchParams.get('provider');
|
||||||
const clusterName = searchParams.get('name');
|
const clusterName = searchParams.get('name');
|
||||||
|
|
||||||
|
const breadcrumbItems = [
|
||||||
|
{
|
||||||
|
title: <a>{intl.formatMessage({ id: 'clusters.title' })}</a>,
|
||||||
|
onClick: () => navigate(-1)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: clusterName
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainerInner
|
||||||
ghost
|
|
||||||
header={{
|
header={{
|
||||||
title: (
|
title: <PageBreadcrumb items={breadcrumbItems} />
|
||||||
<span className="flex-center">
|
|
||||||
<span>{clusterName}</span>
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
}}
|
||||||
extra={[]}
|
|
||||||
>
|
>
|
||||||
<ClusterMetrics />
|
<ClusterMetrics />
|
||||||
{/* {provider === ProviderValueMap.DigitalOcean && <WorkerPools />} */}
|
</PageContainerInner>
|
||||||
</PageContainer>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ import useExpandedRowKeys from '@/hooks/use-expanded-row-keys';
|
|||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import useWatchList from '@/hooks/use-watch-list';
|
import useWatchList from '@/hooks/use-watch-list';
|
||||||
import AddWorker from '@/pages/cluster-management/components/add-worker';
|
import AddWorker from '@/pages/cluster-management/components/add-worker';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
|
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Button, message } from 'antd';
|
import { Button, message } from 'antd';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import NoResult from '../_components/no-result';
|
import NoResult from '../_components/no-result';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import {
|
import {
|
||||||
CLUSTERS_API,
|
CLUSTERS_API,
|
||||||
createWorkerPool,
|
createWorkerPool,
|
||||||
@@ -327,19 +327,7 @@ const Clusters: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({
|
|
||||||
id: 'menu.clusterManagement.clusters'
|
|
||||||
}),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<FilterBar
|
<FilterBar
|
||||||
showSelect={false}
|
showSelect={false}
|
||||||
showPrimaryButton={true}
|
showPrimaryButton={true}
|
||||||
@@ -404,7 +392,7 @@ const Clusters: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
></SealTable>
|
></SealTable>
|
||||||
</TableContext.Provider>
|
</TableContext.Provider>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
<AddCluster
|
<AddCluster
|
||||||
provider={openAddModal.provider}
|
provider={openAddModal.provider}
|
||||||
open={openAddModal.open}
|
open={openAddModal.open}
|
||||||
|
|||||||
@@ -53,6 +53,15 @@ interface ClusterDetailProps {
|
|||||||
data: ClusterListItem | null;
|
data: ClusterListItem | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const titleConfig = {
|
||||||
|
textStyle: {
|
||||||
|
color: '#000',
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: 600
|
||||||
|
},
|
||||||
|
top: -5
|
||||||
|
};
|
||||||
|
|
||||||
const gaugeConfig = {
|
const gaugeConfig = {
|
||||||
radius: '100%',
|
radius: '100%',
|
||||||
progress: {
|
progress: {
|
||||||
@@ -140,7 +149,10 @@ const ClusterMetrics = () => {
|
|||||||
<Row gutter={16} style={{ width: '100%' }}>
|
<Row gutter={16} style={{ width: '100%' }}>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
<GaugeChart
|
<GaugeChart
|
||||||
title="GPU Utilization"
|
title={{
|
||||||
|
text: 'GPU Utilization',
|
||||||
|
...titleConfig
|
||||||
|
}}
|
||||||
value={formatValue(detailContent.current.gpu)}
|
value={formatValue(detailContent.current.gpu)}
|
||||||
height={chartHeight}
|
height={chartHeight}
|
||||||
gaugeConfig={gaugeConfig}
|
gaugeConfig={gaugeConfig}
|
||||||
@@ -148,7 +160,10 @@ const ClusterMetrics = () => {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
<GaugeChart
|
<GaugeChart
|
||||||
title="CPU Utilization"
|
title={{
|
||||||
|
text: 'CPU Utilization',
|
||||||
|
...titleConfig
|
||||||
|
}}
|
||||||
value={formatValue(detailContent.current.cpu)}
|
value={formatValue(detailContent.current.cpu)}
|
||||||
height={chartHeight}
|
height={chartHeight}
|
||||||
gaugeConfig={gaugeConfig}
|
gaugeConfig={gaugeConfig}
|
||||||
@@ -156,7 +171,10 @@ const ClusterMetrics = () => {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
<GaugeChart
|
<GaugeChart
|
||||||
title="RAM Utilization"
|
title={{
|
||||||
|
text: 'RAM Utilization',
|
||||||
|
...titleConfig
|
||||||
|
}}
|
||||||
value={formatValue(detailContent.current.ram)}
|
value={formatValue(detailContent.current.ram)}
|
||||||
height={chartHeight}
|
height={chartHeight}
|
||||||
gaugeConfig={gaugeConfig}
|
gaugeConfig={gaugeConfig}
|
||||||
@@ -164,7 +182,10 @@ const ClusterMetrics = () => {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
<GaugeChart
|
<GaugeChart
|
||||||
title="VRAM Utilization"
|
title={{
|
||||||
|
text: 'VRAM Utilization',
|
||||||
|
...titleConfig
|
||||||
|
}}
|
||||||
value={formatValue(detailContent.current.vram)}
|
value={formatValue(detailContent.current.vram)}
|
||||||
height={chartHeight}
|
height={chartHeight}
|
||||||
gaugeConfig={gaugeConfig}
|
gaugeConfig={gaugeConfig}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import { FilterBar } from '@/components/page-tools';
|
|||||||
import { PageAction } from '@/config';
|
import { PageAction } from '@/config';
|
||||||
import type { PageActionType } from '@/config/types';
|
import type { PageActionType } from '@/config/types';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Button, ConfigProvider, Table, message } from 'antd';
|
import { Button, ConfigProvider, Table, message } from 'antd';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import NoResult from '../_components/no-result';
|
import NoResult from '../_components/no-result';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import {
|
import {
|
||||||
createCredential,
|
createCredential,
|
||||||
deleteCredential,
|
deleteCredential,
|
||||||
@@ -178,26 +178,14 @@ const Credentials: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({
|
|
||||||
id: 'menu.clusterManagement.credentials'
|
|
||||||
}),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<FilterBar
|
<FilterBar
|
||||||
actionItems={addActions}
|
actionItems={addActions}
|
||||||
actionType="dropdown"
|
actionType="dropdown"
|
||||||
showSelect={false}
|
showSelect={false}
|
||||||
showPrimaryButton={true}
|
showPrimaryButton={true}
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
marginTop={30}
|
marginTop={0}
|
||||||
buttonText={intl.formatMessage({
|
buttonText={intl.formatMessage({
|
||||||
id: 'clusters.button.addCredential'
|
id: 'clusters.button.addCredential'
|
||||||
})}
|
})}
|
||||||
@@ -228,7 +216,7 @@ const Credentials: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
></Table>
|
></Table>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
<AddModal
|
<AddModal
|
||||||
provider={openModalStatus.provider}
|
provider={openModalStatus.provider}
|
||||||
open={openModalStatus.open}
|
open={openModalStatus.open}
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ const SystemLoad = () => {
|
|||||||
<Row style={{ height: largeChartHeight }}>
|
<Row style={{ height: largeChartHeight }}>
|
||||||
<Col span={12} style={{ height: smallChartHeight }}>
|
<Col span={12} style={{ height: smallChartHeight }}>
|
||||||
<GaugeChart
|
<GaugeChart
|
||||||
|
name="GPU"
|
||||||
height={smallChartHeight}
|
height={smallChartHeight}
|
||||||
value={chartData.gpu.data}
|
value={chartData.gpu.data}
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
@@ -64,6 +65,7 @@ const SystemLoad = () => {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={12} style={{ height: smallChartHeight }}>
|
<Col span={12} style={{ height: smallChartHeight }}>
|
||||||
<GaugeChart
|
<GaugeChart
|
||||||
|
name="VRAM"
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id: 'dashboard.vramutilization'
|
id: 'dashboard.vramutilization'
|
||||||
})}
|
})}
|
||||||
@@ -73,6 +75,7 @@ const SystemLoad = () => {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={12} style={{ height: smallChartHeight }}>
|
<Col span={12} style={{ height: smallChartHeight }}>
|
||||||
<GaugeChart
|
<GaugeChart
|
||||||
|
name="CPU"
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id: 'dashboard.cpuutilization'
|
id: 'dashboard.cpuutilization'
|
||||||
})}
|
})}
|
||||||
@@ -82,6 +85,7 @@ const SystemLoad = () => {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={12} style={{ height: smallChartHeight }}>
|
<Col span={12} style={{ height: smallChartHeight }}>
|
||||||
<GaugeChart
|
<GaugeChart
|
||||||
|
name="RAM"
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id: 'dashboard.memoryutilization'
|
id: 'dashboard.memoryutilization'
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { Spin } from 'antd';
|
import { Spin } from 'antd';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import DashboardInner from './components/dahboard-inner';
|
import DashboardInner from './components/dahboard-inner';
|
||||||
|
|
||||||
const Dashboard: React.FC = () => {
|
const Dashboard: React.FC = () => {
|
||||||
@@ -8,19 +8,11 @@ const Dashboard: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
extra={[]}
|
|
||||||
header={{
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Spin spinning={loading}>
|
<Spin spinning={loading}>
|
||||||
<DashboardInner setLoading={setLoading} />
|
<DashboardInner setLoading={setLoading} />
|
||||||
</Spin>
|
</Spin>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import useBodyScroll from '@/hooks/use-body-scroll';
|
|||||||
import { ScrollerContext } from '@/pages/_components/infinite-scroller/use-scroller-context';
|
import { ScrollerContext } from '@/pages/_components/infinite-scroller/use-scroller-context';
|
||||||
import { IS_FIRST_LOGIN, writeState } from '@/utils/localstore/index';
|
import { IS_FIRST_LOGIN, writeState } from '@/utils/localstore/index';
|
||||||
import { SearchOutlined, SyncOutlined } from '@ant-design/icons';
|
import { SearchOutlined, SyncOutlined } from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Button, Input, Space, message } from 'antd';
|
import { Button, Input, Space, message } from 'antd';
|
||||||
@@ -16,6 +15,7 @@ import _ from 'lodash';
|
|||||||
import React, { useCallback, useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import NoResult from '../_components/no-result';
|
import NoResult from '../_components/no-result';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import { createModel, queryCatalogList } from './apis';
|
import { createModel, queryCatalogList } from './apis';
|
||||||
import CatalogList from './components/catalog-list';
|
import CatalogList from './components/catalog-list';
|
||||||
import DelopyBuiltInModal from './components/deploy-builtin-modal';
|
import DelopyBuiltInModal from './components/deploy-builtin-modal';
|
||||||
@@ -219,19 +219,10 @@ const Catalog: React.FC = () => {
|
|||||||
}, [fetchData]);
|
}, [fetchData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'menu.modelCatalog' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<PageTools
|
<PageTools
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
|
marginTop={0}
|
||||||
left={
|
left={
|
||||||
<Space>
|
<Space>
|
||||||
<Input
|
<Input
|
||||||
@@ -311,7 +302,7 @@ const Catalog: React.FC = () => {
|
|||||||
onCancel={handleDeployModalCancel}
|
onCancel={handleDeployModalCancel}
|
||||||
onOk={handleCreateModel}
|
onOk={handleCreateModel}
|
||||||
></DelopyBuiltInModal>
|
></DelopyBuiltInModal>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ import useExpandedRowKeys from '@/hooks/use-expanded-row-keys';
|
|||||||
import useTableRowSelection from '@/hooks/use-table-row-selection';
|
import useTableRowSelection from '@/hooks/use-table-row-selection';
|
||||||
import useTableSort from '@/hooks/use-table-sort';
|
import useTableSort from '@/hooks/use-table-sort';
|
||||||
import NoResult from '@/pages/_components/no-result';
|
import NoResult from '@/pages/_components/no-result';
|
||||||
|
import PageBox from '@/pages/_components/page-box';
|
||||||
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
|
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
|
||||||
import { handleBatchRequest } from '@/utils';
|
import { handleBatchRequest } from '@/utils';
|
||||||
import { DownOutlined, SearchOutlined, SyncOutlined } from '@ant-design/icons';
|
import { DownOutlined, SearchOutlined, SyncOutlined } from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Button, Input, Space, message } from 'antd';
|
import { Button, Input, Space, message } from 'antd';
|
||||||
@@ -596,20 +596,10 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox>
|
||||||
className="models-page-container"
|
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'menu.models.deployment' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<PageTools
|
<PageTools
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
|
marginTop={0}
|
||||||
left={
|
left={
|
||||||
<Space>
|
<Space>
|
||||||
<Input
|
<Input
|
||||||
@@ -742,7 +732,7 @@ const Models: React.FC<ModelsProps> = ({
|
|||||||
onChange: handlePageChange
|
onChange: handlePageChange
|
||||||
}}
|
}}
|
||||||
></SealTable>
|
></SealTable>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
<UpdateModelModal
|
<UpdateModelModal
|
||||||
open={openAddModal}
|
open={openAddModal}
|
||||||
action={PageAction.EDIT}
|
action={PageAction.EDIT}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import CardList from '@/components/templates/card-list';
|
|||||||
import CardSkeleton from '@/components/templates/card-skelton';
|
import CardSkeleton from '@/components/templates/card-skelton';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import { SyncOutlined } from '@ant-design/icons';
|
import { SyncOutlined } from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
||||||
import { Button, Input, Space } from 'antd';
|
import { Button, Input, Space } from 'antd';
|
||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import { ScrollerContext } from '../_components/infinite-scroller/use-scroller-context';
|
import { ScrollerContext } from '../_components/infinite-scroller/use-scroller-context';
|
||||||
import NoResult from '../_components/no-result';
|
import NoResult from '../_components/no-result';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import { MY_MODELS_API, queryMyModels } from './apis';
|
import { MY_MODELS_API, queryMyModels } from './apis';
|
||||||
import ModelItem from './components/model-item';
|
import ModelItem from './components/model-item';
|
||||||
import {
|
import {
|
||||||
@@ -172,7 +172,7 @@ const UserModels: React.FC = () => {
|
|||||||
}, [dataSource.dataList, status]);
|
}, [dataSource.dataList, status]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageBox
|
||||||
ghost
|
ghost
|
||||||
header={{
|
header={{
|
||||||
title: intl.formatMessage({ id: 'menu.models.userModels' }),
|
title: intl.formatMessage({ id: 'menu.models.userModels' }),
|
||||||
@@ -261,7 +261,7 @@ const UserModels: React.FC = () => {
|
|||||||
subTitle={intl.formatMessage({ id: 'noresult.mymodels.subTitle' })}
|
subTitle={intl.formatMessage({ id: 'noresult.mymodels.subTitle' })}
|
||||||
></NoResult>
|
></NoResult>
|
||||||
</ScrollerContext.Provider>
|
</ScrollerContext.Provider>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export const login = async (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const logout = async (userInfo: any) => {
|
export const logout = async (userInfo?: any) => {
|
||||||
await request(`${AUTH_API}/logout`, {
|
await request(`${AUTH_API}/logout`, {
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import AudioPlayer from '@/components/audio-player';
|
|||||||
import CopyButton from '@/components/copy-button';
|
import CopyButton from '@/components/copy-button';
|
||||||
import IconFont from '@/components/icon-font';
|
import IconFont from '@/components/icon-font';
|
||||||
import UploadAudio from '@/components/upload-audio';
|
import UploadAudio from '@/components/upload-audio';
|
||||||
|
import { HEADER_HEIGHT } from '@/config/constants';
|
||||||
import routeCachekey from '@/config/route-cachekey';
|
import routeCachekey from '@/config/route-cachekey';
|
||||||
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
||||||
import { useCancelToken } from '@/hooks/use-request-token';
|
import { useCancelToken } from '@/hooks/use-request-token';
|
||||||
@@ -13,7 +14,6 @@ import { SendOutlined } from '@ant-design/icons';
|
|||||||
import { useIntl, useSearchParams } from '@umijs/max';
|
import { useIntl, useSearchParams } from '@umijs/max';
|
||||||
import { Button, Spin, Tooltip } from 'antd';
|
import { Button, Spin, Tooltip } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import 'overlayscrollbars/overlayscrollbars.css';
|
|
||||||
import React, {
|
import React, {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
useCallback,
|
useCallback,
|
||||||
@@ -289,7 +289,7 @@ const GroundSTT: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
<div
|
<div
|
||||||
className="ground-left-wrapper"
|
className="ground-left-wrapper"
|
||||||
style={{
|
style={{
|
||||||
height: 'calc(100vh - 72px)'
|
height: `calc(100vh - ${HEADER_HEIGHT}px)`
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="ground-left">
|
<div className="ground-left">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { HEADER_HEIGHT } from '@/config/constants';
|
||||||
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
import useOverlayScroller from '@/hooks/use-overlay-scroller';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import 'overlayscrollbars/overlayscrollbars.css';
|
|
||||||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import CompareContext from '../../config/compare-context';
|
import CompareContext from '../../config/compare-context';
|
||||||
import {
|
import {
|
||||||
@@ -39,7 +39,7 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList, loaded }) => {
|
|||||||
const modelsCounterMap = useRef<Record<string, number>>({});
|
const modelsCounterMap = useRef<Record<string, number>>({});
|
||||||
const modelRefs = useRef<any>({});
|
const modelRefs = useRef<any>({});
|
||||||
const chatListScrollRef = useRef<any>(null);
|
const chatListScrollRef = useRef<any>(null);
|
||||||
const boxHeight = 'calc(100vh - 72px)';
|
const boxHeight = `calc(100vh - ${HEADER_HEIGHT}px)`;
|
||||||
const [actions, setActions] = useState<MessageItemAction[]>([
|
const [actions, setActions] = useState<MessageItemAction[]>([
|
||||||
'upload',
|
'upload',
|
||||||
'delete',
|
'delete',
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { Button, Space } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
import IconFont from '../../../components/icon-font';
|
||||||
|
|
||||||
|
const ViewCodeButtons: React.FC<{
|
||||||
|
handleViewCode: () => void;
|
||||||
|
handleToggleCollapse: () => void;
|
||||||
|
activeKey: string;
|
||||||
|
}> = ({ handleViewCode, handleToggleCollapse, activeKey }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
if (activeKey === 'compare') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space key="buttons" style={{ marginRight: 8 }}>
|
||||||
|
<Button
|
||||||
|
size="middle"
|
||||||
|
onClick={handleViewCode}
|
||||||
|
icon={<IconFont type="icon-code" className="font-size-16"></IconFont>}
|
||||||
|
>
|
||||||
|
{intl.formatMessage({ id: 'playground.viewcode' })}
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="middle"
|
||||||
|
onClick={handleToggleCollapse}
|
||||||
|
icon={
|
||||||
|
<IconFont
|
||||||
|
type="icon-a-layout6-line"
|
||||||
|
className="font-size-16"
|
||||||
|
></IconFont>
|
||||||
|
}
|
||||||
|
></Button>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ViewCodeButtons;
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
import IconFont from '@/components/icon-font';
|
|
||||||
import HotKeys from '@/config/hotkeys';
|
import HotKeys from '@/config/hotkeys';
|
||||||
|
import { ExtraContent } from '@/layouts/extraRender';
|
||||||
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Button, Space } from 'antd';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
import { Divider } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import { PageContainerInner } from '../_components/page-box';
|
||||||
import { queryModelsList } from './apis';
|
import { queryModelsList } from './apis';
|
||||||
import GroundEmbedding from './components/ground-embedding';
|
import GroundEmbedding from './components/ground-embedding';
|
||||||
|
import ViewCodeButtons from './components/view-code-buttons';
|
||||||
import useCollapseLayout from './hooks/use-collapse-layout';
|
import useCollapseLayout from './hooks/use-collapse-layout';
|
||||||
import './style/play-ground.less';
|
import './style/play-ground.less';
|
||||||
|
|
||||||
@@ -27,12 +29,12 @@ const PlaygroundEmbedding: React.FC = () => {
|
|||||||
triggeredRef: groundLeftRef.current
|
triggeredRef: groundLeftRef.current
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleViewCode = useCallback(() => {
|
const handleViewCode = useMemoizedFn(() => {
|
||||||
groundLeftRef.current?.viewCode?.();
|
groundLeftRef.current?.viewCode?.();
|
||||||
}, [groundLeftRef.current]);
|
});
|
||||||
const handleToggleCollapse = useCallback(() => {
|
const handleToggleCollapse = useMemoizedFn(() => {
|
||||||
groundLeftRef.current?.setCollapse?.();
|
groundLeftRef.current?.setCollapse?.();
|
||||||
}, [groundLeftRef.current]);
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getModelListByEmbedding = async () => {
|
const getModelListByEmbedding = async () => {
|
||||||
@@ -66,30 +68,6 @@ const PlaygroundEmbedding: React.FC = () => {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const renderExtra = () => {
|
|
||||||
return (
|
|
||||||
<Space key="buttons">
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleViewCode}
|
|
||||||
icon={<IconFont type="icon-code" className="font-size-16"></IconFont>}
|
|
||||||
>
|
|
||||||
{intl.formatMessage({ id: 'playground.viewcode' })}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleToggleCollapse}
|
|
||||||
icon={
|
|
||||||
<IconFont
|
|
||||||
type="icon-a-layout6-line"
|
|
||||||
className="font-size-16"
|
|
||||||
></IconFont>
|
|
||||||
}
|
|
||||||
></Button>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
HotKeys.RIGHT.join(','),
|
HotKeys.RIGHT.join(','),
|
||||||
() => {
|
() => {
|
||||||
@@ -101,17 +79,22 @@ const PlaygroundEmbedding: React.FC = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainerInner
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'menu.playground.embedding' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={renderExtra()}
|
|
||||||
className={classNames('playground-container chat')}
|
className={classNames('playground-container chat')}
|
||||||
|
extra={[
|
||||||
|
<ViewCodeButtons
|
||||||
|
activeKey=""
|
||||||
|
handleViewCode={handleViewCode}
|
||||||
|
handleToggleCollapse={handleToggleCollapse}
|
||||||
|
key="view-code-buttons"
|
||||||
|
/>,
|
||||||
|
<Divider
|
||||||
|
key="divider"
|
||||||
|
type="vertical"
|
||||||
|
style={{ height: 24, marginInline: 16 }}
|
||||||
|
/>,
|
||||||
|
<ExtraContent key="extra-content" />
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<div className="play-ground">
|
<div className="play-ground">
|
||||||
<div className="chat">
|
<div className="chat">
|
||||||
@@ -122,7 +105,7 @@ const PlaygroundEmbedding: React.FC = () => {
|
|||||||
></GroundEmbedding>
|
></GroundEmbedding>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainerInner>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
import IconFont from '@/components/icon-font';
|
|
||||||
import breakpoints from '@/config/breakpoints';
|
import breakpoints from '@/config/breakpoints';
|
||||||
import HotKeys from '@/config/hotkeys';
|
import HotKeys from '@/config/hotkeys';
|
||||||
import useWindowResize from '@/hooks/use-window-resize';
|
import useWindowResize from '@/hooks/use-window-resize';
|
||||||
|
import { ExtraContent } from '@/layouts/extraRender';
|
||||||
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
||||||
import { DiffOutlined, HighlightOutlined } from '@ant-design/icons';
|
import { DiffOutlined, HighlightOutlined } from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Button, Segmented, Space, Tabs, TabsProps } from 'antd';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
import { Divider, Segmented, Tabs, TabsProps } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import { PageContainerInner } from '../_components/page-box';
|
||||||
import { queryModelsList } from './apis';
|
import { queryModelsList } from './apis';
|
||||||
import GroundImages from './components/ground-images';
|
import GroundImages from './components/ground-images';
|
||||||
import ImageEdit from './components/image-edit';
|
import ImageEdit from './components/image-edit';
|
||||||
|
import ViewCodeButtons from './components/view-code-buttons';
|
||||||
import './style/play-ground.less';
|
import './style/play-ground.less';
|
||||||
|
|
||||||
const TabsValueMap = {
|
const TabsValueMap = {
|
||||||
@@ -44,21 +46,21 @@ const TextToImages: React.FC = () => {
|
|||||||
];
|
];
|
||||||
}, [intl]);
|
}, [intl]);
|
||||||
|
|
||||||
const handleViewCode = useCallback(() => {
|
const handleViewCode = useMemoizedFn(() => {
|
||||||
if (activeKey === TabsValueMap.Tab1) {
|
if (activeKey === TabsValueMap.Tab1) {
|
||||||
groundTabRef1.current?.viewCode?.();
|
groundTabRef1.current?.viewCode?.();
|
||||||
} else if (activeKey === TabsValueMap.Tab2) {
|
} else if (activeKey === TabsValueMap.Tab2) {
|
||||||
groundTabRef2.current?.viewCode?.();
|
groundTabRef2.current?.viewCode?.();
|
||||||
}
|
}
|
||||||
}, [activeKey]);
|
});
|
||||||
|
|
||||||
const handleToggleCollapse = useCallback(() => {
|
const handleToggleCollapse = useMemoizedFn(() => {
|
||||||
if (activeKey === TabsValueMap.Tab1) {
|
if (activeKey === TabsValueMap.Tab1) {
|
||||||
groundTabRef1.current?.setCollapse?.();
|
groundTabRef1.current?.setCollapse?.();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
groundTabRef2.current?.setCollapse?.();
|
groundTabRef2.current?.setCollapse?.();
|
||||||
}, [activeKey]);
|
});
|
||||||
|
|
||||||
const items: TabsProps['items'] = useMemo(() => {
|
const items: TabsProps['items'] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
@@ -124,30 +126,6 @@ const TextToImages: React.FC = () => {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const renderExtra = useMemo(() => {
|
|
||||||
return (
|
|
||||||
<Space key="buttons">
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleViewCode}
|
|
||||||
icon={<IconFont type="icon-code" className="font-size-16"></IconFont>}
|
|
||||||
>
|
|
||||||
{intl.formatMessage({ id: 'playground.viewcode' })}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleToggleCollapse}
|
|
||||||
icon={
|
|
||||||
<IconFont
|
|
||||||
type="icon-a-layout6-line"
|
|
||||||
className="font-size-16"
|
|
||||||
></IconFont>
|
|
||||||
}
|
|
||||||
></Button>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}, [intl, handleViewCode, handleToggleCollapse]);
|
|
||||||
|
|
||||||
const header = useMemo(() => {
|
const header = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
title: (
|
title: (
|
||||||
@@ -164,11 +142,7 @@ const TextToImages: React.FC = () => {
|
|||||||
></Segmented>
|
></Segmented>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
),
|
)
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
};
|
};
|
||||||
}, [optionsList]);
|
}, [optionsList]);
|
||||||
|
|
||||||
@@ -183,10 +157,22 @@ const TextToImages: React.FC = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainerInner
|
||||||
ghost
|
|
||||||
header={header}
|
header={header}
|
||||||
extra={renderExtra}
|
extra={[
|
||||||
|
<ViewCodeButtons
|
||||||
|
handleViewCode={handleViewCode}
|
||||||
|
handleToggleCollapse={handleToggleCollapse}
|
||||||
|
activeKey={activeKey}
|
||||||
|
key="view-code-buttons"
|
||||||
|
></ViewCodeButtons>,
|
||||||
|
<Divider
|
||||||
|
key="divider"
|
||||||
|
type="vertical"
|
||||||
|
style={{ height: 24, marginInline: 16 }}
|
||||||
|
/>,
|
||||||
|
<ExtraContent key="extra-content" />
|
||||||
|
]}
|
||||||
className={classNames('playground-container chat')}
|
className={classNames('playground-container chat')}
|
||||||
>
|
>
|
||||||
<div className="play-ground">
|
<div className="play-ground">
|
||||||
@@ -194,7 +180,7 @@ const TextToImages: React.FC = () => {
|
|||||||
<Tabs items={items} activeKey={activeKey}></Tabs>
|
<Tabs items={items} activeKey={activeKey}></Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainerInner>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,32 @@
|
|||||||
import IconFont from '@/components/icon-font';
|
|
||||||
import breakpoints from '@/config/breakpoints';
|
import breakpoints from '@/config/breakpoints';
|
||||||
import HotKeys from '@/config/hotkeys';
|
import HotKeys from '@/config/hotkeys';
|
||||||
import useWindowResize from '@/hooks/use-window-resize';
|
import useWindowResize from '@/hooks/use-window-resize';
|
||||||
|
import { ExtraContent } from '@/layouts/extraRender';
|
||||||
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
||||||
import { MessageOutlined, OneToOneOutlined } from '@ant-design/icons';
|
import { MessageOutlined, OneToOneOutlined } from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Button, Segmented, Space, Tabs, TabsProps } from 'antd';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
import { Divider, Segmented, Tabs, TabsProps } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { PageContainerInner } from '../_components/page-box';
|
||||||
import { queryModelsList } from './apis';
|
import { queryModelsList } from './apis';
|
||||||
import GroundLeft from './components/ground-left';
|
import GroundLeft from './components/ground-left';
|
||||||
import MultipleChat from './components/multiple-chat';
|
import MultipleChat from './components/multiple-chat';
|
||||||
|
import ViewCodeButtons from './components/view-code-buttons';
|
||||||
import './style/play-ground.less';
|
import './style/play-ground.less';
|
||||||
|
|
||||||
|
const Header = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 16px;
|
||||||
|
padding-inline: 32px;
|
||||||
|
`;
|
||||||
|
|
||||||
const Playground: React.FC = () => {
|
const Playground: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { size } = useWindowResize();
|
const { size } = useWindowResize();
|
||||||
@@ -40,27 +51,28 @@ const Playground: React.FC = () => {
|
|||||||
];
|
];
|
||||||
}, [intl]);
|
}, [intl]);
|
||||||
|
|
||||||
const handleViewCode = useCallback(() => {
|
const handleViewCode = useMemoizedFn(() => {
|
||||||
if (activeKey === 'reranker') {
|
if (activeKey === 'reranker') {
|
||||||
groundRerankerRef.current?.viewCode?.();
|
groundRerankerRef.current?.viewCode?.();
|
||||||
} else if (activeKey === 'chat') {
|
} else if (activeKey === 'chat') {
|
||||||
groundLeftRef.current?.viewCode?.();
|
groundLeftRef.current?.viewCode?.();
|
||||||
}
|
}
|
||||||
}, [activeKey]);
|
});
|
||||||
|
|
||||||
const handleToggleCollapse = useCallback(() => {
|
const handleToggleCollapse = useMemoizedFn(() => {
|
||||||
if (activeKey === 'reranker') {
|
if (activeKey === 'reranker') {
|
||||||
groundRerankerRef.current?.setCollapse?.();
|
groundRerankerRef.current?.setCollapse?.();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
groundLeftRef.current?.setCollapse?.();
|
groundLeftRef.current?.setCollapse?.();
|
||||||
}, [activeKey]);
|
});
|
||||||
|
|
||||||
const items: TabsProps['items'] = useMemo(() => {
|
const items: TabsProps['items'] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
key: 'chat',
|
key: 'chat',
|
||||||
label: 'Chat',
|
label: 'Chat',
|
||||||
|
icon: <MessageOutlined />,
|
||||||
children: (
|
children: (
|
||||||
<GroundLeft ref={groundLeftRef} modelList={modelList}></GroundLeft>
|
<GroundLeft ref={groundLeftRef} modelList={modelList}></GroundLeft>
|
||||||
)
|
)
|
||||||
@@ -68,6 +80,7 @@ const Playground: React.FC = () => {
|
|||||||
{
|
{
|
||||||
key: 'compare',
|
key: 'compare',
|
||||||
label: 'Compare',
|
label: 'Compare',
|
||||||
|
icon: <OneToOneOutlined />,
|
||||||
children: <MultipleChat modelList={modelList} loaded={loaded} />
|
children: <MultipleChat modelList={modelList} loaded={loaded} />
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -105,33 +118,6 @@ const Playground: React.FC = () => {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const renderExtra = useMemo(() => {
|
|
||||||
if (activeKey === 'compare') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Space key="buttons">
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleViewCode}
|
|
||||||
icon={<IconFont type="icon-code" className="font-size-16"></IconFont>}
|
|
||||||
>
|
|
||||||
{intl.formatMessage({ id: 'playground.viewcode' })}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleToggleCollapse}
|
|
||||||
icon={
|
|
||||||
<IconFont
|
|
||||||
type="icon-a-layout6-line"
|
|
||||||
className="font-size-16"
|
|
||||||
></IconFont>
|
|
||||||
}
|
|
||||||
></Button>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}, [activeKey, intl, handleViewCode, handleToggleCollapse]);
|
|
||||||
|
|
||||||
const header = useMemo(() => {
|
const header = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
title: (
|
title: (
|
||||||
@@ -148,11 +134,7 @@ const Playground: React.FC = () => {
|
|||||||
></Segmented>
|
></Segmented>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
),
|
)
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
};
|
};
|
||||||
}, [optionsList]);
|
}, [optionsList]);
|
||||||
|
|
||||||
@@ -169,21 +151,33 @@ const Playground: React.FC = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainerInner
|
||||||
ghost
|
|
||||||
header={header}
|
|
||||||
extra={renderExtra}
|
|
||||||
className={classNames('playground-container', {
|
className={classNames('playground-container', {
|
||||||
compare: activeKey === 'compare',
|
compare: activeKey === 'compare',
|
||||||
chat: activeKey !== 'compare'
|
chat: activeKey !== 'compare'
|
||||||
})}
|
})}
|
||||||
|
header={header}
|
||||||
|
extra={[
|
||||||
|
<ViewCodeButtons
|
||||||
|
handleViewCode={handleViewCode}
|
||||||
|
handleToggleCollapse={handleToggleCollapse}
|
||||||
|
activeKey={activeKey}
|
||||||
|
key="view-code-buttons"
|
||||||
|
/>,
|
||||||
|
<Divider
|
||||||
|
key="divider"
|
||||||
|
type="vertical"
|
||||||
|
style={{ height: 24, marginInline: 16 }}
|
||||||
|
/>,
|
||||||
|
<ExtraContent key="extra-content" />
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<div className="play-ground">
|
<div className="play-ground">
|
||||||
<div className="chat">
|
<div className="chat">
|
||||||
<Tabs items={items} activeKey={activeKey}></Tabs>
|
<Tabs items={items} activeKey={activeKey}></Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainerInner>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
import IconFont from '@/components/icon-font';
|
|
||||||
import HotKeys from '@/config/hotkeys';
|
import HotKeys from '@/config/hotkeys';
|
||||||
|
import { ExtraContent } from '@/layouts/extraRender';
|
||||||
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Button, Space } from 'antd';
|
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
||||||
|
import { Divider } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import { PageContainerInner } from '../_components/page-box';
|
||||||
import { queryModelsList } from './apis';
|
import { queryModelsList } from './apis';
|
||||||
import GroundReranker from './components/ground-reranker';
|
import GroundReranker from './components/ground-reranker';
|
||||||
|
import ViewCodeButtons from './components/view-code-buttons';
|
||||||
import useCollapseLayout from './hooks/use-collapse-layout';
|
import useCollapseLayout from './hooks/use-collapse-layout';
|
||||||
import './style/play-ground.less';
|
import './style/play-ground.less';
|
||||||
|
|
||||||
const PlaygroundRerank: React.FC = () => {
|
const PlaygroundRerank: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const groundLeftRef = useRef<any>(null);
|
|
||||||
const groundRerankerRef = useRef<any>(null);
|
const groundRerankerRef = useRef<any>(null);
|
||||||
const [rerankerModelList, setRerankerModelList] = useState<
|
const [rerankerModelList, setRerankerModelList] = useState<
|
||||||
Global.BaseOption<string>[]
|
Global.BaseOption<string>[]
|
||||||
@@ -29,13 +30,13 @@ const PlaygroundRerank: React.FC = () => {
|
|||||||
triggeredRef: groundRerankerRef.current
|
triggeredRef: groundRerankerRef.current
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleViewCode = useCallback(() => {
|
const handleViewCode = useMemoizedFn(() => {
|
||||||
groundRerankerRef.current?.viewCode?.();
|
groundRerankerRef.current?.viewCode?.();
|
||||||
}, [groundRerankerRef]);
|
});
|
||||||
|
|
||||||
const handleToggleCollapse = useCallback(() => {
|
const handleToggleCollapse = useMemoizedFn(() => {
|
||||||
groundRerankerRef.current?.setCollapse?.();
|
groundRerankerRef.current?.setCollapse?.();
|
||||||
}, [groundRerankerRef]);
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getModelListByReranker = async () => {
|
const getModelListByReranker = async () => {
|
||||||
@@ -71,30 +72,6 @@ const PlaygroundRerank: React.FC = () => {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const renderExtra = () => {
|
|
||||||
return (
|
|
||||||
<Space key="buttons">
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleViewCode}
|
|
||||||
icon={<IconFont type="icon-code" className="font-size-16"></IconFont>}
|
|
||||||
>
|
|
||||||
{intl.formatMessage({ id: 'playground.viewcode' })}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleToggleCollapse}
|
|
||||||
icon={
|
|
||||||
<IconFont
|
|
||||||
type="icon-a-layout6-line"
|
|
||||||
className="font-size-16"
|
|
||||||
></IconFont>
|
|
||||||
}
|
|
||||||
></Button>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
HotKeys.RIGHT.join(','),
|
HotKeys.RIGHT.join(','),
|
||||||
() => {
|
() => {
|
||||||
@@ -106,17 +83,22 @@ const PlaygroundRerank: React.FC = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainerInner
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'menu.playground.rerank' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={renderExtra()}
|
|
||||||
className={classNames('playground-container chat')}
|
className={classNames('playground-container chat')}
|
||||||
|
extra={[
|
||||||
|
<ViewCodeButtons
|
||||||
|
activeKey=""
|
||||||
|
handleViewCode={handleViewCode}
|
||||||
|
handleToggleCollapse={handleToggleCollapse}
|
||||||
|
key="view-code-buttons"
|
||||||
|
></ViewCodeButtons>,
|
||||||
|
<Divider
|
||||||
|
key="divider"
|
||||||
|
type="vertical"
|
||||||
|
style={{ height: 24, marginInline: 16 }}
|
||||||
|
/>,
|
||||||
|
<ExtraContent key="extra-content" />
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<div className="play-ground">
|
<div className="play-ground">
|
||||||
<div className="chat">
|
<div className="chat">
|
||||||
@@ -127,7 +109,7 @@ const PlaygroundRerank: React.FC = () => {
|
|||||||
></GroundReranker>
|
></GroundReranker>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainerInner>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,18 +2,21 @@ import IconFont from '@/components/icon-font';
|
|||||||
import breakpoints from '@/config/breakpoints';
|
import breakpoints from '@/config/breakpoints';
|
||||||
import HotKeys from '@/config/hotkeys';
|
import HotKeys from '@/config/hotkeys';
|
||||||
import useWindowResize from '@/hooks/use-window-resize';
|
import useWindowResize from '@/hooks/use-window-resize';
|
||||||
|
import { ExtraContent } from '@/layouts/extraRender';
|
||||||
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
import { modelCategoriesMap } from '@/pages/llmodels/config';
|
||||||
import { AudioOutlined } from '@ant-design/icons';
|
import { AudioOutlined } from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useSearchParams } from '@umijs/max';
|
import { useIntl, useSearchParams } from '@umijs/max';
|
||||||
import { Button, Segmented, Space, Tabs, TabsProps } from 'antd';
|
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
||||||
|
import { Divider, Segmented, Tabs, TabsProps } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import { PageContainerInner } from '../_components/page-box';
|
||||||
import { queryModelsList } from './apis';
|
import { queryModelsList } from './apis';
|
||||||
import GroundSTT from './components/ground-stt';
|
import GroundSTT from './components/ground-stt';
|
||||||
import GroundTTS from './components/ground-tts';
|
import GroundTTS from './components/ground-tts';
|
||||||
|
import ViewCodeButtons from './components/view-code-buttons';
|
||||||
import './style/play-ground.less';
|
import './style/play-ground.less';
|
||||||
|
|
||||||
const TabsValueMap = {
|
const TabsValueMap = {
|
||||||
@@ -53,21 +56,21 @@ const Playground: React.FC = () => {
|
|||||||
];
|
];
|
||||||
}, [intl]);
|
}, [intl]);
|
||||||
|
|
||||||
const handleViewCode = useCallback(() => {
|
const handleViewCode = useMemoizedFn(() => {
|
||||||
if (activeKey === TabsValueMap.Tab1) {
|
if (activeKey === TabsValueMap.Tab1) {
|
||||||
groundTabRef1.current?.viewCode?.();
|
groundTabRef1.current?.viewCode?.();
|
||||||
} else if (activeKey === TabsValueMap.Tab2) {
|
} else if (activeKey === TabsValueMap.Tab2) {
|
||||||
groundTabRef2.current?.viewCode?.();
|
groundTabRef2.current?.viewCode?.();
|
||||||
}
|
}
|
||||||
}, [activeKey]);
|
});
|
||||||
|
|
||||||
const handleToggleCollapse = useCallback(() => {
|
const handleToggleCollapse = useMemoizedFn(() => {
|
||||||
if (activeKey === TabsValueMap.Tab1) {
|
if (activeKey === TabsValueMap.Tab1) {
|
||||||
groundTabRef1.current?.setCollapse?.();
|
groundTabRef1.current?.setCollapse?.();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
groundTabRef2.current?.setCollapse?.();
|
groundTabRef2.current?.setCollapse?.();
|
||||||
}, [activeKey]);
|
});
|
||||||
|
|
||||||
const items: TabsProps['items'] = useMemo(() => {
|
const items: TabsProps['items'] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
@@ -160,30 +163,6 @@ const Playground: React.FC = () => {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const renderExtra = useMemo(() => {
|
|
||||||
return (
|
|
||||||
<Space key="buttons">
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleViewCode}
|
|
||||||
icon={<IconFont type="icon-code" className="font-size-16"></IconFont>}
|
|
||||||
>
|
|
||||||
{intl.formatMessage({ id: 'playground.viewcode' })}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="middle"
|
|
||||||
onClick={handleToggleCollapse}
|
|
||||||
icon={
|
|
||||||
<IconFont
|
|
||||||
type="icon-a-layout6-line"
|
|
||||||
className="font-size-16"
|
|
||||||
></IconFont>
|
|
||||||
}
|
|
||||||
></Button>
|
|
||||||
</Space>
|
|
||||||
);
|
|
||||||
}, [handleToggleCollapse, handleViewCode, intl]);
|
|
||||||
|
|
||||||
const header = useMemo(() => {
|
const header = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
title: (
|
title: (
|
||||||
@@ -201,11 +180,7 @@ const Playground: React.FC = () => {
|
|||||||
></Segmented>
|
></Segmented>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
),
|
)
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
};
|
};
|
||||||
}, [activeKey, optionsList]);
|
}, [activeKey, optionsList]);
|
||||||
|
|
||||||
@@ -220,10 +195,22 @@ const Playground: React.FC = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer
|
<PageContainerInner
|
||||||
ghost
|
|
||||||
header={header}
|
header={header}
|
||||||
extra={renderExtra}
|
extra={[
|
||||||
|
<ViewCodeButtons
|
||||||
|
activeKey=""
|
||||||
|
handleViewCode={handleViewCode}
|
||||||
|
handleToggleCollapse={handleToggleCollapse}
|
||||||
|
key="view-code-buttons"
|
||||||
|
></ViewCodeButtons>,
|
||||||
|
<Divider
|
||||||
|
key="divider"
|
||||||
|
type="vertical"
|
||||||
|
style={{ height: 24, marginInline: 16 }}
|
||||||
|
/>,
|
||||||
|
<ExtraContent key="extra-content" />
|
||||||
|
]}
|
||||||
className={classNames('playground-container', {
|
className={classNames('playground-container', {
|
||||||
compare: activeKey === 'compare',
|
compare: activeKey === 'compare',
|
||||||
chat: activeKey !== 'compare'
|
chat: activeKey !== 'compare'
|
||||||
@@ -234,7 +221,7 @@ const Playground: React.FC = () => {
|
|||||||
<Tabs items={items} activeKey={activeKey}></Tabs>
|
<Tabs items={items} activeKey={activeKey}></Tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainerInner>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@HEADER_HEIGHT: 56px;
|
||||||
|
|
||||||
.ground-left-wrapper {
|
.ground-left-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
@@ -7,7 +9,7 @@
|
|||||||
width: 390px;
|
width: 390px;
|
||||||
border-left: 1px solid var(--ant-color-split);
|
border-left: 1px solid var(--ant-color-split);
|
||||||
transition: width 0.3s ease;
|
transition: width 0.3s ease;
|
||||||
height: calc(100vh - 72px);
|
height: calc(100vh - @HEADER_HEIGHT);
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
@@ -40,7 +42,7 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: calc(100vh - 72px);
|
height: calc(100vh - @HEADER_HEIGHT);
|
||||||
width: calc(100% - 390px);
|
width: calc(100% - 390px);
|
||||||
|
|
||||||
.message-list-wrap {
|
.message-list-wrap {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@HEADER_HEIGHT: 56px;
|
||||||
|
|
||||||
.play-ground {
|
.play-ground {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -37,7 +39,7 @@
|
|||||||
|
|
||||||
.params {
|
.params {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: calc(100vh - 72px);
|
height: calc(100vh - @HEADER_HEIGHT);
|
||||||
|
|
||||||
.collapse {
|
.collapse {
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -81,20 +83,19 @@
|
|||||||
|
|
||||||
.ant-page-header {
|
.ant-page-header {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 72px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.chat {
|
&.chat {
|
||||||
.ant-page-header {
|
.ant-page-header {
|
||||||
&::after {
|
// &::after {
|
||||||
position: absolute;
|
// position: absolute;
|
||||||
content: '';
|
// content: '';
|
||||||
left: 32px;
|
// left: 32px;
|
||||||
right: 32px;
|
// right: 32px;
|
||||||
bottom: 0;
|
// bottom: 0;
|
||||||
height: 1px;
|
// height: 1px;
|
||||||
border-bottom: 1px solid var(--ant-color-split);
|
// border-bottom: 1px solid var(--ant-color-split);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-23
@@ -1,9 +1,9 @@
|
|||||||
import useTabActive from '@/hooks/use-tab-active';
|
import useTabActive from '@/hooks/use-tab-active';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useModel } from '@umijs/max';
|
import { useIntl, useModel } from '@umijs/max';
|
||||||
import { TabsProps } from 'antd';
|
import { Tabs, TabsProps } from 'antd';
|
||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import Appearance from './components/appearance';
|
import Appearance from './components/appearance';
|
||||||
import ModifyPasswordn from './components/modify-password';
|
import ModifyPasswordn from './components/modify-password';
|
||||||
|
|
||||||
@@ -53,27 +53,14 @@ const Profile: React.FC = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<PageBox>
|
||||||
<PageContainer
|
<Tabs
|
||||||
ghost
|
activeKey={activeKey}
|
||||||
header={{
|
onChange={handleChangeTab}
|
||||||
title: intl.formatMessage({ id: 'users.settings.title' }),
|
items={items}
|
||||||
style: {
|
type="card"
|
||||||
paddingInline: 'var(--layout-content-inlinepadding)'
|
/>
|
||||||
}
|
</PageBox>
|
||||||
}}
|
|
||||||
tabList={items}
|
|
||||||
onTabChange={handleChangeTab}
|
|
||||||
tabActiveKey={activeKey}
|
|
||||||
tabProps={{
|
|
||||||
type: 'card',
|
|
||||||
style: {
|
|
||||||
marginTop: 78
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
></PageContainer>
|
|
||||||
</Wrapper>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import IconFont from '@/components/icon-font';
|
|||||||
import { FilterBar } from '@/components/page-tools';
|
import { FilterBar } from '@/components/page-tools';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import NoResult from '@/pages/_components/no-result';
|
import NoResult from '@/pages/_components/no-result';
|
||||||
|
import PageBox from '@/pages/_components/page-box';
|
||||||
import { queryClusterList } from '@/pages/cluster-management/apis';
|
import { queryClusterList } from '@/pages/cluster-management/apis';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { ConfigProvider, Table } from 'antd';
|
import { ConfigProvider, Table } from 'antd';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
@@ -76,17 +76,7 @@ const GPUList: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: 'GPUs',
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<FilterBar
|
<FilterBar
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
marginTop={30}
|
marginTop={30}
|
||||||
@@ -116,7 +106,7 @@ const GPUList: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
></Table>
|
></Table>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import useAppUtils from '@/hooks/use-app-utils';
|
|||||||
import useBodyScroll from '@/hooks/use-body-scroll';
|
import useBodyScroll from '@/hooks/use-body-scroll';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import NoResult from '@/pages/_components/no-result';
|
import NoResult from '@/pages/_components/no-result';
|
||||||
|
import PageBox from '@/pages/_components/page-box';
|
||||||
import { createModel } from '@/pages/llmodels/apis';
|
import { createModel } from '@/pages/llmodels/apis';
|
||||||
import DeployModal from '@/pages/llmodels/components/deploy-modal';
|
import DeployModal from '@/pages/llmodels/components/deploy-modal';
|
||||||
import { modelSourceMap } from '@/pages/llmodels/config';
|
import { modelSourceMap } from '@/pages/llmodels/config';
|
||||||
@@ -20,7 +21,6 @@ import DownloadModal from '@/pages/llmodels/download';
|
|||||||
import useCheckBackend from '@/pages/llmodels/hooks/use-check-backend';
|
import useCheckBackend from '@/pages/llmodels/hooks/use-check-backend';
|
||||||
import { useGenerateWorkerOptions } from '@/pages/llmodels/hooks/use-form-initial-values';
|
import { useGenerateWorkerOptions } from '@/pages/llmodels/hooks/use-form-initial-values';
|
||||||
import useRecognizeAudio from '@/pages/llmodels/hooks/use-recognize-audio';
|
import useRecognizeAudio from '@/pages/llmodels/hooks/use-recognize-audio';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { ConfigProvider, Table, message } from 'antd';
|
import { ConfigProvider, Table, message } from 'antd';
|
||||||
@@ -290,17 +290,7 @@ const ModelFiles = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'resources.modelfiles.modelfile' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<FilterBar
|
<FilterBar
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
marginTop={30}
|
marginTop={30}
|
||||||
@@ -365,7 +355,7 @@ const ModelFiles = () => {
|
|||||||
isGGUF={openDeployModal.isGGUF}
|
isGGUF={openDeployModal.isGGUF}
|
||||||
clusterList={clusterList}
|
clusterList={clusterList}
|
||||||
></DeployModal>
|
></DeployModal>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import DeleteModal from '@/components/delete-modal';
|
|||||||
import IconFont from '@/components/icon-font';
|
import IconFont from '@/components/icon-font';
|
||||||
import { FilterBar } from '@/components/page-tools';
|
import { FilterBar } from '@/components/page-tools';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
|
import PageBox from '@/pages/_components/page-box';
|
||||||
import { queryClusterList } from '@/pages/cluster-management/apis';
|
import { queryClusterList } from '@/pages/cluster-management/apis';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Button, ConfigProvider, Table, message } from 'antd';
|
import { Button, ConfigProvider, Table, message } from 'antd';
|
||||||
@@ -227,7 +227,7 @@ const Workers: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox
|
||||||
ghost
|
ghost
|
||||||
footer={[
|
footer={[
|
||||||
<TerminalTabs
|
<TerminalTabs
|
||||||
@@ -239,14 +239,6 @@ const Workers: React.FC = () => {
|
|||||||
onClose={handleTerminalClose}
|
onClose={handleTerminalClose}
|
||||||
/>
|
/>
|
||||||
]}
|
]}
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'resources.nodes' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
>
|
||||||
<FilterBar
|
<FilterBar
|
||||||
showSelect={true}
|
showSelect={true}
|
||||||
@@ -300,7 +292,7 @@ const Workers: React.FC = () => {
|
|||||||
setWorkerDetailStatus({ currentData: null, open: false })
|
setWorkerDetailStatus({ currentData: null, open: false })
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import { FilterBar } from '@/components/page-tools';
|
|||||||
import { PageAction } from '@/config';
|
import { PageAction } from '@/config';
|
||||||
import type { PageActionType } from '@/config/types';
|
import type { PageActionType } from '@/config/types';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
|
||||||
import { useIntl, useModel } from '@umijs/max';
|
import { useIntl, useModel } from '@umijs/max';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Button, ConfigProvider, message, Table } from 'antd';
|
import { Button, ConfigProvider, message, Table } from 'antd';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import NoResult from '../_components/no-result';
|
import NoResult from '../_components/no-result';
|
||||||
|
import PageBox from '../_components/page-box';
|
||||||
import { createUser, deleteUser, queryUsersList, updateUser } from './apis';
|
import { createUser, deleteUser, queryUsersList, updateUser } from './apis';
|
||||||
import AddModal from './components/add-modal';
|
import AddModal from './components/add-modal';
|
||||||
import { FormData, ListItem } from './config/types';
|
import { FormData, ListItem } from './config/types';
|
||||||
@@ -165,17 +165,7 @@ const Users: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageContainer
|
<PageBox>
|
||||||
ghost
|
|
||||||
header={{
|
|
||||||
title: intl.formatMessage({ id: 'users.title' }),
|
|
||||||
style: {
|
|
||||||
paddingInline: 'var(--layout-content-header-inlinepadding)'
|
|
||||||
},
|
|
||||||
breadcrumb: {}
|
|
||||||
}}
|
|
||||||
extra={[]}
|
|
||||||
>
|
|
||||||
<FilterBar
|
<FilterBar
|
||||||
marginBottom={22}
|
marginBottom={22}
|
||||||
marginTop={30}
|
marginTop={30}
|
||||||
@@ -205,7 +195,7 @@ const Users: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
></Table>
|
></Table>
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</PageContainer>
|
</PageBox>
|
||||||
<AddModal
|
<AddModal
|
||||||
open={openAddModalStatus.open}
|
open={openAddModalStatus.open}
|
||||||
action={openAddModalStatus.action}
|
action={openAddModalStatus.action}
|
||||||
|
|||||||
Reference in New Issue
Block a user