fix: query catalog spec, default_version check

This commit is contained in:
jialin
2025-12-12 17:08:30 +08:00
parent cb43131ccb
commit 0500dd2e35
19 changed files with 86 additions and 23 deletions
+1 -2
View File
@@ -3,8 +3,7 @@
.ant-layout-sider-children { .ant-layout-sider-children {
border-inline: none; border-inline: none;
border-radius: 0; border-radius: 0;
// padding-inline: 16px; padding-block-end: 8px;
padding-block-end: 12px;
} }
.umi-plugin-layout-right { .umi-plugin-layout-right {
+5 -1
View File
@@ -218,6 +218,11 @@ body {
background-color: var(--color-fill-1); background-color: var(--color-fill-1);
height: 100%; height: 100%;
.ant-pro-sider-footer {
padding-block: 2px 0;
padding-left: 6px;
}
.ant-pro-sider-actions-list-item { .ant-pro-sider-actions-list-item {
padding: 0; padding: 0;
@@ -228,7 +233,6 @@ body {
.ant-pro-sider-logo { .ant-pro-sider-logo {
position: relative; position: relative;
padding-left: 18px;
padding-block: 12px; padding-block: 12px;
border-block-end: none; border-block-end: none;
} }
+5 -1
View File
@@ -1,7 +1,7 @@
// @ts-nocheck // @ts-nocheck
import { routeCacheAtom, setRouteCache } from '@/atoms/route-cache'; import { routeCacheAtom, setRouteCache } from '@/atoms/route-cache';
import { userAtom } from '@/atoms/user'; import { GPUStackVersionAtom, userAtom } from '@/atoms/user';
import DarkMask from '@/components/dark-mask'; import DarkMask from '@/components/dark-mask';
import IconFont from '@/components/icon-font'; import IconFont from '@/components/icon-font';
import routeCachekey from '@/config/route-cachekey'; import routeCachekey from '@/config/route-cachekey';
@@ -112,6 +112,7 @@ export default (props: any) => {
const navigate = useNavigate(); const navigate = useNavigate();
const intl = useIntl(); const intl = useIntl();
const { clientRoutes } = useAppData(); const { clientRoutes } = useAppData();
const [version] = useAtom(GPUStackVersionAtom);
const initialInfo = (useModel && useModel('@@initialState')) || { const initialInfo = (useModel && useModel('@@initialState')) || {
initialState: undefined, initialState: undefined,
@@ -311,6 +312,9 @@ export default (props: any) => {
onCollapse={onCollapse} onCollapse={onCollapse}
onMenuHeaderClick={onMenuHeaderClick} onMenuHeaderClick={onMenuHeaderClick}
menuHeaderRender={renderMenuHeader} menuHeaderRender={renderMenuHeader}
menuFooterRender={() => (
<span style={{ fontSize: 12 }}>{version?.version}</span>
)}
extra={[ extra={[
<ExtraContent <ExtraContent
key="extra-content" key="extra-content"
+3 -1
View File
@@ -32,5 +32,7 @@ export default {
'The built-in backends custom version name must end with "-custom".', 'The built-in backends custom version name must end with "-custom".',
'backend.backend.rules.custom': 'backend.backend.rules.custom':
'The custom backend name must end with "-custom".', 'The custom backend name must end with "-custom".',
'backend.quickConfig': 'Quick Config' 'backend.quickConfig': 'Quick Config',
'backend.version.default.not.exists':
'The default version does not exist in {versions}.'
}; };
+3 -1
View File
@@ -268,5 +268,7 @@ export default {
'Accessible to all authenticated platform users.', 'Accessible to all authenticated platform users.',
'models.accessSettings.allowedUsers.tips': 'models.accessSettings.allowedUsers.tips':
'Only designated users can access the model.', 'Only designated users can access the model.',
'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.` 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
'models.catalog.nogpus.tips':
'No compatible GPUs are available in the selected cluster for this model.'
}; };
+3 -1
View File
@@ -32,5 +32,7 @@ export default {
'The built-in backends custom version name must end with "-custom".', 'The built-in backends custom version name must end with "-custom".',
'backend.backend.rules.custom': 'backend.backend.rules.custom':
'The custom backend name must end with "-custom".', 'The custom backend name must end with "-custom".',
'backend.quickConfig': 'Quick Config' 'backend.quickConfig': 'Quick Config',
'backend.version.default.not.exists':
'The default version does not exist in {versions}.'
}; };
+5 -2
View File
@@ -268,7 +268,9 @@ export default {
'Accessible to all authenticated platform users.', 'Accessible to all authenticated platform users.',
'models.accessSettings.allowedUsers.tips': 'models.accessSettings.allowedUsers.tips':
'Only designated users can access the model.', 'Only designated users can access the model.',
'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.` 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
'models.catalog.nogpus.tips':
'No compatible GPUs are available in the selected cluster for this model.'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -360,5 +362,6 @@ export default {
// 69. 'models.accessSettings.public.desc': 'Accessible to anyone without authentication.', // 69. 'models.accessSettings.public.desc': 'Accessible to anyone without authentication.',
// 70. 'models.accessSettings.authed.tips': 'Accessible to all authenticated platform users.', // 70. 'models.accessSettings.authed.tips': 'Accessible to all authenticated platform users.',
// 71.'models.accessSettings.allowedUsers.tips': 'Only designated users can access the model.', // 71.'models.accessSettings.allowedUsers.tips': 'Only designated users can access the model.',
// 72. 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.` // 72. 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
// 73. 'models.catalog.nogpus.tips': 'No compatible GPUs are available in the selected cluster for this model.'
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+4 -2
View File
@@ -32,9 +32,11 @@ export default {
'Пользовательское название версии встроенного бэкенда должно оканчиваться на «-custom».', 'Пользовательское название версии встроенного бэкенда должно оканчиваться на «-custom».',
'backend.backend.rules.custom': 'backend.backend.rules.custom':
'Пользовательское название бэкенда должно оканчиваться на «-custom».', 'Пользовательское название бэкенда должно оканчиваться на «-custom».',
'backend.quickConfig': 'Быстрая настройка' 'backend.quickConfig': 'Быстрая настройка',
'backend.version.default.not.exists':
'The default version does not exist in {versions}.'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'backend.version.default.not.exists': 'The default version does not exist in {versions}.'
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+5 -2
View File
@@ -273,12 +273,15 @@ export default {
'Accessible to all authenticated platform users.', 'Accessible to all authenticated platform users.',
'models.accessSettings.allowedUsers.tips': 'models.accessSettings.allowedUsers.tips':
'Only designated users can access the model.', 'Only designated users can access the model.',
'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.` 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
'models.catalog.nogpus.tips':
'No compatible GPUs are available in the selected cluster for this model.'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'models.accessSettings.public.desc': 'Accessible to anyone without authentication.', // 1. 'models.accessSettings.public.desc': 'Accessible to anyone without authentication.',
// 2. 'models.accessSettings.authed.tips': 'Accessible to all authenticated platform users.', // 2. 'models.accessSettings.authed.tips': 'Accessible to all authenticated platform users.',
// 3. 'models.accessSettings.allowedUsers.tips': 'Only designated users can access the model.', // 3. 'models.accessSettings.allowedUsers.tips': 'Only designated users can access the model.',
// 4. 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.` // 4. 'models.form.backendVersions.tips': `To use more versions, go to the {link} page and edit the backend to add versions.`,
// 5. 'models.catalog.nogpus.tips': 'No compatible GPUs are available in the selected cluster for this model.'
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+2 -1
View File
@@ -30,5 +30,6 @@ export default {
'backend.version.rules.builtin': '须以 "-custom" 结尾', 'backend.version.rules.builtin': '须以 "-custom" 结尾',
'backend.version.no.tips': '内置后端自定义版本名称必须以 "-custom" 结尾。', 'backend.version.no.tips': '内置后端自定义版本名称必须以 "-custom" 结尾。',
'backend.backend.rules.custom': '自定义后端名称须以 "-custom" 结尾。', 'backend.backend.rules.custom': '自定义后端名称须以 "-custom" 结尾。',
'backend.quickConfig': '快速配置' 'backend.quickConfig': '快速配置',
'backend.version.default.not.exists': '默认版本不存在于 {versions}。'
}; };
+2 -1
View File
@@ -252,5 +252,6 @@ export default {
'models.accessSettings.public.desc': '任何人无需认证即可访问。', 'models.accessSettings.public.desc': '任何人无需认证即可访问。',
'models.accessSettings.authed.tips': '平台内所有已认证用户可访问。', 'models.accessSettings.authed.tips': '平台内所有已认证用户可访问。',
'models.accessSettings.allowedUsers.tips': '仅允许选定的特定用户访问。', 'models.accessSettings.allowedUsers.tips': '仅允许选定的特定用户访问。',
'models.form.backendVersions.tips': `如需使用更多版本,请前往{link}页面并编辑对应的后端以添加版本。` 'models.form.backendVersions.tips': `如需使用更多版本,请前往{link}页面并编辑对应的后端以添加版本。`,
'models.catalog.nogpus.tips': '所选集群中没有兼容该模型的 GPU。'
}; };
+22 -2
View File
@@ -110,24 +110,44 @@ const ImportYAML: React.FC<ImportYAMLProps> = forwardRef(
const jsonData = yaml2Json(content); const jsonData = yaml2Json(content);
const exsistingVersions = Object.keys(jsonData.version_configs || {}); const exsistingVersions = Object.keys(jsonData.version_configs || {});
// Check backend version rules
if ( if (
actionStatus.isBuiltIn && actionStatus.isBuiltIn &&
exsistingVersions.find((v) => !v.endsWith('-custom')) exsistingVersions.find((v) => !v?.endsWith('-custom'))
) { ) {
setError(intl.formatMessage({ id: 'backend.version.no.tips' })); setError(intl.formatMessage({ id: 'backend.version.no.tips' }));
return false; return false;
} }
// Check custom backend name rule
if ( if (
!actionStatus.isBuiltIn && !actionStatus.isBuiltIn &&
actionStatus.action === PageAction.CREATE && actionStatus.action === PageAction.CREATE &&
!jsonData.backend_name.endsWith('-custom') !jsonData.backend_name?.endsWith('-custom')
) { ) {
setError(intl.formatMessage({ id: 'backend.backend.rules.custom' })); setError(intl.formatMessage({ id: 'backend.backend.rules.custom' }));
return false; return false;
} }
// Check default version exists
if (
jsonData.default_version &&
!exsistingVersions.includes(jsonData.default_version) &&
!actionStatus.isBuiltIn
) {
// the default_version must be in [existingVersions]
setError(
intl.formatMessage(
{ id: 'backend.version.default.not.exists' },
{ versions: exsistingVersions.join(', ') }
)
);
return false;
}
return content; return content;
} catch (error) { } catch (error) {
setError((error as Error).message);
return false; return false;
} }
}; };
@@ -88,12 +88,12 @@ const ViewerEditor: React.FC<ViewerProps> = forwardRef((props, ref) => {
} }
}; };
// Currently, do not use this function, but keep it for future validation needs
const getMarkers = () => { const getMarkers = () => {
const uri = editorRef.current?.getModel()?.uri; const uri = editorRef.current?.getModel()?.uri;
const markers = monacoRef.current?.editor.getModelMarkers({ const markers = monacoRef.current?.editor.getModelMarkers({
resource: uri resource: uri
}); });
console.log('Validation markers:', uri, markers);
return markers; return markers;
}; };
+1 -1
View File
@@ -367,7 +367,7 @@ export async function queryCatalogList(
} }
export async function queryCatalogItemSpec( export async function queryCatalogItemSpec(
params: { id: number; cluster_id: number }, params: { id: number; cluster_id: number | null },
options?: any options?: any
) { ) {
return request<Global.PageResponse<CatalogSpec>>( return request<Global.PageResponse<CatalogSpec>>(
+4 -1
View File
@@ -198,7 +198,10 @@ const Catalog: React.FC = () => {
const getCatalogSource = async () => { const getCatalogSource = async () => {
try { try {
const id = dataSource.dataList?.[0]?.id; const id = dataSource.dataList?.[0]?.id;
const res: any = await queryCatalogItemSpec({ id, cluster_id: 0 }); const res: any = await queryCatalogItemSpec({
id,
cluster_id: null
});
sourceRef.current = res?.items?.[0]?.source; sourceRef.current = res?.items?.[0]?.source;
} catch (error) {} } catch (error) {}
}; };
@@ -250,6 +250,16 @@ const AddModal: React.FC<AddModalProps> = (props) => {
cluster_id: clusterId, cluster_id: clusterId,
name name
}); });
// If no avaliable gpus for the model, show warning message
if (!res.items.length) {
setWarningStatus({
show: true,
type: 'warning',
message: intl.formatMessage({ id: 'models.catalog.nogpus.tips' })
});
return;
}
handleCheckCompatibility(allValues); handleCheckCompatibility(allValues);
} catch (error) { } catch (error) {
// ignore // ignore
-1
View File
@@ -103,7 +103,6 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const intl = useIntl(); const intl = useIntl();
const [activeKey, setActiveKey] = React.useState<string[]>([]); const [activeKey, setActiveKey] = React.useState<string[]>([]);
const scheduleType = Form.useWatch('scheduleType', form);
const [target, setTarget] = React.useState<string>(TABKeysMap.BASIC); const [target, setTarget] = React.useState<string>(TABKeysMap.BASIC);
console.log('scroller instance in form:', osInstance, scrollEventElement); console.log('scroller instance in form:', osInstance, scrollEventElement);
+6 -1
View File
@@ -296,7 +296,12 @@ export const useCheckCompatibility = () => {
title: intl.formatMessage({ id: 'models.form.check.passed' }), title: intl.formatMessage({ id: 'models.form.check.passed' }),
message: intl.formatMessage({ id: messageId }, { ram, vram }) message: intl.formatMessage({ id: messageId }, { ram, vram })
}; };
} else if (othersAvailable) { } else if (
othersAvailable &&
!scheduling_messages?.length &&
!compatibility_messages?.length
) {
// no specific messages, but other clusters are available
msgData = { msgData = {
title: intl.formatMessage({ title: intl.formatMessage({
id: 'models.form.check.clusterUnavailable' id: 'models.form.check.clusterUnavailable'
+4 -1
View File
@@ -24,11 +24,14 @@ export const login = async (
}; };
export const logout = async (userInfo?: any) => { export const logout = async (userInfo?: any) => {
await request(`${AUTH_API}/logout`, { const res = await request(`${AUTH_API}/logout`, {
method: 'POST' method: 'POST'
}); });
clearStorageUserSettings(); clearStorageUserSettings();
clearAtomStorage(userAtom); clearAtomStorage(userAtom);
if (res.logout_url) {
window.location.href = res.logout_url;
}
return; return;
}; };