style: view instance logs
This commit is contained in:
@@ -11,6 +11,15 @@ type CopyButtonProps = {
|
|||||||
type?: 'text' | 'primary' | 'dashed' | 'link' | 'default';
|
type?: 'text' | 'primary' | 'dashed' | 'link' | 'default';
|
||||||
size?: 'small' | 'middle' | 'large';
|
size?: 'small' | 'middle' | 'large';
|
||||||
shape?: 'circle' | 'round' | 'default';
|
shape?: 'circle' | 'round' | 'default';
|
||||||
|
placement?:
|
||||||
|
| 'top'
|
||||||
|
| 'left'
|
||||||
|
| 'right'
|
||||||
|
| 'bottom'
|
||||||
|
| 'topLeft'
|
||||||
|
| 'topRight'
|
||||||
|
| 'bottomLeft'
|
||||||
|
| 'bottomRight';
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,6 +30,7 @@ const CopyButton: React.FC<CopyButtonProps> = ({
|
|||||||
shape = 'default',
|
shape = 'default',
|
||||||
fontSize = '14px',
|
fontSize = '14px',
|
||||||
style,
|
style,
|
||||||
|
placement,
|
||||||
size = 'middle'
|
size = 'middle'
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
@@ -55,7 +65,10 @@ const CopyButton: React.FC<CopyButtonProps> = ({
|
|||||||
}, [buttonRef]);
|
}, [buttonRef]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip title={intl.formatMessage({ id: 'common.button.copy' })}>
|
<Tooltip
|
||||||
|
title={intl.formatMessage({ id: 'common.button.copy' })}
|
||||||
|
placement={placement}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
className="copy-button"
|
className="copy-button"
|
||||||
ref={buttonRef}
|
ref={buttonRef}
|
||||||
|
|||||||
@@ -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_fabphdpng0n.js'
|
scriptUrl: '//at.alicdn.com/t/c/font_4613488_hdf3t88r4j.js'
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IconFont;
|
export default IconFont;
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
:local(.status-content-wrapper) {
|
:local(.status-content-wrapper) {
|
||||||
// padding-top: 24px;
|
|
||||||
&:hover {
|
&:hover {
|
||||||
:global(.copy-button-wrapper) {
|
:global(.copy-button-wrapper) {
|
||||||
display: block;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,13 +14,10 @@
|
|||||||
background-color: #383838;
|
background-color: #383838;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
right: 0;
|
right: -28px;
|
||||||
top: 0;
|
top: 0;
|
||||||
border-radius: 0 8px 0 4px;
|
padding: 2px;
|
||||||
}
|
border-radius: 4px;
|
||||||
|
|
||||||
.simplebar-scrollbar::before {
|
|
||||||
background: var(--color-scroll-bg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.simplebar-content {
|
.simplebar-content {
|
||||||
@@ -26,3 +25,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.simplebar-scrollbar::before {
|
||||||
|
background: var(--color-scroll-bg);
|
||||||
|
width: var(--scrollbar-size);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { StatusColorMap } from '@/config';
|
import { StatusColorMap } from '@/config';
|
||||||
import { StatusType } from '@/config/types';
|
import { StatusType } from '@/config/types';
|
||||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||||
import { Tooltip } from 'antd';
|
import { Button, Divider, Tooltip } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import SimpleBar from 'simplebar-react';
|
import SimpleBar from 'simplebar-react';
|
||||||
import 'simplebar-react/dist/simplebar.min.css';
|
import 'simplebar-react/dist/simplebar.min.css';
|
||||||
import CopyButton from '../copy-button';
|
import CopyButton from '../copy-button';
|
||||||
@@ -28,11 +28,19 @@ type StatusTagProps = {
|
|||||||
download?: {
|
download?: {
|
||||||
percent: number;
|
percent: number;
|
||||||
};
|
};
|
||||||
|
actions?: {
|
||||||
|
label: string;
|
||||||
|
icon?: React.ReactNode;
|
||||||
|
key: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
render?: () => React.ReactNode;
|
||||||
|
}[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const StatusTag: React.FC<StatusTagProps> = ({
|
const StatusTag: React.FC<StatusTagProps> = ({
|
||||||
statusValue,
|
statusValue,
|
||||||
download,
|
download,
|
||||||
|
actions = [],
|
||||||
type = 'tag'
|
type = 'tag'
|
||||||
}) => {
|
}) => {
|
||||||
const { text, status } = statusValue;
|
const { text, status } = statusValue;
|
||||||
@@ -70,7 +78,30 @@ const StatusTag: React.FC<StatusTagProps> = ({
|
|||||||
style={{ color: 'rgba(255,255,255,.8)' }}
|
style={{ color: 'rgba(255,255,255,.8)' }}
|
||||||
text={statusValue.message || ''}
|
text={statusValue.message || ''}
|
||||||
size="small"
|
size="small"
|
||||||
|
placement="right"
|
||||||
></CopyButton>
|
></CopyButton>
|
||||||
|
{actions?.map((item) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Divider
|
||||||
|
style={{
|
||||||
|
marginBlock: 5,
|
||||||
|
borderColor: 'rgba(255,255,255,.5)'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tooltip title={item.label} key={item.key} placement="right">
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="text"
|
||||||
|
style={{ color: 'rgba(255,255,255,.8)', padding: 1 }}
|
||||||
|
onClick={item.onClick}
|
||||||
|
>
|
||||||
|
<span className="font-size-14">{item.icon}</span>
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SimpleBar style={{ maxHeight: 200 }}>
|
<SimpleBar style={{ maxHeight: 200 }}>
|
||||||
|
|||||||
@@ -85,6 +85,6 @@ export default {
|
|||||||
'vLLM: For non-GGUF format models, supports x86 Linux only.',
|
'vLLM: For non-GGUF format models, supports x86 Linux only.',
|
||||||
'models.form.backend.voxbox': 'vox-box: For non-GGUF format audio models.',
|
'models.form.backend.voxbox': 'vox-box: For non-GGUF format audio models.',
|
||||||
'models.form.search.gguftips':
|
'models.form.search.gguftips':
|
||||||
'Check GGUF on Mac and Windows (uncheck for seaching audio models).',
|
'If using Mac or Windows as a worker, check GGUF (uncheck for audio models).',
|
||||||
'models.form.button.addlabel': 'Add Label'
|
'models.form.button.addlabel': 'Add Label'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -81,6 +81,6 @@ export default {
|
|||||||
'models.form.backend.vllm': 'vLLM: 用于非 GGUF 格式模型,仅支持 x86 Linux',
|
'models.form.backend.vllm': 'vLLM: 用于非 GGUF 格式模型,仅支持 x86 Linux',
|
||||||
'models.form.backend.voxbox': 'vox-box: 用于非 GGUF 格式的音频模型',
|
'models.form.backend.voxbox': 'vox-box: 用于非 GGUF 格式的音频模型',
|
||||||
'models.form.search.gguftips':
|
'models.form.search.gguftips':
|
||||||
'在 Mac 和 Windows 上勾选 GGUF(搜索音频模型时取消勾选)。',
|
'当 Mac 或 Windows 作 worker 时勾选 GGUF(搜索音频模型时取消勾选)',
|
||||||
'models.form.button.addlabel': '添加标签'
|
'models.form.button.addlabel': '添加标签'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
} from '@/pages/resources/config/types';
|
} from '@/pages/resources/config/types';
|
||||||
import {
|
import {
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
FieldTimeOutlined,
|
|
||||||
HddFilled,
|
HddFilled,
|
||||||
InfoCircleOutlined,
|
InfoCircleOutlined,
|
||||||
ThunderboltFilled
|
ThunderboltFilled
|
||||||
@@ -72,7 +71,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
InstanceStatusMap.Error,
|
InstanceStatusMap.Error,
|
||||||
InstanceStatusMap.Downloading
|
InstanceStatusMap.Downloading
|
||||||
],
|
],
|
||||||
icon: <FieldTimeOutlined />
|
icon: <IconFont type="icon-logs" />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'common.button.delrecreate',
|
label: 'common.button.delrecreate',
|
||||||
@@ -260,6 +259,21 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
>
|
>
|
||||||
{item.state && (
|
{item.state && (
|
||||||
<StatusTag
|
<StatusTag
|
||||||
|
actions={
|
||||||
|
item.state === InstanceStatusMap.Error
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
label: intl.formatMessage({
|
||||||
|
id: 'common.button.viewlog'
|
||||||
|
}),
|
||||||
|
key: 'viewlog',
|
||||||
|
icon: <IconFont type="icon-logs" />,
|
||||||
|
onClick: () =>
|
||||||
|
handleChildSelect('viewlog', item, list)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
}
|
||||||
download={
|
download={
|
||||||
item.state === InstanceStatusMap.Downloading
|
item.state === InstanceStatusMap.Downloading
|
||||||
? { percent: item.download_progress }
|
? { percent: item.download_progress }
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ const ViewCodeModal: React.FC<ViewModalProps> = (props) => {
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
zIndex={3000}
|
||||||
open={open}
|
open={open}
|
||||||
centered={true}
|
centered={true}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
.column-wrapper {
|
.column-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
// border-left: 1px solid var(--ant-color-split);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.simplebar-scrollbar::before {
|
.simplebar-scrollbar::before {
|
||||||
width: var(--scrollbar-size);
|
width: var(--scrollbar-size);
|
||||||
|
background: var(--scrollbar-handle-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.column-wrapper-footer {
|
.column-wrapper-footer {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
// border-left: 1px solid var(--ant-color-split);
|
|
||||||
|
|
||||||
.column-wrapper {
|
.column-wrapper {
|
||||||
border-left: none;
|
border-left: none;
|
||||||
|
|||||||
@@ -4,14 +4,12 @@
|
|||||||
background-color: rgba(255, 255, 255, 100%);
|
background-color: rgba(255, 255, 255, 100%);
|
||||||
padding: 16px @padding;
|
padding: 16px @padding;
|
||||||
border-radius: 0 0 var(--border-radius-base) var(--border-radius-base);
|
border-radius: 0 0 var(--border-radius-base) var(--border-radius-base);
|
||||||
// overflow-y: auto;
|
|
||||||
// height: calc(100vh - 194px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.gguf-tips {
|
.gguf-tips {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 8px 0;
|
padding: 7px 0;
|
||||||
color: var(--ant-color-text-tertiary);
|
color: var(--ant-color-text-tertiary);
|
||||||
|
|
||||||
.warning {
|
.warning {
|
||||||
@@ -24,14 +22,13 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
padding-inline: @padding;
|
padding-inline: @padding;
|
||||||
background: var(--color-white-1);
|
background: var(--color-white-1);
|
||||||
// border-bottom: 1px solid var(--ant-color-split);
|
padding-bottom: 10px;
|
||||||
padding-bottom: 16px;
|
|
||||||
|
|
||||||
.filter {
|
.filter {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 16px;
|
margin-top: 10px;
|
||||||
color: var(--ant-color-text-tertiary);
|
color: var(--ant-color-text-tertiary);
|
||||||
|
|
||||||
:global {
|
:global {
|
||||||
|
|||||||
Reference in New Issue
Block a user