refactor: playground chat
This commit is contained in:
@@ -19,13 +19,13 @@ import { CHAT_API } from '../apis';
|
|||||||
import { Roles } from '../config';
|
import { Roles } from '../config';
|
||||||
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 MessageInput from './message-input';
|
||||||
import MessageItem from './message-item';
|
import MessageItem from './message-item';
|
||||||
import ReferenceParams from './reference-params';
|
|
||||||
import ViewCodeModal from './view-code-modal';
|
import ViewCodeModal from './view-code-modal';
|
||||||
|
|
||||||
interface MessageProps {
|
interface MessageProps {
|
||||||
parameters: any;
|
parameters: any;
|
||||||
|
modelList: Global.BaseOption<string>[];
|
||||||
ref?: any;
|
ref?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ interface MessageItemProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MessageList: React.FC<MessageProps> = forwardRef((props, ref) => {
|
const MessageList: React.FC<MessageProps> = forwardRef((props, ref) => {
|
||||||
const { parameters } = props;
|
const { parameters, modelList } = props;
|
||||||
const messageId = useRef<number>(0);
|
const messageId = useRef<number>(0);
|
||||||
const [messageList, setMessageList] = useState<MessageItemProps[]>([
|
const [messageList, setMessageList] = useState<MessageItemProps[]>([
|
||||||
{
|
{
|
||||||
@@ -81,11 +81,14 @@ const MessageList: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
const setMessageId = () => {
|
const setMessageId = () => {
|
||||||
messageId.current = messageId.current + 1;
|
messageId.current = messageId.current + 1;
|
||||||
};
|
};
|
||||||
const handleNewMessage = (role?: any) => {
|
const handleNewMessage = (message?: { role: string; content: string }) => {
|
||||||
messageList.push({
|
const newMessage = message || {
|
||||||
role:
|
role:
|
||||||
_.last(messageList)?.role === Roles.User ? Roles.Assistant : Roles.User,
|
_.last(messageList)?.role === Roles.User ? Roles.Assistant : Roles.User,
|
||||||
content: '',
|
content: ''
|
||||||
|
};
|
||||||
|
messageList.push({
|
||||||
|
...newMessage,
|
||||||
uid: messageId.current + 1
|
uid: messageId.current + 1
|
||||||
});
|
});
|
||||||
setMessageId();
|
setMessageId();
|
||||||
@@ -234,6 +237,10 @@ const MessageList: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
setCurrentIsFocus(false);
|
setCurrentIsFocus(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSelectModel = () => {};
|
||||||
|
|
||||||
|
const handlePresetPrompt = () => {};
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
HotKeys.SUBMIT,
|
HotKeys.SUBMIT,
|
||||||
() => {
|
() => {
|
||||||
@@ -324,7 +331,17 @@ const MessageList: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="ground-left-footer">
|
<div className="ground-left-footer">
|
||||||
<ChatFooter
|
<MessageInput
|
||||||
|
loading={loading}
|
||||||
|
handleSubmit={handleSubmit}
|
||||||
|
addMessage={handleNewMessage}
|
||||||
|
handleAbortFetch={handleStopConversation}
|
||||||
|
clearAll={handleClear}
|
||||||
|
setModelSelections={handleSelectModel}
|
||||||
|
presetPrompt={handlePresetPrompt}
|
||||||
|
modelList={modelList}
|
||||||
|
/>
|
||||||
|
{/* <ChatFooter
|
||||||
onClear={handleClear}
|
onClear={handleClear}
|
||||||
onNewMessage={handleNewMessage}
|
onNewMessage={handleNewMessage}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
@@ -334,7 +351,7 @@ const MessageList: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
selectedModel={parameters.model}
|
selectedModel={parameters.model}
|
||||||
hasTokenResult={!!tokenResult}
|
hasTokenResult={!!tokenResult}
|
||||||
feedback={<ReferenceParams usage={tokenResult}></ReferenceParams>}
|
feedback={<ReferenceParams usage={tokenResult}></ReferenceParams>}
|
||||||
></ChatFooter>
|
></ChatFooter> */}
|
||||||
</div>
|
</div>
|
||||||
<ViewCodeModal
|
<ViewCodeModal
|
||||||
open={show}
|
open={show}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
ClearOutlined,
|
ClearOutlined,
|
||||||
ControlOutlined,
|
ControlOutlined,
|
||||||
PictureOutlined,
|
PictureOutlined,
|
||||||
SendOutlined,
|
|
||||||
SwapOutlined
|
SwapOutlined
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
@@ -59,10 +58,15 @@ interface MessageInputProps {
|
|||||||
modelList: Global.BaseOption<string>[];
|
modelList: Global.BaseOption<string>[];
|
||||||
handleSubmit: (params: { role: string; content: string }) => void;
|
handleSubmit: (params: { role: string; content: string }) => void;
|
||||||
handleAbortFetch: () => void;
|
handleAbortFetch: () => void;
|
||||||
setSpans: (value: { span: number; count: number }) => void;
|
updateLayout?: (value: { span: number; count: number }) => void;
|
||||||
clearAll: () => void;
|
clearAll: () => void;
|
||||||
setModelSelections: (modelList: Global.BaseOption<string>[]) => void;
|
setModelSelections: (
|
||||||
|
modelList: (Global.BaseOption<string> & {
|
||||||
|
instanceId: symbol;
|
||||||
|
})[]
|
||||||
|
) => void;
|
||||||
presetPrompt: (list: { role: string; content: string }[]) => void;
|
presetPrompt: (list: { role: string; content: string }[]) => void;
|
||||||
|
addMessage: (message: { role: string; content: string }) => void;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +78,8 @@ const MessageInput: React.FC<MessageInputProps> = ({
|
|||||||
loading,
|
loading,
|
||||||
modelList,
|
modelList,
|
||||||
clearAll,
|
clearAll,
|
||||||
setSpans
|
updateLayout,
|
||||||
|
addMessage
|
||||||
}) => {
|
}) => {
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
@@ -105,7 +110,7 @@ const MessageInput: React.FC<MessageInputProps> = ({
|
|||||||
};
|
};
|
||||||
const handleLayoutChange = (value: { span: number; count: number }) => {
|
const handleLayoutChange = (value: { span: number; count: number }) => {
|
||||||
console.log('layout change:', value);
|
console.log('layout change:', value);
|
||||||
setSpans(value);
|
updateLayout?.(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleToggleRole = () => {
|
const handleToggleRole = () => {
|
||||||
@@ -125,7 +130,8 @@ const MessageInput: React.FC<MessageInputProps> = ({
|
|||||||
const list = value?.map?.((val) => {
|
const list = value?.map?.((val) => {
|
||||||
return {
|
return {
|
||||||
value: val,
|
value: val,
|
||||||
label: val
|
label: val,
|
||||||
|
instanceId: Symbol(val)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
setModelSelections(list);
|
setModelSelections(list);
|
||||||
@@ -134,6 +140,16 @@ const MessageInput: React.FC<MessageInputProps> = ({
|
|||||||
const handleOpenPrompt = () => {
|
const handleOpenPrompt = () => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleAddMessage = () => {
|
||||||
|
console.log('add message');
|
||||||
|
addMessage({ ...message });
|
||||||
|
setMessage({
|
||||||
|
...message,
|
||||||
|
content: ''
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
HotKeys.SUBMIT.join(','),
|
HotKeys.SUBMIT.join(','),
|
||||||
() => {
|
() => {
|
||||||
@@ -167,21 +183,25 @@ const MessageInput: React.FC<MessageInputProps> = ({
|
|||||||
size="middle"
|
size="middle"
|
||||||
onClick={handleOpenPrompt}
|
onClick={handleOpenPrompt}
|
||||||
></Button>
|
></Button>
|
||||||
<Divider type="vertical" style={{ margin: 0 }} />
|
{updateLayout && (
|
||||||
{layoutOptions.map((option) => (
|
<>
|
||||||
<Button
|
<Divider type="vertical" style={{ margin: 0 }} />
|
||||||
key={option.icon}
|
{layoutOptions.map((option) => (
|
||||||
type="text"
|
<Button
|
||||||
icon={<IconFont type={option.icon}></IconFont>}
|
key={option.icon}
|
||||||
size="middle"
|
type="text"
|
||||||
onClick={() => handleLayoutChange(option.value)}
|
icon={<IconFont type={option.icon}></IconFont>}
|
||||||
></Button>
|
size="middle"
|
||||||
))}
|
onClick={() => handleLayoutChange(option.value)}
|
||||||
|
></Button>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="actions">
|
<div className="actions">
|
||||||
<Select
|
<Select
|
||||||
variant="borderless"
|
variant="borderless"
|
||||||
style={{ width: 200 }}
|
style={{ width: 180 }}
|
||||||
placeholder="select models"
|
placeholder="select models"
|
||||||
options={modelList}
|
options={modelList}
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
@@ -190,14 +210,12 @@ const MessageInput: React.FC<MessageInputProps> = ({
|
|||||||
maxTagTextLength={15}
|
maxTagTextLength={15}
|
||||||
onChange={handleUpdateModelSelections}
|
onChange={handleUpdateModelSelections}
|
||||||
></Select>
|
></Select>
|
||||||
|
<Button type="default" size="middle" onClick={handleAddMessage}>
|
||||||
|
{intl.formatMessage({ id: 'common.button.add' })}
|
||||||
|
</Button>
|
||||||
{!loading ? (
|
{!loading ? (
|
||||||
<Button
|
<Button type="primary" onClick={handleSendMessage} size="middle">
|
||||||
style={{ width: 44 }}
|
{intl.formatMessage({ id: 'common.button.submit' })}
|
||||||
type="primary"
|
|
||||||
onClick={handleSendMessage}
|
|
||||||
size="middle"
|
|
||||||
>
|
|
||||||
<SendOutlined />
|
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Col, Row } from 'antd';
|
import { Col, Row } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { ModelSelectionItem } from '../../config/types';
|
||||||
import ModelItem from './model-item';
|
import ModelItem from './model-item';
|
||||||
|
|
||||||
interface ActiveModelsProps {
|
interface ActiveModelsProps {
|
||||||
@@ -7,8 +8,8 @@ interface ActiveModelsProps {
|
|||||||
span: number;
|
span: number;
|
||||||
count: number;
|
count: number;
|
||||||
};
|
};
|
||||||
modelSelections: Global.BaseOption<string>[];
|
modelSelections: ModelSelectionItem[];
|
||||||
setModelRefs: (modelname: string, value: React.MutableRefObject<any>) => void;
|
setModelRefs: (modelname: symbol, value: React.MutableRefObject<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActiveModels: React.FC<ActiveModelsProps> = (props) => {
|
const ActiveModels: React.FC<ActiveModelsProps> = (props) => {
|
||||||
@@ -16,12 +17,13 @@ const ActiveModels: React.FC<ActiveModelsProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<Row gutter={[16, 16]} style={{ height: '100%' }}>
|
<Row gutter={[16, 16]} style={{ height: '100%' }}>
|
||||||
{modelSelections.map((model, index) => (
|
{modelSelections.map((model, index) => (
|
||||||
<Col span={spans.span} key={model.value}>
|
<Col span={spans.span} key={`${model.value || 'empty'}-${model.uid}`}>
|
||||||
<ModelItem
|
<ModelItem
|
||||||
key={model.value}
|
key={`${model.value || 'empty'}-${model.uid}`}
|
||||||
ref={(el: React.MutableRefObject<any>) =>
|
ref={(el: React.MutableRefObject<any>) =>
|
||||||
setModelRefs(model.value, el)
|
setModelRefs(model.instanceId, el)
|
||||||
}
|
}
|
||||||
|
instanceId={model.instanceId}
|
||||||
modelList={modelSelections}
|
modelList={modelSelections}
|
||||||
model={model.value}
|
model={model.value}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import CompareContext from '../../config/compare-context';
|
import CompareContext from '../../config/compare-context';
|
||||||
|
import { ModelSelectionItem } from '../../config/types';
|
||||||
import '../../style/multiple-chat.less';
|
import '../../style/multiple-chat.less';
|
||||||
import MessageInput from '../message-input';
|
import MessageInput from '../message-input';
|
||||||
import ActiveModels from './active-models';
|
import ActiveModels from './active-models';
|
||||||
|
|
||||||
interface MultiCompareProps {
|
interface MultiCompareProps {
|
||||||
modelList: Global.BaseOption<string>[];
|
modelList: (Global.BaseOption<string> & { type?: string })[];
|
||||||
spans?: number;
|
spans?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
||||||
const [loadingStatus, setLoadingStatus] = useState<Record<string, boolean>>(
|
const [loadingStatus, setLoadingStatus] = useState<Record<symbol, boolean>>(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
const [modelSelections, setModelSelections] = useState<
|
const [modelSelections, setModelSelections] = useState<ModelSelectionItem[]>(
|
||||||
Global.BaseOption<string>[]
|
[]
|
||||||
>([]);
|
);
|
||||||
const [globalParams, setGlobalParams] = useState<Record<string, any>>({
|
const [globalParams, setGlobalParams] = useState<Record<string, any>>({
|
||||||
seed: null,
|
seed: null,
|
||||||
stop: null,
|
stop: null,
|
||||||
@@ -31,69 +32,89 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
|||||||
span: 12,
|
span: 12,
|
||||||
count: 2
|
count: 2
|
||||||
});
|
});
|
||||||
|
const cacheModelInstanceList = useRef<any[]>([]);
|
||||||
|
const modelsCounterMap = useRef<Record<string, number>>({});
|
||||||
const modelRefs = useRef<any>({});
|
const modelRefs = useRef<any>({});
|
||||||
const boxHeight = 'calc(100vh - 72px)';
|
const boxHeight = 'calc(100vh - 72px)';
|
||||||
|
|
||||||
const isLoading = useMemo(() => {
|
const isLoading = useMemo(() => {
|
||||||
console.log('loadingStatus========2', loadingStatus);
|
const modelRefList = Object.getOwnPropertySymbols(loadingStatus);
|
||||||
return _.keys(loadingStatus).some(
|
return modelRefList.some((instanceId: symbol) => loadingStatus[instanceId]);
|
||||||
(modelname: string) => loadingStatus[modelname]
|
|
||||||
);
|
|
||||||
}, [loadingStatus]);
|
}, [loadingStatus]);
|
||||||
|
|
||||||
useEffect(() => {
|
const modelFullList = useMemo(() => {
|
||||||
const list = modelList.slice?.(0, spans.count);
|
return modelList.map((item) => {
|
||||||
setModelSelections(list);
|
return {
|
||||||
}, [modelList, spans.count]);
|
...item,
|
||||||
|
disabled: modelSelections.some((model) => model.value === item.value)
|
||||||
useEffect(() => {
|
};
|
||||||
modelRefs.current = {};
|
|
||||||
modelSelections.forEach((item) => {
|
|
||||||
modelRefs.current[item.value] = null;
|
|
||||||
});
|
});
|
||||||
}, [modelSelections]);
|
}, [modelList, modelSelections]);
|
||||||
|
|
||||||
|
const setModelCounter = (model: string) => {
|
||||||
|
modelsCounterMap.current[model] = _.add(modelsCounterMap.current[model], 1);
|
||||||
|
return modelsCounterMap.current[model];
|
||||||
|
};
|
||||||
|
|
||||||
|
const pruneInstanceSymbol = (instanceId: symbol) => {
|
||||||
|
modelRefs.current[instanceId] = null;
|
||||||
|
loadingStatus[instanceId] = false;
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmit = (currentMessage: { role: string; content: string }) => {
|
const handleSubmit = (currentMessage: { role: string; content: string }) => {
|
||||||
const modelRefList = _.keys(modelRefs.current);
|
const modelRefList = Object.getOwnPropertySymbols(modelRefs.current);
|
||||||
modelRefList.forEach(async (modelname: any, index: number) => {
|
modelRefList.forEach((instanceId: symbol) => {
|
||||||
const ref = modelRefs.current[modelname];
|
const ref = modelRefs.current[instanceId];
|
||||||
ref?.submit(currentMessage);
|
ref?.submit(currentMessage);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleAddMessage = (message: { role: string; content: string }) => {
|
||||||
|
const modelRefList = Object.getOwnPropertySymbols(modelRefs.current);
|
||||||
|
modelRefList.forEach((instanceId: symbol) => {
|
||||||
|
const ref = modelRefs.current[instanceId];
|
||||||
|
ref?.setMessageList((preList: any) => {
|
||||||
|
return [...preList, { ...message }];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleAbortFetch = () => {
|
const handleAbortFetch = () => {
|
||||||
_.keys(modelRefs.current).forEach((modelname: string) => {
|
const modelRefList = Object.getOwnPropertySymbols(modelRefs.current);
|
||||||
const ref = modelRefs.current[modelname];
|
modelRefList.forEach((instanceId: symbol) => {
|
||||||
|
const ref = modelRefs.current[instanceId];
|
||||||
ref?.abortFetch();
|
ref?.abortFetch();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const setModelRefs = useCallback(
|
const setModelRefs = useCallback(
|
||||||
(modelname: string, el: React.MutableRefObject<any>) => {
|
(instanceId: symbol, el: React.MutableRefObject<any>) => {
|
||||||
modelRefs.current[modelname] = el;
|
modelRefs.current[instanceId] = el;
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSetLoadingStatus = (modeName: string, status: boolean) => {
|
const handleSetLoadingStatus = (instanceId: symbol, status: boolean) => {
|
||||||
setLoadingStatus((preStatus) => {
|
setLoadingStatus((preStatus) => {
|
||||||
const newState = { ...preStatus };
|
const newState = { ...preStatus };
|
||||||
newState[modeName] = status;
|
newState[instanceId] = status;
|
||||||
return newState;
|
return newState;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClearAll = () => {
|
const handleClearAll = () => {
|
||||||
_.keys(modelRefs.current).forEach((modelname: string) => {
|
const modelRefList = Object.getOwnPropertySymbols(modelRefs.current);
|
||||||
const ref = modelRefs.current[modelname];
|
modelRefList.forEach((instanceId: symbol) => {
|
||||||
|
const ref = modelRefs.current[instanceId];
|
||||||
ref?.clear();
|
ref?.clear();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteModel = (modelname: string) => {
|
const handleDeleteModel = (instanceId: symbol) => {
|
||||||
const newModelList = modelSelections.filter(
|
const newModelList = modelSelections.filter(
|
||||||
(model) => model.value !== modelname
|
(model) => model.instanceId !== instanceId
|
||||||
);
|
);
|
||||||
|
pruneInstanceSymbol(instanceId);
|
||||||
const span = Math.floor(24 / (24 / spans.span - 1));
|
const span = Math.floor(24 / (24 / spans.span - 1));
|
||||||
setSpans({
|
setSpans({
|
||||||
span,
|
span,
|
||||||
@@ -102,27 +123,108 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
|||||||
setModelSelections(newModelList);
|
setModelSelections(newModelList);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateModelSelections = (list: Global.BaseOption<string>[]) => {
|
const handleUpdateModelSelections = (
|
||||||
// set spans.span
|
list: (Global.BaseOption<string> & { instanceId: symbol })[]
|
||||||
const span = Math.floor(24 / list.length);
|
) => {
|
||||||
|
const newList = list.map((item) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
uid: setModelCounter(item.value),
|
||||||
|
instanceId: Symbol(item.value)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const updateList = _.concat(modelSelections, newList);
|
||||||
|
const span = Math.floor(24 / updateList.length);
|
||||||
setSpans({
|
setSpans({
|
||||||
span: span < 8 ? 8 : span,
|
span: span < 8 ? 8 : span,
|
||||||
count: spans.count
|
count: spans.count
|
||||||
});
|
});
|
||||||
setModelSelections(list);
|
setModelSelections(updateList);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePresetPrompt = (list: { role: string; content: string }[]) => {
|
const handlePresetPrompt = (list: { role: string; content: string }[]) => {
|
||||||
const sysMsg = list.filter((item) => item.role === 'system');
|
const sysMsg = list.filter((item) => item.role === 'system');
|
||||||
const userMsg = list.filter((item) => item.role === 'user');
|
const userMsg = list.filter((item) => item.role === 'user');
|
||||||
const modelRefList = _.keys(modelRefs.current);
|
|
||||||
modelRefList.forEach(async (modelname: any) => {
|
const modelRefList = Object.getOwnPropertySymbols(modelRefs.current);
|
||||||
const ref = modelRefs.current[modelname];
|
modelRefList.forEach(async (instanceId: symbol) => {
|
||||||
|
const ref = modelRefs.current[instanceId];
|
||||||
ref?.presetPrompt(userMsg);
|
ref?.presetPrompt(userMsg);
|
||||||
ref?.setSystemMessage(_.get(sysMsg, '0.content', ''));
|
ref?.setSystemMessage(_.get(sysMsg, '0.content', ''));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleUpdateModelList = (spans: { span: number; count: number }) => {
|
||||||
|
const list = modelSelections;
|
||||||
|
// less than count
|
||||||
|
if (list.length < spans.count) {
|
||||||
|
const restCount = spans.count - list.length;
|
||||||
|
const restList = _.slice(modelList, list.length, list.length + restCount);
|
||||||
|
const resultList = Array.from(
|
||||||
|
{ length: restCount - restList.length },
|
||||||
|
(_, index) => {
|
||||||
|
return {
|
||||||
|
label: '',
|
||||||
|
value: '',
|
||||||
|
type: 'empty'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const newResultList = _.concat(restList, resultList).map((item: any) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
uid: setModelCounter(item.value || 'empty'),
|
||||||
|
instanceId:
|
||||||
|
item.type === 'empty' ? Symbol('empty') : Symbol(item.value)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
setModelSelections(_.concat(list, newResultList));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// more than count
|
||||||
|
if (list.length > spans.count) {
|
||||||
|
const newList = list.slice(0, spans.count);
|
||||||
|
setModelSelections(newList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateLayout = (value: { span: number; count: number }) => {
|
||||||
|
setSpans(value);
|
||||||
|
handleUpdateModelList(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
modelRefs.current = {};
|
||||||
|
let list = _.take(modelList, spans.count);
|
||||||
|
if (list.length < spans.count && list.length > 0) {
|
||||||
|
const restCount = spans.count - list.length;
|
||||||
|
const restList = Array.from({ length: restCount }, (_, index) => {
|
||||||
|
return {
|
||||||
|
label: '',
|
||||||
|
value: '',
|
||||||
|
type: 'empty'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
list = _.concat(list, restList);
|
||||||
|
}
|
||||||
|
const resultList = list.map((item: any) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
uid: setModelCounter(item.value || 'empty'),
|
||||||
|
instanceId: item.type === 'empty' ? Symbol('empty') : Symbol(item.value)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
setModelSelections(resultList);
|
||||||
|
}, [modelList]);
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// modelRefs.current = {};
|
||||||
|
// modelSelections.forEach((item) => {
|
||||||
|
// modelRefs.current[item.instanceId] = null;
|
||||||
|
// });
|
||||||
|
// }, [modelSelections]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="multiple-chat" style={{ height: boxHeight }}>
|
<div className="multiple-chat" style={{ height: boxHeight }}>
|
||||||
<div className="chat-list">
|
<div className="chat-list">
|
||||||
@@ -147,12 +249,13 @@ const MultiCompare: React.FC<MultiCompareProps> = ({ modelList }) => {
|
|||||||
<MessageInput
|
<MessageInput
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
handleSubmit={handleSubmit}
|
handleSubmit={handleSubmit}
|
||||||
|
addMessage={handleAddMessage}
|
||||||
handleAbortFetch={handleAbortFetch}
|
handleAbortFetch={handleAbortFetch}
|
||||||
clearAll={handleClearAll}
|
clearAll={handleClearAll}
|
||||||
setSpans={setSpans}
|
updateLayout={updateLayout}
|
||||||
setModelSelections={handleUpdateModelSelections}
|
setModelSelections={handleUpdateModelSelections}
|
||||||
presetPrompt={handlePresetPrompt}
|
presetPrompt={handlePresetPrompt}
|
||||||
modelList={modelList}
|
modelList={modelFullList}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import React, {
|
|||||||
useContext,
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
useImperativeHandle,
|
useImperativeHandle,
|
||||||
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
useState
|
useState
|
||||||
} from 'react';
|
} from 'react';
|
||||||
@@ -30,6 +31,7 @@ import 'simplebar-react/dist/simplebar.min.css';
|
|||||||
import { CHAT_API } from '../../apis';
|
import { CHAT_API } from '../../apis';
|
||||||
import { Roles } from '../../config';
|
import { Roles } from '../../config';
|
||||||
import CompareContext from '../../config/compare-context';
|
import CompareContext from '../../config/compare-context';
|
||||||
|
import { ModelSelectionItem } from '../../config/types';
|
||||||
import '../../style/model-item.less';
|
import '../../style/model-item.less';
|
||||||
import ParamsSettings from '../params-settings';
|
import ParamsSettings from '../params-settings';
|
||||||
import ReferenceParams from '../reference-params';
|
import ReferenceParams from '../reference-params';
|
||||||
@@ -38,7 +40,8 @@ import MessageContent from './message-content';
|
|||||||
|
|
||||||
interface ModelItemProps {
|
interface ModelItemProps {
|
||||||
model: string;
|
model: string;
|
||||||
modelList: Global.BaseOption<string>[];
|
modelList: ModelSelectionItem[];
|
||||||
|
instanceId: symbol;
|
||||||
ref: any;
|
ref: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@ interface MessageItemProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
||||||
({ model, modelList }, ref) => {
|
({ model, modelList, instanceId }, ref) => {
|
||||||
const {
|
const {
|
||||||
spans,
|
spans,
|
||||||
globalParams,
|
globalParams,
|
||||||
@@ -63,7 +66,8 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
const [autoSize, setAutoSize] = useState<{
|
const [autoSize, setAutoSize] = useState<{
|
||||||
minRows: number;
|
minRows: number;
|
||||||
maxRows: number;
|
maxRows: number;
|
||||||
}>({ minRows: 1, maxRows: 1 });
|
focus: boolean;
|
||||||
|
}>({ minRows: 1, maxRows: 1, focus: false });
|
||||||
const [systemMessage, setSystemMessage] = useState<string>('');
|
const [systemMessage, setSystemMessage] = useState<string>('');
|
||||||
const [params, setParams] = useState<Record<string, any>>({});
|
const [params, setParams] = useState<Record<string, any>>({});
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -74,6 +78,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
const contentRef = useRef<any>('');
|
const contentRef = useRef<any>('');
|
||||||
const controllerRef = useRef<any>(null);
|
const controllerRef = useRef<any>(null);
|
||||||
const currentMessageRef = useRef<MessageItemProps>({} as MessageItemProps);
|
const currentMessageRef = useRef<MessageItemProps>({} as MessageItemProps);
|
||||||
|
const systemMessageRef = useRef<any>(null);
|
||||||
|
|
||||||
const setMessageId = () => {
|
const setMessageId = () => {
|
||||||
messageId.current = messageId.current + 1;
|
messageId.current = messageId.current + 1;
|
||||||
@@ -81,7 +86,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
|
|
||||||
const abortFetch = () => {
|
const abortFetch = () => {
|
||||||
controllerRef.current?.abort?.();
|
controllerRef.current?.abort?.();
|
||||||
setLoadingStatus(params.model, false);
|
setLoadingStatus(instanceId, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const joinMessage = (chunk: any) => {
|
const joinMessage = (chunk: any) => {
|
||||||
@@ -118,7 +123,7 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
const { parameters, currentMessage } = currentParams;
|
const { parameters, currentMessage } = currentParams;
|
||||||
if (!parameters.model) return;
|
if (!parameters.model) return;
|
||||||
try {
|
try {
|
||||||
setLoadingStatus(parameters.model, true);
|
setLoadingStatus(instanceId, true);
|
||||||
setMessageId();
|
setMessageId();
|
||||||
|
|
||||||
controllerRef.current?.abort?.();
|
controllerRef.current?.abort?.();
|
||||||
@@ -179,16 +184,15 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
await readStreamData(reader, decoder, (chunk: any) => {
|
await readStreamData(reader, decoder, (chunk: any) => {
|
||||||
joinMessage(chunk);
|
joinMessage(chunk);
|
||||||
});
|
});
|
||||||
setLoadingStatus(params.model, false);
|
setLoadingStatus(instanceId, false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('error=====', error);
|
setLoadingStatus(instanceId, false);
|
||||||
setLoadingStatus(params.model, false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleDropdownAction = useCallback(({ key }: { key: string }) => {
|
const handleDropdownAction = useCallback(({ key }: { key: string }) => {
|
||||||
console.log('key:', key);
|
|
||||||
if (key === 'clear') {
|
if (key === 'clear') {
|
||||||
setMessageList([]);
|
setMessageList([]);
|
||||||
|
setSystemMessage('');
|
||||||
}
|
}
|
||||||
if (key === 'viewCode') {
|
if (key === 'viewCode') {
|
||||||
setShow(true);
|
setShow(true);
|
||||||
@@ -239,7 +243,9 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
setTokenResult(null);
|
setTokenResult(null);
|
||||||
setSystemMessage('');
|
setSystemMessage('');
|
||||||
currentMessageRef.current = {} as MessageItemProps;
|
currentMessageRef.current = {} as MessageItemProps;
|
||||||
|
console.log('clear message', systemMessage);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCloseViewCode = () => {
|
const handleCloseViewCode = () => {
|
||||||
setShow(false);
|
setShow(false);
|
||||||
};
|
};
|
||||||
@@ -270,23 +276,40 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
handleDeleteModel(params.model);
|
handleDeleteModel(instanceId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFocus = () => {
|
const handleFocus = () => {
|
||||||
setAutoSize({
|
setAutoSize({
|
||||||
minRows: 4,
|
minRows: 4,
|
||||||
maxRows: 4
|
maxRows: 4,
|
||||||
|
focus: true
|
||||||
});
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
systemMessageRef.current?.focus?.({
|
||||||
|
cursor: 'end'
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
setAutoSize({
|
setAutoSize({
|
||||||
minRows: 1,
|
minRows: 1,
|
||||||
maxRows: 1
|
maxRows: 1,
|
||||||
|
focus: false
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClearSystemMessage = () => {
|
||||||
|
setSystemMessage('');
|
||||||
|
};
|
||||||
|
|
||||||
|
const modelOptions = useMemo(() => {
|
||||||
|
return modelList.filter((item) => {
|
||||||
|
return item.type !== 'empty';
|
||||||
|
});
|
||||||
|
}, [modelList]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('globalParams:', globalParams.model, globalParams);
|
console.log('globalParams:', globalParams.model, globalParams);
|
||||||
setParams({
|
setParams({
|
||||||
@@ -319,8 +342,9 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
<div className="header">
|
<div className="header">
|
||||||
<span className="title">
|
<span className="title">
|
||||||
<Select
|
<Select
|
||||||
|
style={{ minWidth: '100px' }}
|
||||||
variant="borderless"
|
variant="borderless"
|
||||||
options={modelList}
|
options={modelOptions}
|
||||||
onChange={handleModelChange}
|
onChange={handleModelChange}
|
||||||
value={params.model}
|
value={params.model}
|
||||||
></Select>
|
></Select>
|
||||||
@@ -390,19 +414,50 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
|
|||||||
></Button>
|
></Button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="sys-message">
|
||||||
<Input.TextArea
|
{
|
||||||
variant="filled"
|
<div style={{ display: autoSize.focus ? 'block' : 'none' }}>
|
||||||
placeholder="Type system message here"
|
<Input.TextArea
|
||||||
style={{ borderRadius: '0', border: 'none' }}
|
ref={systemMessageRef}
|
||||||
value={systemMessage}
|
variant="filled"
|
||||||
autoSize={autoSize}
|
placeholder="Type system message here"
|
||||||
onFocus={handleFocus}
|
style={{
|
||||||
onBlur={handleBlur}
|
borderRadius: '0',
|
||||||
allowClear={false}
|
border: 'none'
|
||||||
onChange={(e) => setSystemMessage(e.target.value)}
|
}}
|
||||||
></Input.TextArea>
|
value={systemMessage}
|
||||||
<Divider style={{ margin: '0' }}></Divider>
|
autoSize={{
|
||||||
|
minRows: autoSize.minRows,
|
||||||
|
maxRows: autoSize.maxRows
|
||||||
|
}}
|
||||||
|
onFocus={handleFocus}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
allowClear={false}
|
||||||
|
onChange={(e) => setSystemMessage(e.target.value)}
|
||||||
|
></Input.TextArea>
|
||||||
|
<Divider style={{ margin: '0' }}></Divider>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{!autoSize.focus && (
|
||||||
|
<div className="sys-content-wrap" onClick={handleFocus}>
|
||||||
|
<div className="sys-content">
|
||||||
|
{systemMessage || (
|
||||||
|
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>
|
||||||
|
Type system message here
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{systemMessage && (
|
||||||
|
<Button
|
||||||
|
className="clear-btn"
|
||||||
|
type="text"
|
||||||
|
icon={<CloseOutlined />}
|
||||||
|
size="small"
|
||||||
|
onClick={handleClearSystemMessage}
|
||||||
|
></Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<MessageContent
|
<MessageContent
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Button, Modal, Typography } from 'antd';
|
import { Button, Modal, Typography } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import SimpleBar from 'simplebar-react';
|
||||||
|
import 'simplebar-react/dist/simplebar.min.css';
|
||||||
import promptList from '../config/prompt';
|
import promptList from '../config/prompt';
|
||||||
import '../style/prompt-modal.less';
|
import '../style/prompt-modal.less';
|
||||||
|
|
||||||
@@ -33,46 +35,55 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
|
|||||||
keyboard={false}
|
keyboard={false}
|
||||||
width={660}
|
width={660}
|
||||||
styles={{
|
styles={{
|
||||||
body: {
|
content: {
|
||||||
maxHeight: '550px',
|
padding: '0'
|
||||||
overflow: 'auto'
|
},
|
||||||
|
header: {
|
||||||
|
padding: 'var(--ant-modal-content-padding)',
|
||||||
|
marginBottom: '0'
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
footer={null}
|
footer={null}
|
||||||
>
|
>
|
||||||
<div className="prompt-wrapper">
|
<SimpleBar style={{ maxHeight: '550px' }}>
|
||||||
{promptList.map((item, index) => {
|
<div className="prompt-wrapper">
|
||||||
return (
|
{promptList.map((item, index) => {
|
||||||
<div key={index} className="prompt-item">
|
return (
|
||||||
<h3 className="title">
|
<div key={index} className="prompt-item">
|
||||||
<span className="text">{item.title}</span>
|
<h3 className="title">
|
||||||
<Button
|
<span className="text">{item.title}</span>
|
||||||
size="middle"
|
<Button
|
||||||
type="default"
|
size="middle"
|
||||||
onClick={() => handleSelect(item)}
|
type="default"
|
||||||
>
|
onClick={() => handleSelect(item)}
|
||||||
Use
|
>
|
||||||
</Button>
|
Use
|
||||||
</h3>
|
</Button>
|
||||||
{item.data.map((data, i) => {
|
</h3>
|
||||||
return (
|
{item.data.map((data, i) => {
|
||||||
<div key={i} className="data-item">
|
return (
|
||||||
<span className="role">{data.role}</span>
|
<div key={i} className="data-item">
|
||||||
<span className="prompt">
|
<span className="role">{data.role}</span>
|
||||||
<Typography.Paragraph
|
<span className="prompt">
|
||||||
style={{ margin: 0 }}
|
<Typography.Paragraph
|
||||||
ellipsis={{ rows: 2, expandable: true, symbol: 'more' }}
|
style={{ margin: 0 }}
|
||||||
>
|
ellipsis={{
|
||||||
{data.content}
|
rows: 2,
|
||||||
</Typography.Paragraph>
|
expandable: true,
|
||||||
</span>
|
symbol: 'more'
|
||||||
</div>
|
}}
|
||||||
);
|
>
|
||||||
})}
|
{data.content}
|
||||||
</div>
|
</Typography.Paragraph>
|
||||||
);
|
</span>
|
||||||
})}
|
</div>
|
||||||
</div>
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</SimpleBar>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ interface CompareContextProps {
|
|||||||
systemMessage?: string;
|
systemMessage?: string;
|
||||||
globalParams: Record<string, any>;
|
globalParams: Record<string, any>;
|
||||||
loadingStatus: Record<string, boolean>;
|
loadingStatus: Record<string, boolean>;
|
||||||
handleDeleteModel: (modelname: string) => void;
|
handleDeleteModel: (instanceId: symbol) => void;
|
||||||
setSystemMessage?: (message: string) => void;
|
setSystemMessage?: (message: string) => void;
|
||||||
setGlobalParams: (value: Record<string, any>) => void;
|
setGlobalParams: (value: Record<string, any>) => void;
|
||||||
setLoadingStatus: (modeName: string, status: boolean) => void;
|
setLoadingStatus: (instanceId: symbol, status: boolean) => void;
|
||||||
}
|
}
|
||||||
const CompareContext = React.createContext<CompareContextProps>(
|
const CompareContext = React.createContext<CompareContextProps>(
|
||||||
{} as CompareContextProps
|
{} as CompareContextProps
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export interface ModelSelectionItem extends Global.BaseOption<string> {
|
||||||
|
uid: number;
|
||||||
|
instanceId: symbol;
|
||||||
|
type?: string;
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ import HotKeys from '@/config/hotkeys';
|
|||||||
import { MessageOutlined, OneToOneOutlined } from '@ant-design/icons';
|
import { MessageOutlined, OneToOneOutlined } from '@ant-design/icons';
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
import { useIntl, useSearchParams } from '@umijs/max';
|
import { useIntl, useSearchParams } from '@umijs/max';
|
||||||
import { Button, Divider, Segmented, Space, Tabs, TabsProps } from 'antd';
|
import { Button, Segmented, Space, Tabs, TabsProps } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
@@ -45,7 +45,11 @@ const Playground: React.FC = () => {
|
|||||||
key: 'chat',
|
key: 'chat',
|
||||||
label: 'Chat',
|
label: 'Chat',
|
||||||
children: (
|
children: (
|
||||||
<GroundLeft parameters={params} ref={groundLeftRef}></GroundLeft>
|
<GroundLeft
|
||||||
|
parameters={params}
|
||||||
|
ref={groundLeftRef}
|
||||||
|
modelList={modelList}
|
||||||
|
></GroundLeft>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -146,13 +150,6 @@ const Playground: React.FC = () => {
|
|||||||
collapse: collapse
|
collapse: collapse
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div
|
|
||||||
className={classNames('divider-line', {
|
|
||||||
collapse: collapse
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<Divider type="vertical" />
|
|
||||||
</div>
|
|
||||||
<div className={classNames('params')}>
|
<div className={classNames('params')}>
|
||||||
<div
|
<div
|
||||||
className={classNames('params-box', {
|
className={classNames('params-box', {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.chat-footer {
|
.chat-footer {
|
||||||
display: flex;
|
// display: flex;
|
||||||
align-items: center;
|
// align-items: center;
|
||||||
padding-block: 10px;
|
padding-block: 10px;
|
||||||
padding-right: 32px;
|
padding-right: 32px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: calc(100vh - 136px);
|
height: calc(100vh - 72px);
|
||||||
|
|
||||||
.message-list-wrap {
|
.message-list-wrap {
|
||||||
max-height: calc(100vh - 152px);
|
max-height: calc(100vh - 152px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding-right: 32px;
|
padding-inline: var(--layout-content-inlinepadding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,25 +33,10 @@
|
|||||||
.actions {
|
.actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-within {
|
|
||||||
// border-color: var(--ant-input-active-border-color);
|
|
||||||
// box-shadow: var(--ant-input-active-shadow);
|
|
||||||
// background-color: var(--color-white-1);
|
|
||||||
// transition: all 0.2s ease;
|
|
||||||
// &:hover {
|
|
||||||
// background-color: var(--color-white-1);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
// background: var(--ant-color-fill-secondary);
|
|
||||||
// transition: background 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
padding-inline: 6px 0;
|
padding-inline: 6px 0;
|
||||||
padding-block: 0;
|
padding-block: 0;
|
||||||
|
|||||||
@@ -14,6 +14,42 @@
|
|||||||
border-bottom: 1px solid var(--ant-color-border);
|
border-bottom: 1px solid var(--ant-color-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sys-message {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sys-content-wrap {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: var(--ant-color-fill-tertiary);
|
||||||
|
padding-right: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.clear-btn {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-btn {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
right: 6px;
|
||||||
|
top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sys-content {
|
||||||
|
height: 36px;
|
||||||
|
line-height: 20px;
|
||||||
|
padding: 8px 14px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
.params {
|
.params {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: calc(100vh - 136px);
|
height: calc(100vh - 72px);
|
||||||
|
|
||||||
.collapse {
|
.collapse {
|
||||||
width: 0;
|
width: 0;
|
||||||
@@ -50,6 +50,7 @@
|
|||||||
width: 390px;
|
width: 390px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
border-left: 1px solid var(--ant-color-split);
|
||||||
|
|
||||||
&.collapse {
|
&.collapse {
|
||||||
padding-inline: 0;
|
padding-inline: 0;
|
||||||
@@ -73,7 +74,8 @@
|
|||||||
|
|
||||||
.playground-container {
|
.playground-container {
|
||||||
.ant-pro-page-container-children-container {
|
.ant-pro-page-container-children-container {
|
||||||
padding-right: 0;
|
padding-inline: 0;
|
||||||
|
padding-block: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.compare {
|
&.compare {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
padding: var(--ant-modal-content-padding);
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
|
|
||||||
.text {
|
.text {
|
||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
|
font-size: var(--font-size-base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user