style: border radius 8px
This commit is contained in:
+1
-1
@@ -88,7 +88,7 @@ export default defineConfig({
|
||||
},
|
||||
token: {
|
||||
colorPrimary: '#2fbf85',
|
||||
borderRadius: 16,
|
||||
borderRadius: 8,
|
||||
fontSize: 12,
|
||||
motion: true
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 101 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 867 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 896 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 144 KiB |
@@ -1,5 +1,5 @@
|
||||
.cardWrapper {
|
||||
border-radius: var(--border-radius-middle);
|
||||
border-radius: var(--border-radius-small);
|
||||
background-color: var(--color-white-1);
|
||||
box-shadow: var(--box-shadow-base);
|
||||
padding: 10px;
|
||||
|
||||
@@ -45,6 +45,12 @@ const LineChart: React.FC<LineChartProps> = (props) => {
|
||||
style: {
|
||||
lineWidth: 1.5,
|
||||
opacity: 0.8
|
||||
// stroke: (params: any) => {
|
||||
// return (
|
||||
// params.color ||
|
||||
// 'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgba(0, 168, 143,.7) 100%)'
|
||||
// );
|
||||
// }
|
||||
},
|
||||
legend: {
|
||||
color: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
:local(.wrapper) {
|
||||
@wrapheight: 54px;
|
||||
@inputheight: 32px;
|
||||
@borderRadius: 20px;
|
||||
@borderRadius: 8px;
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
+11
-17
@@ -7,7 +7,7 @@ html {
|
||||
// --color-fill-1: #fff;
|
||||
--color-fill-2: #fff;
|
||||
--color-fill-3: #f3f6fa;
|
||||
--menu-border-radius-base: 20px;
|
||||
--menu-border-radius-base: 8px;
|
||||
--border-radius-base: 16px;
|
||||
--border-radius-middle: 20px;
|
||||
--border-radius-small: 8px;
|
||||
@@ -20,11 +20,11 @@ html {
|
||||
--font-size-large: 16px;
|
||||
--font-size-middle: 14px;
|
||||
--ant-color-fill-secondary: rgba(0, 0, 0, 6%);
|
||||
--table-td-radius: 20px;
|
||||
--table-td-radius: 8px;
|
||||
--checkbox-border-radius: 4px;
|
||||
--ant-table-cell-padding-inline: 16px;
|
||||
--ant-table-cell-padding-block: 16px;
|
||||
--ant-table-header-border-radius: 16px;
|
||||
--ant-table-cell-padding-inline: 8px;
|
||||
--ant-table-cell-padding-block: 8px;
|
||||
--ant-table-header-border-radius: 8px;
|
||||
--ant-table-header-split-color: #f0f0f0;
|
||||
--ant-table-row-selected-bg: #f0fff6;
|
||||
--ant-table-row-selected-hover-bg: #d8f2e4;
|
||||
@@ -51,7 +51,7 @@ html {
|
||||
&.ant-menu-css-var {
|
||||
--ant-menu-item-height: 46px;
|
||||
--ant-menu-item-selected-bg: var(--color-white-1);
|
||||
--ant-menu-item-border-radius: 16px;
|
||||
--ant-menu-item-border-radius: 8px;
|
||||
--ant-menu-item-selected-color: var(--ant-color-primary);
|
||||
--ant-menu-item-hover-bg: var(--color-white-1);
|
||||
--ant-menu-item-color: var(--color-text-1);
|
||||
@@ -66,7 +66,7 @@ html {
|
||||
--ant-font-size-xl: 20px;
|
||||
--ant-font-size: var(--font-size-base);
|
||||
--ant-padding-sm: 14px;
|
||||
--ant-border-radius-lg: 16px;
|
||||
--ant-border-radius-lg: 8px;
|
||||
--ant-color-error: #ff4d4f;
|
||||
--ant-color-bg-mask: rgba(0, 0, 0, 35%);
|
||||
--ant-color-border: rgb(217 217 217 / 50%);
|
||||
@@ -98,7 +98,7 @@ html {
|
||||
.css-var-rh.ant-menu-css-var {
|
||||
--ant-menu-item-height: 46px;
|
||||
--ant-menu-item-selected-bg: var(--color-white-1);
|
||||
--ant-menu-item-border-radius: 20px;
|
||||
--ant-menu-item-border-radius: 8px;
|
||||
--ant-menu-item-selected-color: var(--ant-color-primary);
|
||||
--ant-menu-item-hover-bg: var(--color-white-1);
|
||||
--ant-menu-item-color: var(--color-text-1);
|
||||
@@ -290,7 +290,7 @@ body {
|
||||
.ant-pro-sider {
|
||||
.ant-menu {
|
||||
.ant-menu-item {
|
||||
border-radius: 16px;
|
||||
border-radius: var(--border-radius-small);
|
||||
|
||||
&:active {
|
||||
background-color: var(--ant-menu-item-selected-bg);
|
||||
@@ -307,6 +307,7 @@ body {
|
||||
|
||||
.ant-menu-item.ant-menu-item-selected:hover {
|
||||
color: var(--ant-color-primary);
|
||||
background-color: var(--ant-menu-item-selected-bg);
|
||||
}
|
||||
|
||||
.ant-menu-item.ant-menu-item-selected {
|
||||
@@ -329,12 +330,7 @@ body {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
// background: radial-gradient(
|
||||
// circle,
|
||||
// rgba(47, 191, 133, 0.02),
|
||||
// rgba(55, 125, 184, 0.2)
|
||||
// );
|
||||
background: url('./assets/images/bg.png') center center no-repeat;
|
||||
background: url('./assets/images/bg-11.png') center center no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
&::after {
|
||||
@@ -345,8 +341,6 @@ body {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
backdrop-filter: blur(100px);
|
||||
filter: blur(100px);
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,9 @@ export default {
|
||||
'apikeys.form.expiretime': 'Expiration',
|
||||
'apikeys.table.name': 'Key Name',
|
||||
'apikeys.table.save.tips':
|
||||
'Make sure to copy your key immediately. You will not be able to see it again.'
|
||||
'Make sure to copy your key immediately. You will not be able to see it again.',
|
||||
'apikeys.form.expiration.7days': '7 days',
|
||||
'apikeys.form.expiration.1month': '1 month',
|
||||
'apikeys.form.expiration.6months': '6 months',
|
||||
'apikeys.form.expiration.never': 'never'
|
||||
};
|
||||
|
||||
@@ -4,5 +4,9 @@ export default {
|
||||
'apikeys.button.create': '新建 API 密钥',
|
||||
'apikeys.form.expiretime': '过期时间',
|
||||
'apikeys.table.name': '密钥名称',
|
||||
'apikeys.table.save.tips': '确保立即复制您的密钥。您将无法再次看到它!'
|
||||
'apikeys.table.save.tips': '确保立即复制您的密钥。您将无法再次看到它!',
|
||||
'apikeys.form.expiration.7days': '7天',
|
||||
'apikeys.form.expiration.1month': '1个月',
|
||||
'apikeys.form.expiration.6months': '6个月',
|
||||
'apikeys.form.expiration.never': '永不'
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import ModalFooter from '@/components/modal-footer';
|
||||
import SealInput from '@/components/seal-form/seal-input';
|
||||
import SealSelect from '@/components/seal-form/seal-select';
|
||||
import { PageAction } from '@/config';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { SyncOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form, Modal } from 'antd';
|
||||
import { Form, Modal, Select } from 'antd';
|
||||
import { expirationOptions } from '../config';
|
||||
import { FormData } from '../config/types';
|
||||
|
||||
@@ -25,14 +25,12 @@ const AddModal: React.FC<AddModalProps> = ({
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const intl = useIntl();
|
||||
const Suffix = (
|
||||
<SyncOutlined
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color: '#1677ff'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
if (action === PageAction.CREATE && open) {
|
||||
form.setFieldsValue({
|
||||
expires_in: 1
|
||||
});
|
||||
}
|
||||
|
||||
const handleSumit = () => {
|
||||
form.submit();
|
||||
@@ -91,8 +89,15 @@ const AddModal: React.FC<AddModalProps> = ({
|
||||
<SealSelect
|
||||
label={intl.formatMessage({ id: 'apikeys.form.expiretime' })}
|
||||
required
|
||||
options={expirationOptions}
|
||||
></SealSelect>
|
||||
>
|
||||
{expirationOptions.map((option) => {
|
||||
return (
|
||||
<Select.Option key={option.value} value={option.value}>
|
||||
{intl.formatMessage({ id: option.label })}
|
||||
</Select.Option>
|
||||
);
|
||||
})}
|
||||
</SealSelect>
|
||||
</Form.Item>
|
||||
<Form.Item<FormData> name="description" rules={[{ required: false }]}>
|
||||
<SealInput.TextArea
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
export const expirationOptions = [
|
||||
{ label: '7 days', type: 'day', value: 7 },
|
||||
{ label: '1 month', type: 'month', value: 1 },
|
||||
{ label: '6 months', type: 'month', value: 6 },
|
||||
// { label: '1 year', type: 'year', value: 1 },
|
||||
{ label: 'never', type: 'never', value: -1 }
|
||||
{ label: 'apikeys.form.expiration.7days', type: 'day', value: 7 },
|
||||
{ label: 'apikeys.form.expiration.1month', type: 'month', value: 1 },
|
||||
{ label: 'apikeys.form.expiration.6months', type: 'month', value: 6 },
|
||||
{ label: 'apikeys.form.expiration.never', type: 'never', value: -1 }
|
||||
];
|
||||
|
||||
@@ -5,10 +5,25 @@ import { useContext, useEffect, useState } from 'react';
|
||||
import { DashboardContext } from '../config/dashboard-context';
|
||||
|
||||
const TypeKeyMap = {
|
||||
cpu: 'CPU',
|
||||
memory: 'Memory',
|
||||
gpu: 'GPU',
|
||||
gpu_memory: 'VRAM'
|
||||
cpu: {
|
||||
label: 'CPU',
|
||||
color:
|
||||
'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgba(0, 168, 143,.7) 100%)'
|
||||
},
|
||||
memory: {
|
||||
label: 'Memory',
|
||||
color:
|
||||
'linear-gradient(90deg,rgba(249, 248, 113,.8) 0%,rgba(255, 199, 92,0.7) 100%)'
|
||||
},
|
||||
gpu: {
|
||||
label: 'GPU',
|
||||
color: 'rgba(84, 204, 152,0.8)'
|
||||
},
|
||||
gpu_memory: {
|
||||
label: 'VRAM',
|
||||
color:
|
||||
'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgba(0, 168, 143,.7) 100%)'
|
||||
}
|
||||
};
|
||||
|
||||
const UtilizationOvertime: React.FC = () => {
|
||||
@@ -44,7 +59,8 @@ const UtilizationOvertime: React.FC = () => {
|
||||
return {
|
||||
value: _.round(item.value, 2) || 0,
|
||||
time: dayjs(item.timestamp * 1000).format('HH:mm:ss'),
|
||||
type: _.get(TypeKeyMap, type, '')
|
||||
type: _.get(TypeKeyMap, [type, 'label'], ''),
|
||||
color: 'red'
|
||||
};
|
||||
});
|
||||
list.push(...dataList);
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
callHuggingfaceQuickSearch,
|
||||
queryHuggingfaceModelFiles
|
||||
} from '../apis';
|
||||
import { ollamaModelOptions } from '../config';
|
||||
import { FormData, ListItem } from '../config/types';
|
||||
|
||||
type AddModalProps = {
|
||||
@@ -99,7 +100,7 @@ const AddModal: React.FC<AddModalProps> = (props) => {
|
||||
const handleOnSearchRepo = async (text: string) => {
|
||||
try {
|
||||
const params = {
|
||||
q: text,
|
||||
q: `${text} gguf`,
|
||||
type: 'model'
|
||||
};
|
||||
const res = await callHuggingfaceQuickSearch(params);
|
||||
@@ -164,7 +165,7 @@ const AddModal: React.FC<AddModalProps> = (props) => {
|
||||
]}
|
||||
>
|
||||
<SealAutoComplete
|
||||
showSearch
|
||||
filterOption
|
||||
label={intl.formatMessage({ id: 'models.form.filename' })}
|
||||
required
|
||||
options={fileOptions}
|
||||
@@ -220,10 +221,12 @@ const AddModal: React.FC<AddModalProps> = (props) => {
|
||||
}
|
||||
]}
|
||||
>
|
||||
<SealInput.Input
|
||||
label={intl.formatMessage({ id: 'models.table.name' })}
|
||||
<SealAutoComplete
|
||||
filterOption
|
||||
label="Ollama Model"
|
||||
required
|
||||
></SealInput.Input>
|
||||
options={ollamaModelOptions}
|
||||
></SealAutoComplete>
|
||||
</Form.Item>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,35 +1,14 @@
|
||||
import { StatusMaps } from '@/config';
|
||||
|
||||
export const modelInstanceCols = [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: 'Create Time',
|
||||
dataIndex: 'createTime',
|
||||
key: 'createTime'
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
dataIndex: 'status',
|
||||
key: 'status'
|
||||
},
|
||||
{
|
||||
title: 'Utilization',
|
||||
dataIndex: 'utilization',
|
||||
key: 'utilization'
|
||||
},
|
||||
{
|
||||
title: 'Host Name',
|
||||
dataIndex: 'hostName',
|
||||
key: 'hostName'
|
||||
},
|
||||
{
|
||||
title: 'Operation',
|
||||
key: 'Operation'
|
||||
}
|
||||
export const ollamaModelOptions = [
|
||||
{ label: 'llama3', value: 'llama3' },
|
||||
{ label: 'gemma', value: 'gemma' },
|
||||
{ label: 'mistral', value: 'mistral' },
|
||||
{ label: 'qwen', value: 'qwen' },
|
||||
{ label: 'llama2', value: 'llama2' },
|
||||
{ label: 'phi3', value: 'phi3' },
|
||||
{ label: 'codellama', value: 'codellama' },
|
||||
{ label: 'deepseek-coder', value: 'deepseek-coder' }
|
||||
];
|
||||
|
||||
export const status: any = {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
overflow-y: auto;
|
||||
|
||||
.ant-pro-page-container-children-container {
|
||||
padding-inline: 26px;
|
||||
padding-inline: 16px 26px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@ const AddModal: React.FC<AddModalProps> = ({
|
||||
...data,
|
||||
is_admin: data?.is_admin ? UserRoles.ADMIN : UserRoles.USER
|
||||
});
|
||||
} else if (action === PageAction.CREATE && open) {
|
||||
form.setFieldsValue({
|
||||
is_admin: UserRoles.USER
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequestConfig } from '@umijs/max';
|
||||
import { RequestConfig, history } from '@umijs/max';
|
||||
import { message } from 'antd';
|
||||
|
||||
const NoBaseURLAPIs = ['/auth', '/v1-openai'];
|
||||
@@ -6,13 +6,16 @@ const NoBaseURLAPIs = ['/auth', '/v1-openai'];
|
||||
export const requestConfig: RequestConfig = {
|
||||
errorConfig: {
|
||||
errorThrower: (res: any) => {
|
||||
console.log('errorThrower+++++++++++++++', res);
|
||||
// to do something
|
||||
},
|
||||
errorHandler: (error: any, opts: any) => {
|
||||
if (opts?.skipErrorHandler) throw error;
|
||||
const { message: errorMessage, response } = error;
|
||||
const errMsg = response?.data?.message || errorMessage;
|
||||
message.error(errMsg);
|
||||
if (response.status === 401) {
|
||||
history.push('/login', { replace: true });
|
||||
}
|
||||
console.log('errorHandler+++++++++++++++', error, opts);
|
||||
}
|
||||
},
|
||||
@@ -28,6 +31,7 @@ export const requestConfig: RequestConfig = {
|
||||
],
|
||||
responseInterceptors: [
|
||||
(response) => {
|
||||
// to do something
|
||||
return response;
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user