@@ -1,6 +1,7 @@
|
||||
import IconFont from '@/components/icon-font';
|
||||
import { RightOutlined } from '@ant-design/icons';
|
||||
import { Button, Checkbox } from 'antd';
|
||||
import { ClearOutlined, RightOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Checkbox, Tooltip } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
@@ -29,10 +30,20 @@ const HeaderPrefix: React.FC<HeaderPrefixProps> = (props) => {
|
||||
disabled
|
||||
} = props;
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
const handleToggleExpand = () => {
|
||||
onExpandAll?.(!expandAll);
|
||||
};
|
||||
|
||||
const handleUnCheckAll = () => {
|
||||
onSelectAll?.({
|
||||
target: {
|
||||
checked: false
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (!hasColumns) {
|
||||
return null;
|
||||
}
|
||||
@@ -66,12 +77,36 @@ const HeaderPrefix: React.FC<HeaderPrefixProps> = (props) => {
|
||||
expandable
|
||||
)}
|
||||
</span>
|
||||
<Checkbox
|
||||
onChange={onSelectAll}
|
||||
indeterminate={indeterminate}
|
||||
checked={selectAll}
|
||||
disabled={disabled}
|
||||
></Checkbox>
|
||||
<Tooltip
|
||||
destroyTooltipOnHide
|
||||
fresh={true}
|
||||
defaultOpen={false}
|
||||
title={
|
||||
indeterminate && (
|
||||
<Button
|
||||
size="small"
|
||||
type="text"
|
||||
variant="filled"
|
||||
color="default"
|
||||
icon={<ClearOutlined />}
|
||||
onClick={handleUnCheckAll}
|
||||
>
|
||||
{intl.formatMessage({ id: 'common.button.clearSelection' })}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
overlayClassName="light-downloading-tooltip"
|
||||
overlayInnerStyle={{
|
||||
backgroundColor: 'var(--color-spotlight-bg)'
|
||||
}}
|
||||
>
|
||||
<Checkbox
|
||||
onChange={onSelectAll}
|
||||
indeterminate={indeterminate}
|
||||
checked={selectAll}
|
||||
disabled={disabled}
|
||||
></Checkbox>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -98,4 +133,4 @@ const HeaderPrefix: React.FC<HeaderPrefixProps> = (props) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export default React.memo(HeaderPrefix);
|
||||
export default HeaderPrefix;
|
||||
|
||||
@@ -45,4 +45,4 @@ const Header: React.FC<HeaderProps> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(Header);
|
||||
export default Header;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Pagination, type PaginationProps } from 'antd';
|
||||
import { memo } from 'react';
|
||||
|
||||
const PaginationComponent: React.FC<PaginationProps> = (props) => {
|
||||
return <Pagination {...props} />;
|
||||
};
|
||||
|
||||
export default memo(PaginationComponent);
|
||||
export default PaginationComponent;
|
||||
|
||||
@@ -60,4 +60,4 @@ const TableHeader: React.FC<TableHeaderProps> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(TableHeader);
|
||||
export default TableHeader;
|
||||
|
||||
@@ -281,4 +281,4 @@ const TableRow: React.FC<
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(TableRow);
|
||||
export default TableRow;
|
||||
|
||||
@@ -249,5 +249,6 @@ export default {
|
||||
'common.page.refresh.tips':
|
||||
'Oops! Something went wrong. Try refreshing the page.',
|
||||
'common.tips.escape.disable':
|
||||
'Click Cancel or the X at the top right to close.'
|
||||
'Click Cancel or the X at the top right to close.',
|
||||
'common.button.clearSelection': 'Clear Selection'
|
||||
};
|
||||
|
||||
@@ -151,5 +151,6 @@ export default {
|
||||
'playground.image.negativeMask.tips':
|
||||
'1. After selection, no further masking can be drawn; therefore, you should draw the mask first and then check the option.\n 2. Once a mask image is uploaded, no further masks can be generated.',
|
||||
'playground.model.noavailable.tips2':
|
||||
'If the expected model isn’t showing up, make sure it’s running and correctly categorized. If the category is incorrect, you can manually adjust it in the model’s settings.'
|
||||
'If the expected model isn’t showing up, make sure it’s running and correctly categorized. If the category is incorrect, you can manually adjust it in the model’s settings.',
|
||||
'playground.rerank.query.validate': 'Please enter something to search.'
|
||||
};
|
||||
|
||||
@@ -249,7 +249,8 @@ export default {
|
||||
'common.page.refresh.tips':
|
||||
'Oops! Something went wrong. Try refreshing the page.',
|
||||
'common.tips.escape.disable':
|
||||
'Click Cancel or the X at the top right to close.'
|
||||
'Click Cancel or the X at the top right to close.',
|
||||
'common.button.clearSelection': 'Clear Selection'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
@@ -266,4 +267,5 @@ export default {
|
||||
// 11. 'common.page.wentwrong': 'Something went wrong.',
|
||||
// 12. 'common.page.refresh.tips': 'Oops! Something went wrong. Try refreshing the page.'
|
||||
// 13. 'common.tips.escape.disable': 'Click Cancel or the X at the top right to close.'
|
||||
// 14. 'common.button.clearSelection': 'Clear Selection'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -154,5 +154,10 @@ export default {
|
||||
'playground.image.negativeMask.tips':
|
||||
'1. 選択後は追加のマスクを描画できません。そのため、最初にマスクを描画してからオプションを選択してください。\n 2. マスク画像をアップロードすると、追加のマスクを生成することはできません。',
|
||||
'playground.model.noavailable.tips2':
|
||||
'期待するモデルが表示されない場合は、モデルが実行中で正しく分類されていることを確認してください。カテゴリが間違っている場合は、モデルの設定で手動で調整できます。'
|
||||
'期待するモデルが表示されない場合は、モデルが実行中で正しく分類されていることを確認してください。カテゴリが間違っている場合は、モデルの設定で手動で調整できます。',
|
||||
'playground.rerank.query.validate': 'Please enter something to search.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
// 1. 'playground.rerank.query.validate': 'Please enter something to search.'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
+22
-11
@@ -81,8 +81,10 @@ export default {
|
||||
'common.button.back': 'Назад',
|
||||
'common.button.undo': 'Отменить',
|
||||
'common.button.discardChange': 'Отменить изменения',
|
||||
'common.tips.save': 'Есть несохранённые изменения. Выход приведёт к их потере.',
|
||||
'common.tips.cancel': 'У вас есть несохранённые изменения. Всё равно продолжить?',
|
||||
'common.tips.save':
|
||||
'Есть несохранённые изменения. Выход приведёт к их потере.',
|
||||
'common.tips.cancel':
|
||||
'У вас есть несохранённые изменения. Всё равно продолжить?',
|
||||
'common.tips.discard': 'Отменить изменения?',
|
||||
'common.tips.title': 'Подсказка:',
|
||||
'common.input.range.start': 'Начальное значение',
|
||||
@@ -135,7 +137,8 @@ export default {
|
||||
'common.table.createdBy': 'Оператор',
|
||||
'common.table.yes': 'Да',
|
||||
'common.table.no': 'Нет',
|
||||
'common.validate.labelName': 'Должен содержать только строчные буквы, цифры или "-", начинаться и заканчиваться буквой/цифрой.',
|
||||
'common.validate.labelName':
|
||||
'Должен содержать только строчные буквы, цифры или "-", начинаться и заканчиваться буквой/цифрой.',
|
||||
'common.search.nodata': 'Нет совпадений',
|
||||
'common.data.empty': 'Нет данных',
|
||||
'common.tips.change': 'Есть несохраненные изменения!',
|
||||
@@ -179,7 +182,8 @@ export default {
|
||||
'common.rule.array': 'должен быть массивом',
|
||||
'common.rule.object': 'должен быть объектом',
|
||||
'common.rule.syntaxerror': 'синтаксическая ошибка',
|
||||
'common.code.hide.tips': '... Скрыто {rows} строк, нажмите чтобы раскрыть ...',
|
||||
'common.code.hide.tips':
|
||||
'... Скрыто {rows} строк, нажмите чтобы раскрыть ...',
|
||||
'common.nodata.created': 'Еще не создано ни одного {type}',
|
||||
'common.nodata.added': 'Еще не добавлено ни одного {type}',
|
||||
'common.status.edited': 'Изменено',
|
||||
@@ -187,11 +191,14 @@ export default {
|
||||
'common.settings.instructions': 'Инструкции',
|
||||
'common.settings.language': 'Язык',
|
||||
'common.delete.confirm': 'Вы уверены, что хотите удалить выбранный {type}?',
|
||||
'common.delete.single.confirm': 'Вы уверены, что хотите удалить <span style="font-size: 13px;font-weight: 700">{name}</span>?',
|
||||
'common.delete.single.confirm':
|
||||
'Вы уверены, что хотите удалить <span style="font-size: 13px;font-weight: 700">{name}</span>?',
|
||||
'common.stop.confirm': 'Вы уверены, что хотите остановить выбранный {type}?',
|
||||
'common.stop.single.confirm': 'Вы уверены, что хотите остановить <span style="font-size: 13px;font-weight: 700">{name}</span>?',
|
||||
'common.stop.single.confirm':
|
||||
'Вы уверены, что хотите остановить <span style="font-size: 13px;font-weight: 700">{name}</span>?',
|
||||
'common.start.confirm': 'Вы уверены, что хотите запустить выбранный {type}?',
|
||||
'common.start.single.confirm': 'Вы уверены, что хотите запустить <span style="font-size: 13px;font-weight: 700">{name}</span>?',
|
||||
'common.start.single.confirm':
|
||||
'Вы уверены, что хотите запустить <span style="font-size: 13px;font-weight: 700">{name}</span>?',
|
||||
'common.filter.name': 'Фильтр по имени',
|
||||
'common.form.password': 'Пароль',
|
||||
'common.form.username': 'Имя пользователя',
|
||||
@@ -230,17 +237,21 @@ export default {
|
||||
'common.appearance.dark': 'Темная',
|
||||
'common.appearance.light': 'Светлая',
|
||||
'common.appearance.system': 'Как в системе',
|
||||
'common.exception.404': 'Извините, страница, которую вы посетили, не существует.',
|
||||
'common.exception.404':
|
||||
'Извините, страница, которую вы посетили, не существует.',
|
||||
'common.appearance.darkmode': 'Тёмная тема',
|
||||
'common.appearance.lightmode': 'Светлая тема',
|
||||
'common.appearance.tips': 'По умолчанию соответствует системным настройкам.',
|
||||
'common.button.forgotpassword': 'Забыли пароль?',
|
||||
'common.appearance.theme': 'Тема',
|
||||
'common.page.wentwrong': 'Что-то пошло не так.',
|
||||
'common.page.refresh.tips': 'Упс! Что-то пошло не так. Попробуйте обновить страницу.',
|
||||
'common.tips.escape.disable': 'Чтобы закрыть, нажмите "Отмена" или крестик (X) в правом верхнем углу.'
|
||||
'common.page.refresh.tips':
|
||||
'Упс! Что-то пошло не так. Попробуйте обновить страницу.',
|
||||
'common.tips.escape.disable':
|
||||
'Чтобы закрыть, нажмите "Отмена" или крестик (X) в правом верхнем углу.',
|
||||
'common.button.clearSelection': 'Clear Selection'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
|
||||
// 1. 'common.button.clearSelection': 'Clear Selection'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -139,15 +139,19 @@ export default {
|
||||
'playground.chat.aithought': 'Рассуждение (CoT)',
|
||||
'playground.chat.thinking': 'Рассуждение...',
|
||||
'playground.image.mask.uploaded': 'Маска загружена',
|
||||
'playground.image.mask.upload': 'Маска загрузки: Дополнительное редактирование запрещено после загрузки.',
|
||||
'playground.image.mask.upload':
|
||||
'Маска загрузки: Дополнительное редактирование запрещено после загрузки.',
|
||||
'playground.params.frequency_penalty.tips': `Число от -2.0 до 2.0. Положительные значения снижают вероятность повторения токенов, уже часто встречающихся в тексте, уменьшая склонность модели дословно повторять одни и те же фразы.`,
|
||||
'playground.params.presence_penalty.tips': `Число от -2.0 до 2.0. Положительные значения снижают вероятность повторения любых токенов, присутствующих в тексте, повышая склонность модели к обсуждению новых тем.`,
|
||||
'playground.image.origin': 'Оригинал',
|
||||
'playground.image.mask': 'Маска',
|
||||
'playground.image.negativeMask.tips': '1. После выделения области создание маски станет недоступным; поэтому сначала нарисуйте маску, а затем активируйте опцию. \n 2. После загрузки изображения маски создание новых масок невозможно.',
|
||||
'playground.model.noavailable.tips2': 'Если нужная модель не отображается, убедитесь, что она запущена и ей присвоена правильная категория. Если категория указана неверно, её можно изменить вручную в настройках модели.' // Translated
|
||||
'playground.image.negativeMask.tips':
|
||||
'1. После выделения области создание маски станет недоступным; поэтому сначала нарисуйте маску, а затем активируйте опцию. \n 2. После загрузки изображения маски создание новых масок невозможно.',
|
||||
'playground.model.noavailable.tips2':
|
||||
'Если нужная модель не отображается, убедитесь, что она запущена и ей присвоена правильная категория. Если категория указана неверно, её можно изменить вручную в настройках модели.',
|
||||
'playground.rerank.query.validate': 'Please enter something to search.'
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
|
||||
// 1. 'playground.rerank.query.validate': 'Please enter something to search.'
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -242,5 +242,6 @@ export default {
|
||||
'common.appearance.theme': '主题',
|
||||
'common.page.wentwrong': '哎呀,出了点问题',
|
||||
'common.page.refresh.tips': '出了点问题,试试刷新页面吧!',
|
||||
'common.tips.escape.disable': '请点击「取消」按钮或右上角 X 关闭窗口'
|
||||
'common.tips.escape.disable': '请点击「取消」按钮或右上角 X 关闭窗口',
|
||||
'common.button.clearSelection': '清除选择'
|
||||
};
|
||||
|
||||
@@ -145,5 +145,6 @@ export default {
|
||||
'playground.image.negativeMask.tips':
|
||||
'1. 选择后,将不可再绘制遮罩;因此,你应该先绘制遮罩然后再勾选.\n 2. 当上传了遮罩图片,将不可再生成遮罩',
|
||||
'playground.model.noavailable.tips2':
|
||||
'若预期的模型未显示,请检查模型是否已正常运行并被正确分类。如分类不正确,请编辑模型并手动调整其类别。'
|
||||
'若预期的模型未显示,请检查模型是否已正常运行并被正确分类。如分类不正确,请编辑模型并手动调整其类别。',
|
||||
'playground.rerank.query.validate': '请输入搜索内容'
|
||||
};
|
||||
|
||||
@@ -206,6 +206,11 @@ const AddModal: FC<AddModalProps> = (props) => {
|
||||
source: props.source
|
||||
});
|
||||
|
||||
// for cancel evaluate request case
|
||||
if (!evaluateRes) {
|
||||
return;
|
||||
}
|
||||
|
||||
const defaultSpec = getDefaultSpec({
|
||||
evaluateResult: evaluateRes
|
||||
});
|
||||
@@ -254,10 +259,14 @@ const AddModal: FC<AddModalProps> = (props) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancelFiles = () => {
|
||||
cancelEvaluate();
|
||||
modelFileRef.current?.cancelRequest();
|
||||
};
|
||||
const handleOnSelectModel = async (item: any) => {
|
||||
// If the item is empty or the same as the selected model, do nothing
|
||||
console.log('handleOnSelectModel', item, selectedModel);
|
||||
modelFileRef.current?.cancelRequest();
|
||||
handleCancelFiles();
|
||||
if (
|
||||
_.isEmpty(item) ||
|
||||
(item.isGGUF === selectedModel.isGGUF && item.name === selectedModel.name)
|
||||
@@ -304,12 +313,18 @@ const AddModal: FC<AddModalProps> = (props) => {
|
||||
state: EvaluateProccess.model,
|
||||
requestModelId: updateRequestModelId()
|
||||
});
|
||||
modelFileRef.current?.cancelRequest();
|
||||
handleCancelFiles();
|
||||
const modelInfo = onSelectModel(item, props.source);
|
||||
|
||||
console.log(
|
||||
'handleOnSelectModelAfterEvaluate',
|
||||
item,
|
||||
evaluateStateRef.current
|
||||
);
|
||||
|
||||
if (
|
||||
evaluateStateRef.current.state === EvaluateProccess.model &&
|
||||
item.evaluateResult
|
||||
item.evaluated
|
||||
) {
|
||||
handleShowCompatibleAlert(item.evaluateResult);
|
||||
form.current?.setFieldsValue?.({
|
||||
@@ -425,6 +440,7 @@ const AddModal: FC<AddModalProps> = (props) => {
|
||||
handleOnOpen();
|
||||
} else {
|
||||
cancelEvaluate();
|
||||
clearCahceFormValues();
|
||||
}
|
||||
return () => {
|
||||
setSelectedModel({});
|
||||
|
||||
@@ -569,7 +569,6 @@ const Models: React.FC<ModelsProps> = ({
|
||||
operation: 'common.start.confirm',
|
||||
async onOk() {
|
||||
await handleBatchRequest(rowSelection.selectedRows, handleStartModel);
|
||||
rowSelection.clearSelections();
|
||||
onStart?.();
|
||||
}
|
||||
});
|
||||
@@ -583,7 +582,6 @@ const Models: React.FC<ModelsProps> = ({
|
||||
operation: 'common.stop.confirm',
|
||||
async onOk() {
|
||||
await handleBatchRequest(rowSelection.selectedRows, handleStopModel);
|
||||
rowSelection.clearSelections();
|
||||
onStop?.(rowSelection.selectedRowKeys as number[]);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -298,6 +298,7 @@ export const useCheckCompatibility = () => {
|
||||
options?: WarningStausOptions
|
||||
) => {
|
||||
const { lockAfterUpdate = false, override = false } = options || {};
|
||||
console.log('updateWarningStatus', params, options);
|
||||
|
||||
setWarningStatus((prev: MessageStatus) => {
|
||||
if (isLockWarningStatus.current && !override) {
|
||||
@@ -348,6 +349,7 @@ export const useCheckCompatibility = () => {
|
||||
const handleCheckCompatibility = (
|
||||
evaluateResult: EvaluateResult | null
|
||||
): MessageStatus => {
|
||||
console.log('handleCheckCompatibility', evaluateResult);
|
||||
if (!evaluateResult) {
|
||||
return {
|
||||
show: false,
|
||||
@@ -586,14 +588,16 @@ export const useCheckCompatibility = () => {
|
||||
);
|
||||
|
||||
const cancelEvaluate = () => {
|
||||
// update the requestId to cancel the current evaluation
|
||||
updateRequestId();
|
||||
checkTokenRef.current?.cancel();
|
||||
checkTokenRef.current = null;
|
||||
cacheFormValuesRef.current = {};
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
cancelEvaluate();
|
||||
clearCahceFormValues();
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -9,7 +9,16 @@ import {
|
||||
SendOutlined
|
||||
} from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Checkbox, Form, Input, Spin, Tag, Tooltip } from 'antd';
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
Form,
|
||||
Input,
|
||||
Spin,
|
||||
Tag,
|
||||
Tooltip,
|
||||
Typography
|
||||
} from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import _ from 'lodash';
|
||||
import 'overlayscrollbars/overlayscrollbars.css';
|
||||
@@ -22,6 +31,7 @@ import React, {
|
||||
useRef,
|
||||
useState
|
||||
} from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { rerankerQuery } from '../apis';
|
||||
import { extractErrorMessage } from '../config';
|
||||
import { ParamsSchema } from '../config/types';
|
||||
@@ -36,6 +46,19 @@ import InputList from './input-list';
|
||||
import TokenUsage from './token-usage';
|
||||
import ViewCommonCode from './view-common-code';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const SearchInputWrapper = styled.div`
|
||||
margin: 16px 32px 10px;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const ValidText = styled(Text)`
|
||||
position: absolute;
|
||||
bottom: -20px;
|
||||
left: 0;
|
||||
`;
|
||||
|
||||
interface MessageProps {
|
||||
modelList: Global.BaseOption<string>[];
|
||||
loaded?: boolean;
|
||||
@@ -89,6 +112,7 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
|
||||
rank?: number;
|
||||
}[]
|
||||
>([]);
|
||||
const [isEmptyQuery, setIsEmptyQuery] = useState<boolean>(false);
|
||||
|
||||
const [textList, setTextList] = useState<
|
||||
{
|
||||
@@ -223,8 +247,10 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
|
||||
|
||||
const submitMessage = async (query: string) => {
|
||||
try {
|
||||
setIsEmptyQuery(!queryValue);
|
||||
await formRef.current?.form.validateFields();
|
||||
if (!parameters.model) return;
|
||||
|
||||
if (!parameters.model || !queryValue) return;
|
||||
const documentList: any[] = [...textList, ...fileList];
|
||||
|
||||
const validDocus = documentList.filter((item) => item.text);
|
||||
@@ -310,6 +336,7 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
|
||||
|
||||
const handleQueryChange = (e: any) => {
|
||||
setQueryValue(e.target.value);
|
||||
setIsEmptyQuery(!e.target.value);
|
||||
};
|
||||
|
||||
const handleCloseViewCode = () => {
|
||||
@@ -430,7 +457,7 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
|
||||
>
|
||||
<span>{intl.formatMessage({ id: 'playground.rerank.query' })}</span>
|
||||
</h3>
|
||||
<div style={{ margin: '16px 32px 10px' }}>
|
||||
<SearchInputWrapper>
|
||||
<Input.Search
|
||||
allowClear
|
||||
onSearch={handleSearch}
|
||||
@@ -452,7 +479,12 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
|
||||
id: 'playground.rerank.query.holder'
|
||||
})}
|
||||
></Input.Search>
|
||||
</div>
|
||||
{isEmptyQuery && (
|
||||
<ValidText type="danger">
|
||||
{intl.formatMessage({ id: 'playground.rerank.query.validate' })}
|
||||
</ValidText>
|
||||
)}
|
||||
</SearchInputWrapper>
|
||||
</div>
|
||||
<div className="center" ref={scroller}>
|
||||
<div className="documents">
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
.doc-header {
|
||||
margin-bottom: 16px;
|
||||
padding-top: 16px;
|
||||
margin-top: 16px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
|
||||
Reference in New Issue
Block a user