style: transition wrapper height

This commit is contained in:
jialin
2024-06-06 16:07:25 +08:00
parent c5b41900df
commit 6a60561401
8 changed files with 119 additions and 90 deletions
+13 -1
View File
@@ -23,6 +23,18 @@
.content-wrapper { .content-wrapper {
overflow: hidden; overflow: hidden;
transition: height 300ms ease-in-out; transition: all 300ms ease-in-out;
.content {
height: max-content;
background-color: var(--color-white-1);
border-radius: var(--border-radius-base);
}
}
.ant-input {
/* 只隐藏垂直滚动条轨道 */
&::-webkit-scrollbar-track {
width: 0px !important;
color: transparent;
}
} }
} }
+62 -39
View File
@@ -1,5 +1,11 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { useEffect, useRef, useState } from 'react'; import {
forwardRef,
useEffect,
useImperativeHandle,
useRef,
useState
} from 'react';
import './index.less'; import './index.less';
interface TransitionWrapProps { interface TransitionWrapProps {
@@ -7,50 +13,67 @@ interface TransitionWrapProps {
header?: React.ReactNode; header?: React.ReactNode;
variant?: 'bordered' | 'filled'; variant?: 'bordered' | 'filled';
children: React.ReactNode; children: React.ReactNode;
ref?: any;
} }
const TransitionWrapper: React.FC<TransitionWrapProps> = (props) => { const TransitionWrapper: React.FC<TransitionWrapProps> = forwardRef(
const { minHeight = 50, header, variant = 'bordered', children } = props; (props, ref) => {
const [isOpen, setIsOpen] = useState(true); const { minHeight = 50, header, variant = 'bordered', children } = props;
const [height, setHeight] = useState(0); const [isOpen, setIsOpen] = useState(true);
const contentRef = useRef(null); const [height, setHeight] = useState(0);
const contentRef = useRef(null);
useEffect(() => { useEffect(() => {
if (isOpen) { if (isOpen) {
setHeight(contentRef?.current?.scrollHeight); setHeight(contentRef?.current?.scrollHeight || 0);
} else { } else {
setHeight(0); setHeight(0);
} }
}, [isOpen]); }, [isOpen]);
const toggleOpen = () => { const toggleOpen = () => {
setIsOpen(!isOpen); setIsOpen(!isOpen);
}; };
return ( const setHeightByContent = () => {
<div setHeight(contentRef?.current?.scrollHeight || 0);
className={classNames('transition-wrapper', { };
bordered: variant === 'bordered',
filled: variant === 'filled' useImperativeHandle(ref, () => {
})} return {
> setHeightByContent
};
});
return (
<div <div
onClick={toggleOpen} className={classNames('transition-wrapper', {
className="header" bordered: variant === 'bordered',
style={{ filled: variant === 'filled'
height: minHeight })}
}}
> >
{header} <div
onClick={toggleOpen}
className="header"
style={{
// when content is closed, header should have minHeight
height: minHeight
}}
>
{header}
</div>
<div
className="content-wrapper"
style={{
minHeight: isOpen ? height : 0,
height: isOpen ? 'auto' : 0
}}
ref={contentRef}
>
<div className="content">{children}</div>
</div>
</div> </div>
<div );
className="content-wrapper" }
style={{ height: height }} );
ref={contentRef}
>
<div className="content">{children}</div>
</div>
</div>
);
};
export default TransitionWrapper; export default TransitionWrapper;
+8 -36
View File
@@ -191,44 +191,16 @@ const Models: React.FC = () => {
); );
}} }}
/> />
<Column title="IP / PID" dataIndex="address" key="address" /> <Column title="IP" dataIndex="address" key="address" />
<Column title="Temperature" dataIndex="Temperature" key="Temperature" />
<Column title="Core" dataIndex="core" key="Core" />
<Column title="GPU-Util" dataIndex="gpuUtil" key="gpuUtil" />
<Column <Column
title="CPU" title="VRAM"
dataIndex="CPU"
key="CPU"
render={(text, record: NodeItem) => {
return (
<RenderProgress record={record} dataIndex="cpu"></RenderProgress>
);
}}
/>
<Column
title="Memory"
dataIndex="memory"
key="Memory"
render={(text, record: NodeItem) => {
return (
<RenderProgress
record={record}
dataIndex="memory"
></RenderProgress>
);
}}
/>
<Column
title="GPU"
dataIndex="GPU"
key="GPU"
render={(text, record: NodeItem) => {
return (
<RenderProgress record={record} dataIndex="gpu"></RenderProgress>
);
}}
/>
<Column
title="GRAM"
dataIndex="GRAM" dataIndex="GRAM"
key="GRAM" key="VRAM"
render={(text, record: NodeItem) => { render={(text, record: NodeItem) => {
return ( return (
<RenderProgress record={record} dataIndex="gram"></RenderProgress> <RenderProgress record={record} dataIndex="gram"></RenderProgress>
+3 -3
View File
@@ -191,7 +191,7 @@ const Models: React.FC = () => {
); );
}} }}
/> />
<Column title="IP / PID" dataIndex="address" key="address" /> <Column title="IP" dataIndex="address" key="address" />
<Column <Column
title="CPU" title="CPU"
dataIndex="CPU" dataIndex="CPU"
@@ -226,9 +226,9 @@ const Models: React.FC = () => {
}} }}
/> />
<Column <Column
title="GRAM" title="VRAM"
dataIndex="GRAM" dataIndex="GRAM"
key="GRAM" key="VRAM"
render={(text, record: NodeItem) => { render={(text, record: NodeItem) => {
return ( return (
<RenderProgress record={record} dataIndex="gram"></RenderProgress> <RenderProgress record={record} dataIndex="gram"></RenderProgress>
+9 -7
View File
@@ -32,13 +32,15 @@ const Resources = () => {
}} }}
extra={[]} extra={[]}
> >
<Tabs <div style={{ marginTop: 70 }}>
type="card" <Tabs
defaultActiveKey="nodes" type="card"
items={items} defaultActiveKey="nodes"
accessKey={activeKey} items={items}
onChange={handleChangeTab} accessKey={activeKey}
></Tabs> onChange={handleChangeTab}
></Tabs>
</div>
</PageContainer> </PageContainer>
); );
}; };
@@ -1,6 +1,7 @@
import CopyButton from '@/components/copy-button'; import CopyButton from '@/components/copy-button';
import ModalFooter from '@/components/modal-footer'; import ModalFooter from '@/components/modal-footer';
import SealInput from '@/components/seal-form/seal-input'; import SealInput from '@/components/seal-form/seal-input';
import SealSelect from '@/components/seal-form/seal-select';
import { PageActionType } from '@/config/types'; import { PageActionType } from '@/config/types';
import { SyncOutlined } from '@ant-design/icons'; import { SyncOutlined } from '@ant-design/icons';
import { Form, Modal } from 'antd'; import { Form, Modal } from 'antd';
@@ -12,6 +13,12 @@ type AddModalProps = {
onOk: () => void; onOk: () => void;
onCancel: () => void; onCancel: () => void;
}; };
const expirationOptions = [
{ label: '1 Month', value: '1m' },
{ label: '6 Months', value: '6m' },
{ label: 'Never', value: 'never' }
];
const AddModal: React.FC<AddModalProps> = ({ const AddModal: React.FC<AddModalProps> = ({
title, title,
action, action,
@@ -55,6 +62,13 @@ const AddModal: React.FC<AddModalProps> = ({
} }
></SealInput.Input> ></SealInput.Input>
</Form.Item> </Form.Item>
<Form.Item name="expiration" rules={[{ required: true }]}>
<SealSelect
label="Expiration"
required
options={expirationOptions}
></SealSelect>
</Form.Item>
</Form> </Form>
</Modal> </Modal>
); );
@@ -2,7 +2,7 @@ import TransitionWrapper from '@/components/transition';
import { EyeInvisibleOutlined } from '@ant-design/icons'; import { EyeInvisibleOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components'; import { PageContainer } from '@ant-design/pro-components';
import { Button, Input } from 'antd'; import { Button, Input } from 'antd';
import { useState } from 'react'; import { useRef, useState } from 'react';
import '../style/ground-left.less'; import '../style/ground-left.less';
import '../style/system-message-wrap.less'; import '../style/system-message-wrap.less';
import ChatFooter from './chat-footer'; import ChatFooter from './chat-footer';
@@ -24,9 +24,9 @@ const MessageList: React.FC = () => {
const [systemMessage, setSystemMessage] = useState(''); const [systemMessage, setSystemMessage] = useState('');
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const [activeIndex, setActiveIndex] = useState(-1); const [activeIndex, setActiveIndex] = useState(-1);
const systemRef = useRef<any>(null);
const handleSystemMessageChange = (e: any) => { const handleSystemMessageChange = (e: any) => {
console.log('system message:', e.target.value);
setSystemMessage(e.target.value); setSystemMessage(e.target.value);
}; };
const handleNewMessage = () => { const handleNewMessage = () => {
@@ -74,11 +74,16 @@ const MessageList: React.FC = () => {
<div className="ground-left"> <div className="ground-left">
<PageContainer title={false} className="message-list-wrap"> <PageContainer title={false} className="message-list-wrap">
<div style={{ marginBottom: 40 }}> <div style={{ marginBottom: 40 }}>
<TransitionWrapper header={renderLabel()} variant="filled"> <TransitionWrapper
header={renderLabel()}
variant="filled"
ref={systemRef}
>
<Input.TextArea <Input.TextArea
value={systemMessage} value={systemMessage}
style={{ minHeight: '0px' }}
variant="filled" variant="filled"
autoSize={true}
placeholder="Enter system message here..."
onChange={handleSystemMessageChange} onChange={handleSystemMessageChange}
></Input.TextArea> ></Input.TextArea>
</TransitionWrapper> </TransitionWrapper>
@@ -2,4 +2,5 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
height: 100%;
} }