style: transition wrapper height
This commit is contained in:
@@ -23,6 +23,18 @@
|
||||
|
||||
.content-wrapper {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import classNames from 'classnames';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
forwardRef,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useRef,
|
||||
useState
|
||||
} from 'react';
|
||||
import './index.less';
|
||||
|
||||
interface TransitionWrapProps {
|
||||
@@ -7,50 +13,67 @@ interface TransitionWrapProps {
|
||||
header?: React.ReactNode;
|
||||
variant?: 'bordered' | 'filled';
|
||||
children: React.ReactNode;
|
||||
ref?: any;
|
||||
}
|
||||
const TransitionWrapper: React.FC<TransitionWrapProps> = (props) => {
|
||||
const { minHeight = 50, header, variant = 'bordered', children } = props;
|
||||
const [isOpen, setIsOpen] = useState(true);
|
||||
const [height, setHeight] = useState(0);
|
||||
const contentRef = useRef(null);
|
||||
const TransitionWrapper: React.FC<TransitionWrapProps> = forwardRef(
|
||||
(props, ref) => {
|
||||
const { minHeight = 50, header, variant = 'bordered', children } = props;
|
||||
const [isOpen, setIsOpen] = useState(true);
|
||||
const [height, setHeight] = useState(0);
|
||||
const contentRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setHeight(contentRef?.current?.scrollHeight);
|
||||
} else {
|
||||
setHeight(0);
|
||||
}
|
||||
}, [isOpen]);
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setHeight(contentRef?.current?.scrollHeight || 0);
|
||||
} else {
|
||||
setHeight(0);
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
const toggleOpen = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
const toggleOpen = () => {
|
||||
setIsOpen(!isOpen);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('transition-wrapper', {
|
||||
bordered: variant === 'bordered',
|
||||
filled: variant === 'filled'
|
||||
})}
|
||||
>
|
||||
const setHeightByContent = () => {
|
||||
setHeight(contentRef?.current?.scrollHeight || 0);
|
||||
};
|
||||
|
||||
useImperativeHandle(ref, () => {
|
||||
return {
|
||||
setHeightByContent
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={toggleOpen}
|
||||
className="header"
|
||||
style={{
|
||||
height: minHeight
|
||||
}}
|
||||
className={classNames('transition-wrapper', {
|
||||
bordered: variant === 'bordered',
|
||||
filled: variant === 'filled'
|
||||
})}
|
||||
>
|
||||
{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
|
||||
className="content-wrapper"
|
||||
style={{ height: height }}
|
||||
ref={contentRef}
|
||||
>
|
||||
<div className="content">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default TransitionWrapper;
|
||||
|
||||
@@ -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
|
||||
title="CPU"
|
||||
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"
|
||||
title="VRAM"
|
||||
dataIndex="GRAM"
|
||||
key="GRAM"
|
||||
key="VRAM"
|
||||
render={(text, record: NodeItem) => {
|
||||
return (
|
||||
<RenderProgress record={record} dataIndex="gram"></RenderProgress>
|
||||
|
||||
@@ -191,7 +191,7 @@ const Models: React.FC = () => {
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Column title="IP / PID" dataIndex="address" key="address" />
|
||||
<Column title="IP" dataIndex="address" key="address" />
|
||||
<Column
|
||||
title="CPU"
|
||||
dataIndex="CPU"
|
||||
@@ -226,9 +226,9 @@ const Models: React.FC = () => {
|
||||
}}
|
||||
/>
|
||||
<Column
|
||||
title="GRAM"
|
||||
title="VRAM"
|
||||
dataIndex="GRAM"
|
||||
key="GRAM"
|
||||
key="VRAM"
|
||||
render={(text, record: NodeItem) => {
|
||||
return (
|
||||
<RenderProgress record={record} dataIndex="gram"></RenderProgress>
|
||||
|
||||
@@ -32,13 +32,15 @@ const Resources = () => {
|
||||
}}
|
||||
extra={[]}
|
||||
>
|
||||
<Tabs
|
||||
type="card"
|
||||
defaultActiveKey="nodes"
|
||||
items={items}
|
||||
accessKey={activeKey}
|
||||
onChange={handleChangeTab}
|
||||
></Tabs>
|
||||
<div style={{ marginTop: 70 }}>
|
||||
<Tabs
|
||||
type="card"
|
||||
defaultActiveKey="nodes"
|
||||
items={items}
|
||||
accessKey={activeKey}
|
||||
onChange={handleChangeTab}
|
||||
></Tabs>
|
||||
</div>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import CopyButton from '@/components/copy-button';
|
||||
import ModalFooter from '@/components/modal-footer';
|
||||
import SealInput from '@/components/seal-form/seal-input';
|
||||
import SealSelect from '@/components/seal-form/seal-select';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { SyncOutlined } from '@ant-design/icons';
|
||||
import { Form, Modal } from 'antd';
|
||||
@@ -12,6 +13,12 @@ type AddModalProps = {
|
||||
onOk: () => void;
|
||||
onCancel: () => void;
|
||||
};
|
||||
|
||||
const expirationOptions = [
|
||||
{ label: '1 Month', value: '1m' },
|
||||
{ label: '6 Months', value: '6m' },
|
||||
{ label: 'Never', value: 'never' }
|
||||
];
|
||||
const AddModal: React.FC<AddModalProps> = ({
|
||||
title,
|
||||
action,
|
||||
@@ -55,6 +62,13 @@ const AddModal: React.FC<AddModalProps> = ({
|
||||
}
|
||||
></SealInput.Input>
|
||||
</Form.Item>
|
||||
<Form.Item name="expiration" rules={[{ required: true }]}>
|
||||
<SealSelect
|
||||
label="Expiration"
|
||||
required
|
||||
options={expirationOptions}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@ import TransitionWrapper from '@/components/transition';
|
||||
import { EyeInvisibleOutlined } from '@ant-design/icons';
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import { Button, Input } from 'antd';
|
||||
import { useState } from 'react';
|
||||
import { useRef, useState } from 'react';
|
||||
import '../style/ground-left.less';
|
||||
import '../style/system-message-wrap.less';
|
||||
import ChatFooter from './chat-footer';
|
||||
@@ -24,9 +24,9 @@ const MessageList: React.FC = () => {
|
||||
const [systemMessage, setSystemMessage] = useState('');
|
||||
const [show, setShow] = useState(false);
|
||||
const [activeIndex, setActiveIndex] = useState(-1);
|
||||
const systemRef = useRef<any>(null);
|
||||
|
||||
const handleSystemMessageChange = (e: any) => {
|
||||
console.log('system message:', e.target.value);
|
||||
setSystemMessage(e.target.value);
|
||||
};
|
||||
const handleNewMessage = () => {
|
||||
@@ -74,11 +74,16 @@ const MessageList: React.FC = () => {
|
||||
<div className="ground-left">
|
||||
<PageContainer title={false} className="message-list-wrap">
|
||||
<div style={{ marginBottom: 40 }}>
|
||||
<TransitionWrapper header={renderLabel()} variant="filled">
|
||||
<TransitionWrapper
|
||||
header={renderLabel()}
|
||||
variant="filled"
|
||||
ref={systemRef}
|
||||
>
|
||||
<Input.TextArea
|
||||
value={systemMessage}
|
||||
style={{ minHeight: '0px' }}
|
||||
variant="filled"
|
||||
autoSize={true}
|
||||
placeholder="Enter system message here..."
|
||||
onChange={handleSystemMessageChange}
|
||||
></Input.TextArea>
|
||||
</TransitionWrapper>
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user