fix: textarea scroll bar, deactive count message
This commit is contained in:
+16
-2
@@ -13,6 +13,7 @@ import {
|
|||||||
writeState
|
writeState
|
||||||
} from '@/utils/localstore/index';
|
} from '@/utils/localstore/index';
|
||||||
import { RequestConfig, history } from '@umijs/max';
|
import { RequestConfig, history } from '@umijs/max';
|
||||||
|
import { message } from 'antd';
|
||||||
|
|
||||||
const loginPath = '/login';
|
const loginPath = '/login';
|
||||||
|
|
||||||
@@ -51,13 +52,26 @@ export async function getInitialState(): Promise<{
|
|||||||
const fetchUserInfo = async (): Promise<Global.UserInfo> => {
|
const fetchUserInfo = async (): Promise<Global.UserInfo> => {
|
||||||
try {
|
try {
|
||||||
const data = await queryCurrentUserState({
|
const data = await queryCurrentUserState({
|
||||||
skipErrorHandler: true
|
skipErrorHandler: false
|
||||||
});
|
});
|
||||||
if (data.is_admin) {
|
if (data.is_admin) {
|
||||||
getUpdateCheck();
|
getUpdateCheck();
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
|
const data = error?.response?.data;
|
||||||
|
if (data?.code === 401) {
|
||||||
|
message.error({
|
||||||
|
content: (
|
||||||
|
<div>
|
||||||
|
<span>{data?.message || 'Please login again.'}</span>
|
||||||
|
<br />
|
||||||
|
<div>Please contact the administrator.</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
duration: 5
|
||||||
|
});
|
||||||
|
}
|
||||||
history.push(loginPath);
|
history.push(loginPath);
|
||||||
}
|
}
|
||||||
return {} as Global.UserInfo;
|
return {} as Global.UserInfo;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const LabelWrapper = styled.div.attrs({
|
|||||||
|
|
||||||
interface InputTextareaProps extends TextAreaProps {
|
interface InputTextareaProps extends TextAreaProps {
|
||||||
scaleSize?: boolean;
|
scaleSize?: boolean;
|
||||||
|
alwaysFocus?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SealTextArea: React.FC<InputTextareaProps & SealFormItemProps> = (
|
const SealTextArea: React.FC<InputTextareaProps & SealFormItemProps> = (
|
||||||
@@ -45,6 +46,7 @@ const SealTextArea: React.FC<InputTextareaProps & SealFormItemProps> = (
|
|||||||
addAfter,
|
addAfter,
|
||||||
trim,
|
trim,
|
||||||
scaleSize,
|
scaleSize,
|
||||||
|
alwaysFocus,
|
||||||
...rest
|
...rest
|
||||||
} = props;
|
} = props;
|
||||||
const [isFocus, setIsFocus] = useState(false);
|
const [isFocus, setIsFocus] = useState(false);
|
||||||
@@ -119,7 +121,7 @@ const SealTextArea: React.FC<InputTextareaProps & SealFormItemProps> = (
|
|||||||
<Wrapper
|
<Wrapper
|
||||||
status={status}
|
status={status}
|
||||||
label={<LabelWrapper>{label}</LabelWrapper>}
|
label={<LabelWrapper>{label}</LabelWrapper>}
|
||||||
isFocus={isFocus}
|
isFocus={alwaysFocus || isFocus}
|
||||||
required={required}
|
required={required}
|
||||||
description={description}
|
description={description}
|
||||||
className="seal-textarea-wrapper"
|
className="seal-textarea-wrapper"
|
||||||
@@ -134,7 +136,7 @@ const SealTextArea: React.FC<InputTextareaProps & SealFormItemProps> = (
|
|||||||
spellCheck={rest.spellCheck ?? false}
|
spellCheck={rest.spellCheck ?? false}
|
||||||
autoSize={autoSize}
|
autoSize={autoSize}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
style={{ minHeight: '80px', ...style }}
|
style={{ ...style }}
|
||||||
className="seal-textarea"
|
className="seal-textarea"
|
||||||
onFocus={handleOnFocus}
|
onFocus={handleOnFocus}
|
||||||
onBlur={handleOnBlur}
|
onBlur={handleOnBlur}
|
||||||
|
|||||||
@@ -163,6 +163,12 @@ const InputWrapper = styled.div`
|
|||||||
.seal-textarea-wrapper {
|
.seal-textarea-wrapper {
|
||||||
height: auto;
|
height: auto;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
|
.ant-input-outlined {
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
overflow-y: auto !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.ant-input-textarea-allow-clear.ant-input-affix-wrapper {
|
.ant-input-textarea-allow-clear.ant-input-affix-wrapper {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@@ -317,6 +317,7 @@ const VersionsForm: React.FC<AddModalProps> = ({
|
|||||||
style={{ marginBottom: 0 }}
|
style={{ marginBottom: 0 }}
|
||||||
>
|
>
|
||||||
<SealInput.TextArea
|
<SealInput.TextArea
|
||||||
|
allowClear
|
||||||
label={intl.formatMessage({ id: 'backend.runCommand' })}
|
label={intl.formatMessage({ id: 'backend.runCommand' })}
|
||||||
></SealInput.TextArea>
|
></SealInput.TextArea>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import SealInput from '@/components/seal-form/seal-input';
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
|
import SealTextArea from '@/components/seal-form/seal-textarea';
|
||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Form } from 'antd';
|
import { Form } from 'antd';
|
||||||
@@ -85,9 +86,10 @@ const ClusterForm: React.FC<AddModalProps> = forwardRef(
|
|||||||
></CloudProvider>
|
></CloudProvider>
|
||||||
)}
|
)}
|
||||||
<Form.Item<FormData> name="description" rules={[{ required: false }]}>
|
<Form.Item<FormData> name="description" rules={[{ required: false }]}>
|
||||||
<SealInput.TextArea
|
<SealTextArea
|
||||||
|
autoSize={{ minRows: 4, maxRows: 6 }}
|
||||||
label={intl.formatMessage({ id: 'common.table.description' })}
|
label={intl.formatMessage({ id: 'common.table.description' })}
|
||||||
></SealInput.TextArea>
|
></SealTextArea>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
// evaluate the form data when select a model file
|
// evaluate the form data when select a model file
|
||||||
// TODO: reset backend related fields when select a GGUF file
|
// TODO: reset backend related fields when select a GGUF file
|
||||||
if (item.fakeName) {
|
if (item.fakeName) {
|
||||||
// onSelectFile(item, modelInfo, manual);
|
onSelectFile(item, modelInfo, manual);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import IconFont from '@/components/icon-font';
|
|||||||
import AutoComplete from '@/components/seal-form/auto-complete';
|
import AutoComplete from '@/components/seal-form/auto-complete';
|
||||||
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 SealSelect from '@/components/seal-form/seal-select';
|
||||||
|
import SealTextArea from '@/components/seal-form/seal-textarea';
|
||||||
import TooltipList from '@/components/tooltip-list';
|
import TooltipList from '@/components/tooltip-list';
|
||||||
import useAppUtils from '@/hooks/use-app-utils';
|
import useAppUtils from '@/hooks/use-app-utils';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
@@ -127,7 +128,6 @@ const BackendFields: React.FC = () => {
|
|||||||
<SealInput.Input
|
<SealInput.Input
|
||||||
required
|
required
|
||||||
allowClear
|
allowClear
|
||||||
scaleSize={true}
|
|
||||||
label={intl.formatMessage({ id: 'backend.imageName' })}
|
label={intl.formatMessage({ id: 'backend.imageName' })}
|
||||||
></SealInput.Input>
|
></SealInput.Input>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -140,15 +140,17 @@ const BackendFields: React.FC = () => {
|
|||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<SealInput.TextArea
|
<SealTextArea
|
||||||
|
allowClear
|
||||||
required
|
required
|
||||||
scaleSize={true}
|
scaleSize={true}
|
||||||
allowClear
|
alwaysFocus={true}
|
||||||
|
autoSize={{ minRows: 2, maxRows: 4 }}
|
||||||
label={intl.formatMessage({ id: 'backend.runCommand' })}
|
label={intl.formatMessage({ id: 'backend.runCommand' })}
|
||||||
placeholder={intl.formatMessage({
|
placeholder={intl.formatMessage({
|
||||||
id: 'models.form.runCommandPlaceholder'
|
id: 'models.form.runCommandPlaceholder'
|
||||||
})}
|
})}
|
||||||
></SealInput.TextArea>
|
></SealTextArea>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
import CollapsePanel from '@/pages/_components/collapse-panel';
|
import CollapsePanel from '@/pages/_components/collapse-panel';
|
||||||
import { useWrapperContext } from '@/pages/_components/column-wrapper/use-wrapper-context';
|
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Form } from 'antd';
|
import { Form } from 'antd';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
@@ -54,7 +53,6 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
|||||||
onValuesChange,
|
onValuesChange,
|
||||||
onOk
|
onOk
|
||||||
} = props;
|
} = props;
|
||||||
const { scrollToTarget, scrollToBottom } = useWrapperContext();
|
|
||||||
const { backendOptions, getBackendOptions } = useQueryBackends();
|
const { backendOptions, getBackendOptions } = useQueryBackends();
|
||||||
const { getGPUOptionList, gpuOptions } = useGenerateGPUOptions();
|
const { getGPUOptionList, gpuOptions } = useGenerateGPUOptions();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ export const useGenerateGPUOptions = () => {
|
|||||||
return gpuSelectorList;
|
return gpuSelectorList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const generateWorkerSelectorOptions = (workerList: WorkerListItem[]) => {};
|
||||||
|
|
||||||
const getGPUOptionList = async (params?: {
|
const getGPUOptionList = async (params?: {
|
||||||
clusterId: number;
|
clusterId: number;
|
||||||
}): Promise<CascaderOption[]> => {
|
}): Promise<CascaderOption[]> => {
|
||||||
|
|||||||
@@ -52,11 +52,18 @@ export default function useChatCompletion(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reasonContentRef.current =
|
const deltaReasoningContent =
|
||||||
reasonContentRef.current +
|
_.get(chunk, 'choices.0.delta.reasoning_content', '') === null
|
||||||
_.get(chunk, 'choices.0.delta.reasoning_content', '');
|
? ''
|
||||||
contentRef.current =
|
: _.get(chunk, 'choices.0.delta.reasoning_content', '');
|
||||||
contentRef.current + _.get(chunk, 'choices.0.delta.content', '');
|
|
||||||
|
const deltaContent =
|
||||||
|
_.get(chunk, 'choices.0.delta.content', '') === null
|
||||||
|
? ''
|
||||||
|
: _.get(chunk, 'choices.0.delta.content', '');
|
||||||
|
|
||||||
|
reasonContentRef.current = reasonContentRef.current + deltaReasoningContent;
|
||||||
|
contentRef.current = contentRef.current + deltaContent;
|
||||||
|
|
||||||
const content = formatContent({
|
const content = formatContent({
|
||||||
content: contentRef.current,
|
content: contentRef.current,
|
||||||
|
|||||||
Reference in New Issue
Block a user