chore: ollama deprecated tips
This commit is contained in:
@@ -3,7 +3,7 @@ import PageTools from '@/components/page-tools';
|
||||
import { PageAction } from '@/config';
|
||||
import useBodyScroll from '@/hooks/use-body-scroll';
|
||||
import { IS_FIRST_LOGIN, writeState } from '@/utils/localstore/index';
|
||||
import { SyncOutlined } from '@ant-design/icons';
|
||||
import { DoubleRightOutlined, SyncOutlined } from '@ant-design/icons';
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import { useIntl, useNavigate } from '@umijs/max';
|
||||
import { Button, Input, Pagination, Select, Space, message } from 'antd';
|
||||
@@ -22,6 +22,18 @@ const PageWrapper = styled.div`
|
||||
margin-block: 32px 16px;
|
||||
`;
|
||||
|
||||
const MoreWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-block: 16px;
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s;
|
||||
&.loading {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
}
|
||||
`;
|
||||
|
||||
const Catalog: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
|
||||
@@ -41,7 +53,7 @@ const Catalog: React.FC = () => {
|
||||
});
|
||||
const [queryParams, setQueryParams] = useState({
|
||||
page: 1,
|
||||
perPage: 12,
|
||||
perPage: 30,
|
||||
search: '',
|
||||
categories: ''
|
||||
});
|
||||
@@ -159,8 +171,6 @@ const Catalog: React.FC = () => {
|
||||
const handleCreateModel = useCallback(
|
||||
async (data: FormData) => {
|
||||
try {
|
||||
console.log('data:', data, openDeployModal);
|
||||
|
||||
const modelData = await createModel({
|
||||
data: {
|
||||
..._.omit(data, ['size', 'quantization'])
|
||||
@@ -213,6 +223,13 @@ const Catalog: React.FC = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const loadMore = () => {
|
||||
fetchData({
|
||||
...queryParams,
|
||||
page: queryParams.page + 1
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
@@ -298,6 +315,18 @@ const Catalog: React.FC = () => {
|
||||
activeId={-1}
|
||||
isFirst={isFirst}
|
||||
></CatalogList>
|
||||
{queryParams.page < dataSource.totalPage && (
|
||||
<MoreWrapper className={dataSource.loading ? 'loading' : ''}>
|
||||
<Button
|
||||
onClick={loadMore}
|
||||
size="middle"
|
||||
type="text"
|
||||
icon={<DoubleRightOutlined rotate={90} />}
|
||||
>
|
||||
{intl.formatMessage({ id: 'common.button.more' })}
|
||||
</Button>
|
||||
</MoreWrapper>
|
||||
)}
|
||||
<PageWrapper>
|
||||
<Pagination
|
||||
hideOnSinglePage={queryParams.perPage === 100}
|
||||
|
||||
@@ -23,6 +23,7 @@ import CompatibilityAlert from './compatible-alert';
|
||||
import DataForm from './data-form';
|
||||
import HFModelFile from './hf-model-file';
|
||||
import ModelCard from './model-card';
|
||||
import OllamaTips from './ollama-tips';
|
||||
import SearchModel from './search-model';
|
||||
import Separator from './separator';
|
||||
import TitleWrapper from './title-wrapper';
|
||||
@@ -360,6 +361,7 @@ const AddModal: FC<AddModalProps> = (props) => {
|
||||
</ColWrapper>
|
||||
</>
|
||||
)}
|
||||
|
||||
<FormContext.Provider
|
||||
value={{
|
||||
isGGUF: isGGUF,
|
||||
@@ -402,6 +404,9 @@ const AddModal: FC<AddModalProps> = (props) => {
|
||||
}
|
||||
>
|
||||
<>
|
||||
{source === modelSourceMap.ollama_library_value && (
|
||||
<OllamaTips></OllamaTips>
|
||||
)}
|
||||
{SEARCH_SOURCE.includes(source) &&
|
||||
deploymentType === 'modelList' && (
|
||||
<TitleWrapper>
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
import AlertBlockInfo from '@/components/alert-info/block';
|
||||
import IconFont from '@/components/icon-font';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button } from 'antd';
|
||||
import { useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
padding-inline: 24px;
|
||||
`;
|
||||
|
||||
const Tips = styled.div`
|
||||
margin-top: 8px !important;
|
||||
ul {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
margin-top: 8px !important;
|
||||
li {
|
||||
position: relative;
|
||||
list-style: none;
|
||||
line-height: 24px;
|
||||
margin: 0 !important;
|
||||
padding-inline: 16px 0 !important;
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--ant-color-text-secondary);
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bold {
|
||||
font-weight: 700;
|
||||
color: var(--ant-color-text);
|
||||
}
|
||||
.notice {
|
||||
margin-top: 8px !important;
|
||||
}
|
||||
`;
|
||||
|
||||
const TitleWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 700;
|
||||
color: var(--ant-color-text);
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
const RenderMessage = () => {
|
||||
const intl = useIntl();
|
||||
return (
|
||||
<Tips>
|
||||
<ul>
|
||||
<li>
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: intl.formatMessage({
|
||||
id: 'models.ollama.deprecated.current'
|
||||
})
|
||||
}}
|
||||
></span>
|
||||
</li>
|
||||
<li>
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: intl.formatMessage({
|
||||
id: 'models.ollama.deprecated.upcoming'
|
||||
})
|
||||
}}
|
||||
></span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="notice">
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: intl.formatMessage({
|
||||
id: 'models.ollama.deprecated.following'
|
||||
})
|
||||
}}
|
||||
></span>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: intl.formatMessage({ id: 'models.ollama.deprecated.issue' })
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
</Tips>
|
||||
);
|
||||
};
|
||||
|
||||
const OllamaTips = () => {
|
||||
const intl = useIntl();
|
||||
const [maxHeight, setMaxHeight] = useState(1);
|
||||
const handleShowMore = () => {
|
||||
setMaxHeight(maxHeight === 1 ? 600 : 1);
|
||||
};
|
||||
return (
|
||||
<Wrapper>
|
||||
<AlertBlockInfo
|
||||
contentStyle={{ paddingInline: 0 }}
|
||||
maxHeight={maxHeight}
|
||||
ellipsis={false}
|
||||
message={<RenderMessage></RenderMessage>}
|
||||
title={
|
||||
<TitleWrapper>
|
||||
<div>
|
||||
{intl.formatMessage({ id: 'models.ollama.deprecated.title' })}
|
||||
</div>
|
||||
<Button
|
||||
onClick={handleShowMore}
|
||||
size="small"
|
||||
type="text"
|
||||
icon={<IconFont type="icon-down"></IconFont>}
|
||||
></Button>
|
||||
</TitleWrapper>
|
||||
}
|
||||
type={'warning'}
|
||||
></AlertBlockInfo>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default OllamaTips;
|
||||
@@ -9,6 +9,7 @@ import { useIntl } from '@umijs/max';
|
||||
import { Form, Typography } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React, { forwardRef, useImperativeHandle, useMemo } from 'react';
|
||||
import OllamaTips from '../components/ollama-tips';
|
||||
import {
|
||||
localPathTipsList,
|
||||
modelSourceMap,
|
||||
@@ -38,6 +39,18 @@ const TargetForm: React.FC<TargetFormProps> = forwardRef((props, ref) => {
|
||||
onOk(data);
|
||||
};
|
||||
|
||||
const handleOnLocalPathBlur = (e: any) => {
|
||||
let { value } = e.target;
|
||||
// remove the last slash: windows or linux
|
||||
const lastChar = value.slice(-1);
|
||||
if (lastChar === '/' || lastChar === '\\') {
|
||||
value = value.slice(0, -1);
|
||||
}
|
||||
form.setFieldsValue({
|
||||
local_path: value
|
||||
});
|
||||
};
|
||||
|
||||
const renderLocalPathFields = () => {
|
||||
return (
|
||||
<>
|
||||
@@ -54,6 +67,7 @@ const TargetForm: React.FC<TargetFormProps> = forwardRef((props, ref) => {
|
||||
<SealInput.Input
|
||||
required
|
||||
label={intl.formatMessage({ id: 'models.form.filePath' })}
|
||||
onBlur={handleOnLocalPathBlur}
|
||||
description={<TooltipList list={localPathTipsList}></TooltipList>}
|
||||
></SealInput.Input>
|
||||
</Form.Item>
|
||||
@@ -119,84 +133,89 @@ const TargetForm: React.FC<TargetFormProps> = forwardRef((props, ref) => {
|
||||
}, [props.source, intl]);
|
||||
|
||||
return (
|
||||
<Form
|
||||
form={form}
|
||||
onFinish={handleOk}
|
||||
preserve={false}
|
||||
style={{ padding: '16px 24px' }}
|
||||
clearOnDestroy={true}
|
||||
initialValues={{
|
||||
source: source
|
||||
}}
|
||||
>
|
||||
<Form.Item<FormData>
|
||||
name="source"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: getRuleMessage('select', 'models.form.source')
|
||||
}
|
||||
]}
|
||||
<div>
|
||||
{source === modelSourceMap.ollama_library_value && (
|
||||
<OllamaTips></OllamaTips>
|
||||
)}
|
||||
<Form
|
||||
form={form}
|
||||
onFinish={handleOk}
|
||||
preserve={false}
|
||||
style={{ padding: '16px 24px' }}
|
||||
clearOnDestroy={true}
|
||||
initialValues={{
|
||||
source: source
|
||||
}}
|
||||
>
|
||||
{
|
||||
<SealSelect
|
||||
disabled
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.source'
|
||||
})}
|
||||
options={sourceOptions}
|
||||
required
|
||||
></SealSelect>
|
||||
}
|
||||
</Form.Item>
|
||||
{renderFieldsBySource}
|
||||
<Form.Item
|
||||
name="worker_id"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: getRuleMessage('select', 'worker', false)
|
||||
}
|
||||
]}
|
||||
>
|
||||
{
|
||||
<SealSelect
|
||||
label="Worker"
|
||||
options={workersList}
|
||||
required
|
||||
></SealSelect>
|
||||
}
|
||||
</Form.Item>
|
||||
{source !== modelSourceMap.local_path_value && (
|
||||
<Form.Item<FormData>
|
||||
name="local_dir"
|
||||
name="source"
|
||||
rules={[
|
||||
{
|
||||
required: false,
|
||||
message: getRuleMessage(
|
||||
'input',
|
||||
'resources.modelfiles.form.localdir'
|
||||
)
|
||||
required: true,
|
||||
message: getRuleMessage('select', 'models.form.source')
|
||||
}
|
||||
]}
|
||||
>
|
||||
<SealInput.Input
|
||||
description={
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: intl.formatMessage({
|
||||
id: 'resources.modelfiles.form.localdir.tips'
|
||||
})
|
||||
}}
|
||||
></span>
|
||||
}
|
||||
label={intl.formatMessage({
|
||||
id: 'resources.modelfiles.form.localdir'
|
||||
})}
|
||||
></SealInput.Input>
|
||||
{
|
||||
<SealSelect
|
||||
disabled
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.source'
|
||||
})}
|
||||
options={sourceOptions}
|
||||
required
|
||||
></SealSelect>
|
||||
}
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form>
|
||||
{renderFieldsBySource}
|
||||
<Form.Item
|
||||
name="worker_id"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: getRuleMessage('select', 'worker', false)
|
||||
}
|
||||
]}
|
||||
>
|
||||
{
|
||||
<SealSelect
|
||||
label="Worker"
|
||||
options={workersList}
|
||||
required
|
||||
></SealSelect>
|
||||
}
|
||||
</Form.Item>
|
||||
{source !== modelSourceMap.local_path_value && (
|
||||
<Form.Item<FormData>
|
||||
name="local_dir"
|
||||
rules={[
|
||||
{
|
||||
required: false,
|
||||
message: getRuleMessage(
|
||||
'input',
|
||||
'resources.modelfiles.form.localdir'
|
||||
)
|
||||
}
|
||||
]}
|
||||
>
|
||||
<SealInput.Input
|
||||
description={
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: intl.formatMessage({
|
||||
id: 'resources.modelfiles.form.localdir.tips'
|
||||
})
|
||||
}}
|
||||
></span>
|
||||
}
|
||||
label={intl.formatMessage({
|
||||
id: 'resources.modelfiles.form.localdir'
|
||||
})}
|
||||
></SealInput.Input>
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user