feat: models list

main
jialin 2 years ago
parent c948110153
commit eeab170970

@ -11,6 +11,14 @@ export default defineConfig({
'root-entry-name': 'variable',
cssVar: true,
hashed: false,
components: {
Input: {
inputFontSize: 12
},
Table: {
cellFontSize: 12
}
},
token: {
colorPrimary: '#2fbf85',
borderRadius: 20,
@ -32,4 +40,4 @@ export default defineConfig({
layout: false,
routes,
npmClient: 'pnpm'
});
}) as any;

@ -1,15 +1,26 @@
.ant-pro-layout {
.ant-pro-sider {
padding: 10px;
&.ant-layout-sider {
background: var(--color-white-1);
}
&.ant-layout-sider {
background: var(--color-white-1);
}
.ant-layout-sider-children {
background-color: var(--color-fill-1);
border-inline: none;
border-radius: 32px;
border-radius: var(--menu-border-radius-base);
padding-inline: 16px;
padding-block-end: 12px;
}
.umi-plugin-layout-right {
width: 100%;
.umi-plugin-layout-action {
padding: 12px;
width: 100%;
border-radius: var(--menu-border-radius-base);
&:hover {
background-color: var(--color-white-1);
}
}
}
}
}
}

@ -0,0 +1,6 @@
.page-tools {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 70px;
}

@ -0,0 +1,33 @@
import { useMemo } from 'react';
import styles from './index.less';
type PageToolsProps = {
left?: React.ReactNode;
right?: React.ReactNode;
marginBottom?: number;
marginTop?: number;
};
const PageTools: React.FC<PageToolsProps> = (props) => {
const { left, right, marginBottom, marginTop } = props;
const newStyle: Record<string, string> = useMemo(() => {
const style: Record<string, string> = {};
if (marginBottom) {
style.marginBottom = `${marginBottom}px`;
}
if (marginTop) {
style.marginTop = `${marginTop}px`;
}
return style;
}, [marginBottom, marginTop]);
return (
<div className={styles['page-tools']} style={newStyle}>
<div className="left">{left}</div>
<div className="right">{right}</div>
</div>
);
};
export default PageTools;

