fix: editor incompatibility with firefox79

This commit is contained in:
jialin
2026-01-09 20:51:48 +08:00
parent afcd3e5693
commit 10b2a8b4f9
33 changed files with 12316 additions and 630 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ html[data-theme='realDark'] {
--color-spotlight-bg: #3e3e3e;
--color-esc-hint-bg: rgba(150, 150, 150, 75%);
background: #292929;
background: #141414;
.ant-result-image {
opacity: 0.9;
+11 -2
View File
@@ -1,7 +1,7 @@
import IconFont from '@/components/icon-font';
import { CaretDownOutlined } from '@ant-design/icons';
import { Link, useLocation } from '@umijs/max';
import { Divider, Tooltip } from 'antd';
import { Tooltip } from 'antd';
import { createStyles } from 'antd-style';
import React, { useMemo, useState } from 'react';
@@ -67,6 +67,7 @@ const useStyles = createStyles(({ css, token }) => {
height: 1px;
padding-block: 0;
padding-inline: 0;
justify-content: center;
}
`,
menuItemContent: css`
@@ -118,6 +119,14 @@ const useStyles = createStyles(({ css, token }) => {
&.menu-item-group-hidden {
display: none;
}
`,
line: css`
height: 1px;
margin-block: 6px;
background-color: ${token.colorSplit};
position: absolute;
left: 6px;
right: 6px;
`
};
});
@@ -228,7 +237,7 @@ const SiderMenu: React.FC<SiderMenuProps> = (props) => {
></CaretDownOutlined>
</span>
) : is_admin ? (
<Divider style={dividerStyles} />
<span className={styles.line}></span>
) : null}
</div>
<div
+1 -1
View File
@@ -219,7 +219,7 @@ export default {
'models.mymodels.status.degrade': 'Not Ready',
'models.mymodels.status.active': 'Ready',
'models.form.kvCache.tips':
'Extended KV cache and speculative decoding are only available with built-in backends (vLLM / SGLang), Please switch the backend in the <span class="bold-text">Advanced</span> settings to enable them.',
'Extended KV cache and speculative decoding are only available with built-in backends (vLLM / SGLang), Please switch the backend to enable them.',
'models.form.kvCache.tips2':
'Only supported when using built-in inference backends (vLLM or SGLang).',
'models.form.scheduling': 'Scheduling',
+2 -2
View File
@@ -219,7 +219,7 @@ export default {
'models.mymodels.status.degrade': 'Not Ready',
'models.mymodels.status.active': 'Ready',
'models.form.kvCache.tips':
'Extended KV cache and speculative decoding are only available with built-in backends (vLLM / SGLang), Please switch the backend in the <span class="bold-text">Advanced</span> settings to enable them.',
'Extended KV cache and speculative decoding are only available with built-in backends (vLLM / SGLang), Please switch the backend to enable them.',
'models.form.kvCache.tips2':
'Only supported when using built-in inference backends (vLLM or SGLang).',
'models.form.scheduling': 'Scheduling',
@@ -318,7 +318,7 @@ export default {
// 41. 'models.mymodels.status.degrade': 'Not Ready',
// 42. 'models.mymodels.status.active': 'Ready',
// 43. 'models.form.remoteURL.tips': 'Refer to the <a href="https://docs.lmcache.ai/api_reference/configurations.html" target="_blank">configuration documentation</a> for details.',
// 44. 'models.form.kvCache.tips': 'Extended KV cache and speculative decoding are only available with built-in backends (vLLM / SGLang), Please switch the backend in the <span class="bold-text">Advanced</span> settings to enable them.',
// 44. 'models.form.kvCache.tips': 'Extended KV cache and speculative decoding are only available with built-in backends (vLLM / SGLang), Please switch the backend to enable them.',
// 45. 'models.form.kvCache.tips2': 'Only supported when using built-in inference backends (vLLM or SGLang).',
// 46. 'models.form.scheduling': 'Scheduling',
// 47. 'models.form.ramRatio': 'RAM-to-VRAM Ratio',
+1 -1
View File
@@ -223,7 +223,7 @@ export default {
'models.mymodels.status.degrade': 'Не готов',
'models.mymodels.status.active': 'Готов',
'models.form.kvCache.tips':
'Расширенный KV-кэш и спекулятивное декодирование доступны только со встроенными бэкендами (vLLM / SGLang). Переключите бэкенд в <span class="bold-text">Расширенных</span> настройках, чтобы включить их.',
'Расширенный KV-кэш и спекулятивное декодирование доступны только для встроенных бэкендов (vLLM / SGLang). Пожалуйста, переключите бэкенд, чтобы включить их.',
'models.form.kvCache.tips2':
'Поддерживается только при использовании встроенных бэкендов вывода (vLLM или SGLang).',
'models.form.scheduling': 'Планирование',
+1 -1
View File
@@ -208,7 +208,7 @@ export default {
'models.mymodels.status.degrade': '异常',
'models.mymodels.status.active': '可用',
'models.form.kvCache.tips':
'扩展 KV 缓存和推测解码仅在内置后端(vLLM / SGLang)可用,请在<span class="bold-text">高级</span>配置中切换后端以启用。',
'扩展 KV 缓存和推测解码仅在内置后端(vLLM / SGLang)可用,请切换后端以启用。',
'models.form.kvCache.tips2': '仅在使用内置推理后端(vLLM 或 SGLang)时支持。',
'models.form.scheduling': '调度',
'models.form.ramRatio': '内存与显存比例',
+7 -4
View File
@@ -1,8 +1,7 @@
import EditorWrap from '@/components/editor-wrap';
import { LoadingOutlined } from '@ant-design/icons';
import Editor, { loader } from '@monaco-editor/react';
import * as monaco from 'monaco-editor';
import { configureMonacoYaml } from 'monaco-yaml';
import { yamlDefaults } from 'monaco-yaml';
import React, {
forwardRef,
useEffect,
@@ -10,7 +9,9 @@ import React, {
useRef
} from 'react';
loader.config({ monaco });
loader.config({
paths: { vs: '/vs' }
});
interface ViewerProps {
ref?: any;
@@ -45,7 +46,9 @@ const EditorInner: React.FC<ViewerProps> = forwardRef((props, ref) => {
const handleBeforeMount = (monaco: any) => {
const yamlUri = monaco.Uri.parse(path);
configureMonacoYaml(monaco, {
yamlDefaults.setDiagnosticsOptions({
validate: false,
enableSchemaRequest: true,
hover: false,
schemas: [
{
@@ -1,13 +1,13 @@
import WorkerList from '@/pages/resources/components/workers';
import { useIntl, useNavigate, useSearchParams } from '@umijs/max';
import { PageContainerInner } from '../_components/page-box';
import PageBreadcrumb from '../_components/page-breadcrumb';
import ClusterMetrics from './components/cluster-metrics';
const ClusterDetailModal = () => {
const navigate = useNavigate();
const intl = useIntl();
const [searchParams] = useSearchParams();
const provider = searchParams.get('provider');
const id = searchParams.get('id');
const clusterName = searchParams.get('name');
const breadcrumbItems = [
@@ -26,7 +26,13 @@ const ClusterDetailModal = () => {
title: <PageBreadcrumb items={breadcrumbItems} />
}}
>
<ClusterMetrics />
<WorkerList
clusterId={id}
showAddButton={false}
showSelect={false}
widths={{ input: 360 }}
sourceType="cluster"
/>
</PageContainerInner>
);
};
@@ -1,60 +0,0 @@
import WorkerList from '@/pages/resources/components/workers';
import { useIntl } from '@umijs/max';
import React from 'react';
import styled from 'styled-components';
import FormDrawer from '../_components/form-drawer';
import { ClusterListItem } from './config/types';
const Content = styled.div`
.ant-pagination {
position: fixed;
bottom: 8px;
right: 24px;
z-index: 100;
}
.page-tools {
position: sticky;
top: 0;
}
`;
interface ClusterWorkersModalProps {
cluster: ClusterListItem;
open: boolean;
onClose: () => void;
}
const ClusterWorkersModal: React.FC<ClusterWorkersModalProps> = ({
open,
onClose,
cluster
}) => {
const intl = useIntl();
return (
<FormDrawer
title={`${intl.formatMessage({ id: 'clusters.title' })}: ${cluster.name}`}
open={open}
onCancel={onClose}
footer={
<div
style={{
height: 56
}}
></div>
}
width={'calc(100vw - 220px)'}
>
<Content>
<WorkerList
cluster={cluster}
showAddButton={false}
showSelect={false}
widths={{ input: 360 }}
sourceType="cluster"
/>
</Content>
</FormDrawer>
);
};
export default ClusterWorkersModal;
+14 -16
View File
@@ -11,7 +11,7 @@ import type { PageActionType } from '@/config/types';
import useExpandedRowKeys from '@/hooks/use-expanded-row-keys';
import useTableFetch from '@/hooks/use-table-fetch';
import useWatchList from '@/hooks/use-watch-list';
import { useIntl } from '@umijs/max';
import { useIntl, useNavigate } from '@umijs/max';
import { useMemoizedFn } from 'ahooks';
import { message } from 'antd';
import { useAtom } from 'jotai';
@@ -31,7 +31,6 @@ import {
WORKER_POOLS_API
} from './apis';
import ClusterModal from './cluster-modal';
import ClusterWorkersModal from './cluster-workers-modal';
import AddCluster from './components/add-cluster';
import AddPool from './components/add-pool';
import {
@@ -49,7 +48,6 @@ import {
} from './config/types';
import useAddWorker from './hooks/use-add-worker';
import useClusterColumns from './hooks/use-cluster-columns';
import { useClusterWorkers } from './hooks/use-cluster-workers';
import useCreateCluster from './hooks/use-create-cluster';
const Clusters: React.FC = () => {
@@ -72,6 +70,7 @@ const Clusters: React.FC = () => {
API: CLUSTERS_API,
contentForDelete: 'menu.clusterManagement.clusters'
});
const navigate = useNavigate();
const { watchDataList: allWorkerPoolList } = useWatchList(WORKER_POOLS_API);
const [expandAtom] = useAtom(expandKeysAtom);
const [clusterSession, setClusterSession] = useAtom(clusterSessionAtom);
@@ -84,12 +83,6 @@ const Clusters: React.FC = () => {
useCreateCluster({
refresh: handleSearch
});
const {
clusterWorkersModalStatus,
openClusterWorkersModal,
closeClusterWorkersModal
} = useClusterWorkers();
const [openAddModal, setOpenAddModal] = useState<{
open: boolean;
action: PageActionType;
@@ -206,7 +199,9 @@ const Clusters: React.FC = () => {
}
});
const handleOnToggleExpandAll = () => {};
const handleOnToggleExpandAll = () => {
// do nothing
};
const handleToggleExpandAll = useMemoizedFn((expanded: boolean) => {
const keys = dataSource.dataList?.map((item) => item.id);
@@ -256,6 +251,14 @@ const Clusters: React.FC = () => {
);
};
const handleOnCell = useMemoizedFn((record: ClusterListItem, dataIndex) => {
if (dataIndex === 'name') {
navigate(
`/cluster-management/clusters/detail?id=${record.id}&name=${record.name}`
);
}
});
useEffect(() => {
const fetchCredentialList = async () => {
const data = await queryCredentialList({ page: -1 });
@@ -318,7 +321,7 @@ const Clusters: React.FC = () => {
);
};
const columns = useClusterColumns(handleSelect, openClusterWorkersModal);
const columns = useClusterColumns(handleSelect, handleOnCell);
return (
<>
@@ -423,11 +426,6 @@ const Clusters: React.FC = () => {
open={clusterModalStatus.open}
onClose={closeClusterModal}
></ClusterModal>
<ClusterWorkersModal
open={clusterWorkersModalStatus.open}
onClose={closeClusterWorkersModal}
cluster={clusterWorkersModalStatus.cluster}
></ClusterWorkersModal>
{AddWorkerModal}
</>
);
@@ -6,7 +6,7 @@ import StatusTag from '@/components/status-tag';
import { tableSorter } from '@/config/settings';
import { StarFilled } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Tooltip, Typography } from 'antd';
import { Tooltip } from 'antd';
import dayjs from 'dayjs';
import { useMemo } from 'react';
import {
@@ -28,7 +28,7 @@ const setActionsItems = (row: ClusterListItem) => {
const useClusterColumns = (
handleSelect: (val: string, record: ClusterListItem) => void,
onViewWorkers: (record: ClusterListItem) => void
onCellClick?: (record: ClusterListItem, dataIndex: string) => void
): SealColumnProps[] => {
const intl = useIntl();
@@ -42,13 +42,7 @@ const useClusterColumns = (
render: (text: string, record: ClusterListItem) => (
<>
<AutoTooltip ghost title={text}>
{record.workers > 0 ? (
<Typography.Link onClick={() => onViewWorkers(record)}>
{record.name}
</Typography.Link>
) : (
text
)}
{text}
</AutoTooltip>
{record.is_default && (
<Tooltip
@@ -136,7 +130,7 @@ const useClusterColumns = (
)
}
];
}, [handleSelect, onViewWorkers]);
}, [handleSelect, onCellClick]);
};
export default useClusterColumns;
@@ -1,32 +0,0 @@
import { useState } from 'react';
import { ClusterListItem } from '../config/types';
export const useClusterWorkers = () => {
const [clusterWorkersModalStatus, setClusterWorkersModalStatus] = useState<{
open: boolean;
cluster: ClusterListItem;
}>({
open: false,
cluster: {} as ClusterListItem
});
const openClusterWorkersModal = (cluster: ClusterListItem) => {
setClusterWorkersModalStatus({
open: true,
cluster
});
};
const closeClusterWorkersModal = () => {
setClusterWorkersModalStatus({
open: false,
cluster: {} as ClusterListItem
});
};
return {
clusterWorkersModalStatus,
openClusterWorkersModal,
closeClusterWorkersModal
};
};
@@ -5,7 +5,7 @@ import YamlEditor from '@/pages/_components/yaml-editor';
import { useIntl } from '@umijs/max';
import { Button, Form } from 'antd';
import React, { forwardRef, useImperativeHandle } from 'react';
import { ProviderType, ProviderValueMap } from '../config';
import { ProviderType } from '../config';
import { ClusterFormData as FormData } from '../config/types';
import schema from '../config/worker-config.json';
import yamlTemplate from '../config/yaml-template';
@@ -32,26 +32,6 @@ const ClusterAdvanceConfig: React.FC<{
return (
<>
{provider !== ProviderValueMap.DigitalOcean && (
<Form.Item<FormData>
name="server_url"
rules={[
{
required: false,
message: ''
}
]}
>
<SealInput.Input
description={intl.formatMessage({
id: 'clusters.form.serverUrl.tips'
})}
label={intl.formatMessage({ id: 'clusters.create.serverUrl' })}
required={false}
trim={true}
></SealInput.Input>
</Form.Item>
)}
<Form.Item<FormData>
hidden
name="worker_config"
+3 -3
View File
@@ -27,13 +27,13 @@ import UpdateLabels from './update-labels';
import WorkerDetailModal from './worker-detail-modal';
const Workers: React.FC<{
cluster: ClusterListItem;
clusterId: string | number | null;
showSelect?: boolean;
showAddButton?: boolean;
widths?: { input: number };
sourceType?: string;
}> = ({
cluster,
clusterId,
showSelect = true,
showAddButton = true,
widths = { input: 200 },
@@ -62,7 +62,7 @@ const Workers: React.FC<{
watch: true,
API: WORKERS_API,
defaultQueryParams: {
cluster_id: cluster?.id || undefined
cluster_id: clusterId
}
});
const { TerminalPanel, terminals, handleAddTerminal } = useTerminalTabs();