fix: backend edit format

This commit is contained in:
jialin
2025-10-15 12:18:50 +08:00
parent 4196351e48
commit 059416bb47
14 changed files with 72 additions and 39 deletions
+1 -1
View File
@@ -14,6 +14,6 @@ export default {
'apikeys.form.expiration.never': 'No expiration', 'apikeys.form.expiration.never': 'No expiration',
'apikeys.table.bindModels': 'Model Access', 'apikeys.table.bindModels': 'Model Access',
'apikeys.models.all': 'All models', 'apikeys.models.all': 'All models',
'apikeys.models.selected': 'Selected models', 'apikeys.models.selected': 'Allowed models',
'apikeys.models.noModelsFound': 'No models found' 'apikeys.models.noModelsFound': 'No models found'
}; };
+6 -2
View File
@@ -174,7 +174,6 @@ export default {
'models.button.accessSettings': 'Access Settings', 'models.button.accessSettings': 'Access Settings',
'models.table.accessScope': 'Access Scope', 'models.table.accessScope': 'Access Scope',
'models.table.accessScope.all': 'All users', 'models.table.accessScope.all': 'All users',
'models.table.accessScope.selected': 'Selected users',
'models.table.userSelection': 'User Selection', 'models.table.userSelection': 'User Selection',
'models.table.filterByName': 'Filter by username', 'models.table.filterByName': 'Filter by username',
'models.table.admin': 'Admin', 'models.table.admin': 'Admin',
@@ -189,5 +188,10 @@ export default {
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
'models.form.remoteURL': 'Remote Storage URL', 'models.form.remoteURL': 'Remote Storage URL',
'models.form.runCommandPlaceholder': 'models.form.runCommandPlaceholder':
'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct' 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct',
'models.accessSettings.public': 'Public',
'models.accessSettings.authed': 'Authenticated',
'models.accessSettings.allowedUsers': 'Allowed users',
'models.accessSettings.public.tips':
'When set to public, anyone can access this model without authentication, which may lead to data exposure risks.'
}; };
+2 -2
View File
@@ -14,13 +14,13 @@ export default {
'apikeys.form.expiration.never': '無期限', 'apikeys.form.expiration.never': '無期限',
'apikeys.table.bindModels': 'Model Access', 'apikeys.table.bindModels': 'Model Access',
'apikeys.models.all': 'All models', 'apikeys.models.all': 'All models',
'apikeys.models.selected': 'Selected models', 'apikeys.models.selected': 'Allowed models',
'apikeys.models.noModelsFound': 'No models found' 'apikeys.models.noModelsFound': 'No models found'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'apikeys.table.bindModels': 'Model Access', // 1. 'apikeys.table.bindModels': 'Model Access',
// 2. 'apikeys.models.all': 'All models', // 2. 'apikeys.models.all': 'All models',
// 3. 'apikeys.models.selected': 'Selected models', // 3. 'apikeys.models.selected': 'Allowed models',
// 4. 'apikeys.models.noModelsFound': 'No models found' // 4. 'apikeys.models.noModelsFound': 'No models found'
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+11 -4
View File
@@ -171,7 +171,6 @@ export default {
'models.button.accessSettings': 'Access Settings', 'models.button.accessSettings': 'Access Settings',
'models.table.accessScope': 'Access Scope', 'models.table.accessScope': 'Access Scope',
'models.table.accessScope.all': 'All users', 'models.table.accessScope.all': 'All users',
'models.table.accessScope.selected': 'Selected users',
'models.table.userSelection': 'User Selection', 'models.table.userSelection': 'User Selection',
'models.table.filterByName': 'Filter by username', 'models.table.filterByName': 'Filter by username',
'models.table.admin': 'Admin', 'models.table.admin': 'Admin',
@@ -186,7 +185,12 @@ export default {
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
'models.form.remoteURL': 'Remote Storage URL', 'models.form.remoteURL': 'Remote Storage URL',
'models.form.runCommandPlaceholder': 'models.form.runCommandPlaceholder':
'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct' 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct',
'models.accessSettings.public': 'Public',
'models.accessSettings.authed': 'Authenticated',
'models.accessSettings.allowedUsers': 'Allowed users',
'models.accessSettings.public.tips':
'When set to public, anyone can access this model without authentication, which may lead to data exposure risks.'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -198,7 +202,6 @@ export default {
// 6. 'models.button.accessSettings': 'Access Settings', // 6. 'models.button.accessSettings': 'Access Settings',
// 7. 'models.table.accessScope': 'Access Scope', // 7. 'models.table.accessScope': 'Access Scope',
// 8. 'models.table.accessScope.all': 'All users', // 8. 'models.table.accessScope.all': 'All users',
// 9. 'models.table.accessScope.selected': 'Selected users',
// 10. 'models.table.userSelection': 'User Selection', // 10. 'models.table.userSelection': 'User Selection',
// 11. 'models.table.filterByName': 'Filter by username', // 11. 'models.table.filterByName': 'Filter by username',
// 12. 'models.table.admin': 'Admin', // 12. 'models.table.admin': 'Admin',
@@ -215,6 +218,10 @@ export default {
// 23. 'models.form.chunkSize': 'Size Of Cache Chunks', // 23. 'models.form.chunkSize': 'Size Of Cache Chunks',
// 24. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', // 24. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
// 25. 'models.form.remoteURL': 'Remote Storage URL', // 25. 'models.form.remoteURL': 'Remote Storage URL',
// 26. 'models.form.runCommandPlaceholder': 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct' // 26. 'models.form.runCommandPlaceholder': 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct',
// 27. 'models.accessSettings.public': 'Public',
// 28. 'models.accessSettings.authed': 'Authenticated',
// 29. 'models.accessSettings.allowedUsers': 'Allowed users',
// 30. 'models.accessSettings.public.tips': 'When set to public, anyone can access this model without authentication, which may lead to data exposure risks.'
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+2 -2
View File
@@ -14,13 +14,13 @@ export default {
'apikeys.form.expiration.never': 'Без срока действия', 'apikeys.form.expiration.never': 'Без срока действия',
'apikeys.table.bindModels': 'Доступ к моделям', 'apikeys.table.bindModels': 'Доступ к моделям',
'apikeys.models.all': 'All models', 'apikeys.models.all': 'All models',
'apikeys.models.selected': 'Selected models', 'apikeys.models.selected': 'Allowed models',
'apikeys.models.noModelsFound': 'No models found' 'apikeys.models.noModelsFound': 'No models found'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'apikeys.table.bindModels': 'Model Access', // 1. 'apikeys.table.bindModels': 'Model Access',
// 2. 'apikeys.models.all': 'All models', // 2. 'apikeys.models.all': 'All models',
// 3. 'apikeys.models.selected': 'Selected models', // 3. 'apikeys.models.selected': 'Allowed models',
// 4. 'apikeys.models.noModelsFound': 'No models found' // 4. 'apikeys.models.noModelsFound': 'No models found'
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+11 -4
View File
@@ -174,7 +174,6 @@ export default {
'models.button.accessSettings': 'Access Settings', 'models.button.accessSettings': 'Access Settings',
'models.table.accessScope': 'Access Scope', 'models.table.accessScope': 'Access Scope',
'models.table.accessScope.all': 'All users', 'models.table.accessScope.all': 'All users',
'models.table.accessScope.selected': 'Selected users',
'models.table.userSelection': 'User Selection', 'models.table.userSelection': 'User Selection',
'models.table.filterByName': 'Filter by username', 'models.table.filterByName': 'Filter by username',
'models.table.admin': 'Admin', 'models.table.admin': 'Admin',
@@ -189,14 +188,18 @@ export default {
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
'models.form.remoteURL': 'Remote Storage URL', 'models.form.remoteURL': 'Remote Storage URL',
'models.form.runCommandPlaceholder': 'models.form.runCommandPlaceholder':
'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct' 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct',
'models.accessSettings.public': 'Public',
'models.accessSettings.authed': 'Authenticated',
'models.accessSettings.allowedUsers': 'Allowed users',
'models.accessSettings.public.tips':
'When set to public, anyone can access this model without authentication, which may lead to data exposure risks.'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'models.button.accessSettings': 'Access Settings', // 1. 'models.button.accessSettings': 'Access Settings',
// 2. 'models.table.accessScope': 'Access Scope', // 2. 'models.table.accessScope': 'Access Scope',
// 3. 'models.table.accessScope.all': 'All users', // 3. 'models.table.accessScope.all': 'All users',
// 4. 'models.table.accessScope.selected': 'Selected users',
// 5. 'models.table.userSelection': 'User Selection', // 5. 'models.table.userSelection': 'User Selection',
// 6. 'models.table.filterByName': 'Filter by username', // 6. 'models.table.filterByName': 'Filter by username',
// 7. 'models.table.admin': 'Admin', // 7. 'models.table.admin': 'Admin',
@@ -210,5 +213,9 @@ export default {
// 15. 'models.form.chunkSize': 'Size Of Cache Chunks', // 15. 'models.form.chunkSize': 'Size Of Cache Chunks',
// 16. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', // 16. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
// 17. 'models.form.remoteURL': 'Remote Storage URL', // 17. 'models.form.remoteURL': 'Remote Storage URL',
// 18. 'models.form.runCommandPlaceholder': 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct'; // 18. 'models.form.runCommandPlaceholder': 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct'
// 19. 'models.accessSettings.public': 'Public',
// 20. 'models.accessSettings.authed': 'Authenticated',
// 21. 'models.accessSettings.allowedUsers': 'Allowed users',
// 22. 'models.accessSettings.public.tips': 'When set to public, anyone can access this model without authentication, which may lead to data exposure risks.'
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+6 -2
View File
@@ -164,7 +164,6 @@ export default {
'models.button.accessSettings': '访问设置', 'models.button.accessSettings': '访问设置',
'models.table.accessScope': '访问范围', 'models.table.accessScope': '访问范围',
'models.table.accessScope.all': '所有用户', 'models.table.accessScope.all': '所有用户',
'models.table.accessScope.selected': '指定用户',
'models.table.userSelection': '用户选择', 'models.table.userSelection': '用户选择',
'models.table.filterByName': '按用户名筛选', 'models.table.filterByName': '按用户名筛选',
'models.table.admin': '管理员', 'models.table.admin': '管理员',
@@ -179,5 +178,10 @@ export default {
'models.form.maxCPUSize': 'CPU 缓存最大占用 (GiB)', 'models.form.maxCPUSize': 'CPU 缓存最大占用 (GiB)',
'models.form.remoteURL': '远程存储地址', 'models.form.remoteURL': '远程存储地址',
'models.form.runCommandPlaceholder': 'models.form.runCommandPlaceholder':
'例如,vllm serve Qwen/Qwen2.5-1.5B-Instruct' '例如,vllm serve Qwen/Qwen2.5-1.5B-Instruct',
'models.accessSettings.public': '公开',
'models.accessSettings.authed': '认证用户',
'models.accessSettings.allowedUsers': '指定用户',
'models.accessSettings.public.tips':
'公开后,任何人无需认证即可访问,可能存在数据泄露风险。'
}; };
+6 -6
View File
@@ -144,20 +144,20 @@ export const frameworks = [
]; ];
export const yamlTemplate = `# backend configuration template export const yamlTemplate = `# backend configuration template
backend_name: SGLang backend_name: my-backend
description: SGLang backend description: this is my-backend
default_version: v0.5.1 default_version: v0.5.1
health_check_path: /health health_check_path: /health
default_backend_param: default_backend_param:
- --host - --host
default_run_command: run sglang default_run_command: myBackend serve {model} --port {port}
version_configs: version_configs:
v0.0.1: v0.0.1:
image_name: lm/sglang image_name: lm/mybackend:latest
run_command: run sglang run_command: myBackend serve {model} --port {port}
custom_framework: cuda custom_framework: cuda
v0.0.2: v0.0.2:
image_name: lm/sglang image_name: lm/mybackend:test
run_command: run_command:
custom_framework: custom_framework:
`; `;
+1 -1
View File
@@ -48,7 +48,7 @@ const BackendList = () => {
isInfiniteScroll: true, isInfiniteScroll: true,
contentForDelete: 'backends.title', contentForDelete: 'backends.title',
defaultQueryParams: { defaultQueryParams: {
perPage: 100 perPage: 24
} }
}); });
const { exportYAML } = useExportYAML(); const { exportYAML } = useExportYAML();
+2 -1
View File
@@ -4,6 +4,7 @@ import { PipelineType } from '@huggingface/tasks';
import { request } from '@umijs/max'; import { request } from '@umijs/max';
import qs from 'query-string'; import qs from 'query-string';
import { import {
AccessControlFormData,
CatalogItem, CatalogItem,
CatalogSpec, CatalogSpec,
EvaluateResult, EvaluateResult,
@@ -426,7 +427,7 @@ export async function queryModelAccessUserList(id: number) {
export async function updateModelAccessUser(params: { export async function updateModelAccessUser(params: {
id: number; id: number;
data: { users: { id: number }[]; set_public: boolean }; data: AccessControlFormData;
}) { }) {
return request(`${MODELS_API}/${params.id}/access`, { return request(`${MODELS_API}/${params.id}/access`, {
method: 'POST', method: 'POST',
@@ -25,7 +25,7 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
const { currentData, onFinish } = props; const { currentData, onFinish } = props;
const intl = useIntl(); const intl = useIntl();
const [form] = Form.useForm(); const [form] = Form.useForm();
const setPublic = Form.useWatch('set_public', form); const accessPolicy = Form.useWatch('access_policy', form);
const [targetKeys, setTargetKeys] = useState<TransferKey[]>([]); const [targetKeys, setTargetKeys] = useState<TransferKey[]>([]);
const [totalPages, setTotalPages] = useState(0); const [totalPages, setTotalPages] = useState(0);
const [userList, setUserList] = useState<{ title: string; key: number }[]>( const [userList, setUserList] = useState<{ title: string; key: number }[]>(
@@ -86,7 +86,7 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
const keys = res.items.map((item) => item.id); const keys = res.items.map((item) => item.id);
setTargetKeys(keys); setTargetKeys(keys);
form.setFieldsValue({ form.setFieldsValue({
set_public: currentData.public, access_policy: currentData.access_policy,
users: res.items.map((item) => ({ id: item.id })) users: res.items.map((item) => ({ id: item.id }))
}); });
}); });
@@ -105,28 +105,34 @@ const AccessControlForm = forwardRef((props: AccessControlFormProps, ref) => {
clearOnDestroy={true} clearOnDestroy={true}
scrollToFirstError={true} scrollToFirstError={true}
initialValues={{ initialValues={{
set_public: true access_policy: 'authed'
}} }}
> >
<Label>{intl.formatMessage({ id: 'models.table.accessScope' })}</Label> <Label>{intl.formatMessage({ id: 'models.table.accessScope' })}</Label>
<Form.Item<AccessControlFormData> name="set_public" noStyle> <Form.Item<AccessControlFormData> name="access_policy" noStyle>
<Radio.Group <Radio.Group
style={{ marginBottom: 12 }} style={{ marginBottom: 12 }}
options={[ options={[
{ {
label: intl.formatMessage({ id: 'models.table.accessScope.all' }), label: intl.formatMessage({ id: 'models.accessSettings.authed' }),
value: true value: 'authed'
}, },
{ {
label: intl.formatMessage({ label: intl.formatMessage({
id: 'models.table.accessScope.selected' id: 'models.accessSettings.allowedUsers'
}), }),
value: false value: 'allowed_users'
},
{
label: intl.formatMessage({
id: 'models.accessSettings.public'
}),
value: 'public'
} }
]} ]}
></Radio.Group> ></Radio.Group>
</Form.Item> </Form.Item>
{!setPublic && ( {accessPolicy === 'allowed_users' && (
<> <>
<Label> <Label>
{intl.formatMessage({ id: 'models.table.userSelection' })} {intl.formatMessage({ id: 'models.table.userSelection' })}
@@ -20,8 +20,9 @@ const AccessControlModal: React.FC<
const handleOnFinish = async (values: AccessControlFormData) => { const handleOnFinish = async (values: AccessControlFormData) => {
try { try {
const data = { const data = {
set_public: values.set_public, access_policy: values.access_policy,
users: values.set_public ? [] : values.users || [] users:
values.access_policy === 'allowed_users' ? values.users || [] : []
}; };
await updateModelAccessUser({ await updateModelAccessUser({
id: currentData?.id as number, id: currentData?.id as number,
+2 -2
View File
@@ -24,7 +24,7 @@ export interface ListItem {
local_path?: string; local_path?: string;
created_at: string; created_at: string;
updated_at: string; updated_at: string;
public?: boolean; access_policy: 'public' | 'authed' | 'allowed_users';
gpu_selector?: { gpu_selector?: {
gpu_ids: string[]; gpu_ids: string[];
}; };
@@ -261,6 +261,6 @@ export interface BackendOption {
} }
export interface AccessControlFormData { export interface AccessControlFormData {
set_public: boolean; access_policy: 'public' | 'authed' | 'allowed_users';
users: { id: number }[]; users: { id: number }[];
} }
+4 -1
View File
@@ -28,7 +28,10 @@ const UserModels: React.FC = () => {
fetchAPI: queryMyModels, fetchAPI: queryMyModels,
API: MY_MODELS_API, API: MY_MODELS_API,
watch: false, watch: false,
isInfiniteScroll: true isInfiniteScroll: true,
defaultQueryParams: {
perPage: 24
}
}); });
const intl = useIntl(); const intl = useIntl();