@ -18,6 +18,10 @@
cursor: not-allowed;
&:hover {
border-color: var(--ant-color-border);
:global(.ant-input-search-button) {
border-color: var(--ant-color-border) !important;
color: var(--ant-color-text-description) !important;
}
}
}
@ -70,7 +74,7 @@
align-items: center;
border: none;
box-shadow: none;
height: @inputheight;
height: @inputheight !important;
}
:global(.ant-select-selector) {
border: none !important;
@ -79,7 +83,7 @@
box-shadow: none !important;
}
:global(.ant-select-selection-item) {
height: @inputheight;
height: @inputheight !important;
}
:global(
.ant-select-outlined.ant-select-disabled:not(.ant-select-customize-input)
@ -96,7 +100,7 @@
box-shadow: none;
padding-block: 5px;
padding-inline: 12px;
height: @inputheight;
height: @inputheight !important;
}
:global(.ant-input-number) {
display: flex;
@ -104,7 +108,7 @@
border: none;
box-shadow: none;
padding: 0;
height: @inputheight;
height: @inputheight !important;
}
:global(.ant-input-outlined) {
&.seal-textarea {
@ -115,7 +119,7 @@
background-color: transparent;
}
:global(input.ant-input-number-input) {
height: @inputheight;
height: @inputheight !important;
padding-block: 5px;
padding-inline: 12px;
}
@ -148,6 +152,7 @@
border-left: var(--ant-line-width) var(--ant-line-type)
var(--ant-color-border);
}
:global(.ant-input-number-handler-wrap) {
top: -20px;
height: @wrapheight - 2px;

@ -56,10 +56,11 @@ const SealInputNumber: React.FC<InputNumberProps & SealFormItemProps> = (
<InputNumber
{...rest}
ref={inputRef}
autoComplete="off"
onFocus={handleOnFocus}
onBlur={handleOnBlur}
onInput={handleInput}
onChange={(e) => handleChange(e)}
onChange={handleChange}
></InputNumber>
</Wrapper>
);

@ -65,10 +65,11 @@ const SealInputSearch: React.FC<SearchProps & SealFormItemProps> = (props) => {
<Input.Search
{...rest}
ref={inputRef}
autoComplete="off"
onFocus={handleOnFocus}
onBlur={handleOnBlur}
onSearch={handleSearch}
onChange={(e) => handleChange(e)}
onChange={handleChange}
></Input.Search>
</Wrapper>
);

@ -50,9 +50,10 @@ const SealPassword: React.FC<InputProps & SealFormItemProps> = (props) => {
<Input.Password
{...rest}
ref={inputRef}
autoComplete="off"
onFocus={handleOnFocus}
onBlur={handleOnBlur}
onChange={(e) => handleChange(e)}
onChange={handleChange}
></Input.Password>
</Wrapper>
);

@ -1,7 +1,7 @@
import type { InputProps } from 'antd';
import { Form, Input } from 'antd';
import type { TextAreaProps } from 'antd/es/input/TextArea';
import { useEffect, useRef, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import Wrapper from './components/wrapper';
import SealInputNumber from './input-number';
import SealInputSearch from './input-search';
@ -9,7 +9,16 @@ import SealPassword from './password';
import { SealFormItemProps } from './types';
const SealTextArea: React.FC<TextAreaProps & SealFormItemProps> = (props) => {
const { label, placeholder, style, ...rest } = props;
const {
label,
placeholder,
onChange,
onFocus,
onBlur,
onInput,
style,
...rest
} = props;
const [isFocus, setIsFocus] = useState(false);
const inputRef = useRef<any>(null);
const { status } = Form.Item.useStatus();
@ -20,32 +29,44 @@ const SealTextArea: React.FC<TextAreaProps & SealFormItemProps> = (props) => {
}
}, [props.value]);
const handleClickWrapper = () => {
const handleClickWrapper = useCallback(() => {
if (!props.disabled && !isFocus) {
inputRef.current?.focus?.();
setIsFocus(true);
}
};
}, [props.disabled, isFocus]);
const handleChange = (e: any) => {
props.onChange?.(e);
};
const handleChange = useCallback(
(e: any) => {
onChange?.(e);
},
[onChange]
);
const handleOnFocus = (e: any) => {
setIsFocus(true);
props.onFocus?.(e);
};
const handleOnFocus = useCallback(
(e: any) => {
setIsFocus(true);
onFocus?.(e);
},
[onFocus]
);
const handleOnBlur = (e: any) => {
if (!inputRef.current?.input?.value) {
setIsFocus(false);
props.onBlur?.(e);
}
};
const handleOnBlur = useCallback(
(e: any) => {
if (!inputRef.current?.input?.value) {
setIsFocus(false);
onBlur?.(e);
}
},
[onBlur]
);
const handleInput = (e: any) => {
props.onInput?.(e);
};
const handleInput = useCallback(
(e: any) => {
onInput?.(e);
},
[onInput]
);
return (
<Wrapper
@ -120,10 +141,11 @@ const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
<Input
{...rest}
ref={inputRef}
autoComplete="off"
onInput={handleInput}
onFocus={handleOnFocus}
onBlur={handleOnBlur}
onChange={(e) => handleChange(e)}
onChange={handleChange}
></Input>
</Wrapper>
);

@ -60,7 +60,7 @@ const SealSelect: React.FC<SelectProps & SealFormItemProps> = (props) => {
onFocus={handleOnFocus}
onBlur={handleOnBlur}
onSearch={handleOnSearch}
onChange={(val, options) => handleChange(val, options)}
onChange={handleChange}
>
{children}
</Select>

@ -1,5 +1,7 @@
html {
--color-fill-1: rgba(0, 0, 0, 0.04);
// --color-fill-1: #f3f6fa;
--color-fill-2: #fff;
--color-fill-2: #fff;
--color-fill-3: #f3f6fa;
--menu-border-radius-base: 32px;
@ -11,6 +13,8 @@ html {
--color-bg-light-1: #f0fff6;
--font-size-base: 12px;
--ant-color-fill-secondary: rgba(0, 0, 0, 0.06);
--table-td-radius: 24px;
--checkbox-border-radius: 4px;
// --color-text-1: #000;
--seal-transition-func: cubic-bezier(0, 0, 1, 1);
@ -39,8 +43,12 @@ html {
&.ant-btn {
--ant-button-content-font-size-lg: 13px;
--ant-button-content-font-size: 13px;
--ant-button-content-font-size-sm: 13px;
--ant-button-content-font-size: 12px;
--ant-button-content-font-size-sm: 12px;
}
&.ant-table-css-var {
--ant-table-row-hover-bg: #e6e6e6;
}
}
@ -57,6 +65,7 @@ html {
--ant-input-input-font-size: var(--font-size-base);
--ant-input-input-font-size-lg: var(--font-size-base);
--ant-input-input-font-size-sm: var(--font-size-base);
--ant-input-padding-inline-lg: 14px;
}
.css-var-r0.ant-select-css-var {
--ant-select-option-active-bg: var(--color-fill-1);
@ -69,7 +78,52 @@ body * {
}
body {
.ant-checkbox {
.ant-checkbox-inner {
border-radius: var(--checkbox-border-radius) !important;
}
}
// table
.ant-table-wrapper .ant-table-selection-column {
padding-inline-start: 16px !important;
}
.ant-table-container .ant-table-content table {
border-spacing: 0 20px;
.ant-table-thead th.ant-table-column-sort {
background-color: transparent;
}
.ant-checkbox {
.ant-checkbox-inner::after {
display: flex !important;
}
}
.ant-checkbox-indeterminate .ant-checkbox-inner:after {
display: flex !important;
}
tr > th {
background-color: var(--color-white-1);
border: none;
padding-block: 0px;
}
tr > td {
background-color: var(--color-fill-1);
border-bottom: none;
height: 70px;
&:first-child {
border-top-left-radius: var(--table-td-radius);
border-bottom-left-radius: var(--table-td-radius);
}
&:last-child {
border-top-right-radius: var(--table-td-radius);
border-bottom-right-radius: var(--table-td-radius);
}
}
}
// input
.ant-input-css-var.ant-input {
height: 40px;
}
.ant-input-outlined.ant-input-status-error:not(.ant-input-disabled) {
border: none;
box-shadow: none;

@ -0,0 +1,16 @@
import { useState } from 'react';
export default function useTableRowSelection() {
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const onSelectChange = (selectedRowKeys: React.Key[]) => {
setSelectedRowKeys(selectedRowKeys);
};
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange
};
return rowSelection;
}

@ -1,16 +1,108 @@
import PageTools from '@/components/page-tools';
import useTableRowSelection from '@/hooks/use-table-row-selection';
import { PlusOutlined, SyncOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
import { Button, Input, Progress, Space, Table } from 'antd';
const { Column } = Table;
const dataSource = [
{
key: '1',
name: 'llama3:latest',
createTime: '2021-09-01 12:00:00'
},
{
key: '2',
name: 'meta-llama/Meta-Llama-3-8B',
createTime: '2021-09-01 12:00:00'
},
{
key: '3',
name: 'apple/OpenELM-3B-Instructor',
createTime: '2021-09-01 12:00:00'
}
];
const columns = [
{
title: '姓名',
dataIndex: 'name',
key: 'name'
},
{
title: '年龄',
dataIndex: 'age',
key: 'age'
},
{
title: '住址',
dataIndex: 'address',
key: 'address'
}
];
const Dashboard: React.FC = () => {
const rowSelection = useTableRowSelection();
return (
<PageContainer
ghost
header={{
title: 'Dashboard',
title: 'Dashboard'
}}
extra={[]}
>
<div>Models</div>
<PageTools
marginBottom={22}
left={
<Space>
<Input placeholder="按名称查询" style={{ width: 300 }}></Input>
<Button
type="text"
style={{ color: 'var(--ant-color-primary)' }}
icon={<SyncOutlined></SyncOutlined>}
></Button>
</Space>
}
right={
<div>
<Button icon={<PlusOutlined></PlusOutlined>} type="primary">
Import Module
</Button>
</div>
}
></PageTools>
<Table dataSource={dataSource} rowSelection={rowSelection}>
<Column
title="Model Name"
dataIndex="name"
key="name"
render={(text, record) => {
return (
<>
<span>{text}</span>
<Progress percent={30} strokeColor="var(--ant-color-primary)" />
</>
);
}}
/>
<Column
title="Create Time"
dataIndex="createTime"
key="createTime"
defaultSortOrder="descend"
sortOrder="descend"
sorter={(a, b) => a.createTime - b.createTime}
/>
<Column
title="Operation"
key="operation"
render={(text, record) => {
return <Button size="middle">Open in PlayGround</Button>;
}}
/>
</Table>
</PageContainer>
);
};
export default Dashboard;
export default Dashboard;

@ -1,6 +1,11 @@
import avatar from '@/assets/images/avatar.png';
import logo from '@/assets/images/logo.png';
import { CopyOutlined, DislikeOutlined, EditOutlined, SyncOutlined } from '@ant-design/icons';
import {
CopyOutlined,
DislikeOutlined,
EditOutlined,
SyncOutlined
} from '@ant-design/icons';
import { Button, Space, Tooltip } from 'antd';
import chatStyle from './chat-style.less';
import ChatEmpty from './chatEmpty';

@ -1,26 +1,43 @@
import { Input,Button} from 'antd';
import { useState } from 'react';
import { SendOutlined } from '@ant-design/icons';
import './message-input.less'
import { Button, Input } from 'antd';
import { useState } from 'react';
import './message-input.less';
const MessageInput: React.FC = () => {
const { TextArea } = Input;
const [message, setMessage] = useState('')
const handleInputChange = (value:string) => {
setMessage(value)
}
const [message, setMessage] = useState('');
const handleInputChange = (value: string) => {
setMessage(value);
};
const handleSendMessage = () => {
console.log('send message:', message)
}
console.log('send message:', message);
};
const SendButton: React.FC = () => {
return <Button type="primary" shape="circle" size="middle" icon={<SendOutlined />} onClick={() => handleSendMessage()}></Button>
}
return (
<Button
type="primary"
shape="circle"
size="middle"
icon={<SendOutlined />}
onClick={() => handleSendMessage()}
></Button>
);
};
return (
<div className="messageInput">
<TextArea placeholder='send your message' autoSize={{minRows: 1,maxRows: 6}} onChange={e => handleInputChange(e.target.value)} value={message} size="large" variant='borderless'></TextArea>
<span className="send-btn"><SendButton/></span>
<TextArea
placeholder="send your message"
autoSize={{ minRows: 1, maxRows: 6 }}
onChange={(e) => handleInputChange(e.target.value)}
value={message}
size="large"
variant="borderless"
></TextArea>
<span className="send-btn">
<SendButton />
</span>
</div>
);
};
export default MessageInput;
export default MessageInput;

Loading…
Cancel
Save