chore: access, endpoints to route targets
This commit is contained in:
+4
-4
@@ -116,14 +116,14 @@ export default [
|
||||
component: './maas-provider/index'
|
||||
},
|
||||
{
|
||||
name: 'accesses',
|
||||
path: '/models/accesses',
|
||||
key: 'accesses',
|
||||
name: 'routes',
|
||||
path: '/models/routes',
|
||||
key: 'routes',
|
||||
icon: 'icon-captive_portal',
|
||||
selectedIcon: 'icon-captive_portal',
|
||||
defaultIcon: 'icon-captive_portal',
|
||||
access: 'canSeeAdmin',
|
||||
component: './model-access/index'
|
||||
component: './model-routes/index'
|
||||
},
|
||||
{
|
||||
name: 'userModels',
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
export default {
|
||||
'accesses.title': 'Accesses',
|
||||
'accesses.button.add': 'Add Access',
|
||||
'accesses.table.accessPoints': 'Access Points',
|
||||
'accesses.table.traffic': 'Traffic Share',
|
||||
'accesses.table.setAsFallback': 'Set as Fallback',
|
||||
'accesses.form.endpoint.title': 'Endpoints',
|
||||
'accesses.form.endpoint.add': 'Add Endpoint',
|
||||
'accesses.form.endpoint.fallback': 'Fallback Endpoint',
|
||||
'accesses.form.endpoint.weight': 'Weight',
|
||||
'accesses.form.endpoint.model': 'Model',
|
||||
'accesses.form.metadata.title': 'Metadata',
|
||||
'accesses.form.metadata.add': 'Add Metadata',
|
||||
'accesses.table.label.fallback': 'Fallback',
|
||||
'accesses.form.metadata.size': 'Size',
|
||||
'accesses.form.metadata.activeSize': 'Active Size',
|
||||
'accesses.form.metadata.tags': 'Tags',
|
||||
'accesses.form.metadata.maxTokens': 'Max Tokens',
|
||||
'accesses.form.metadata.dimension': 'Dimensions',
|
||||
'accesses.form.metadata.license': 'Licenses',
|
||||
'accesses.form.metadata.releaseDate': 'Release Date',
|
||||
'accesses.form.metadata.languages': 'Languages',
|
||||
'accesses.form.metadata.icons': 'Icon',
|
||||
'accesses.form.metadata.uploadIcon': 'Upload Icon'
|
||||
};
|
||||
@@ -17,7 +17,7 @@ export default {
|
||||
'menu.models.benchmark': 'Benchmarks',
|
||||
'menu.models.benchmarkDetail': 'Benchmark Details',
|
||||
'menu.models.providers': 'Providers',
|
||||
'menu.models.accesses': 'Accesses',
|
||||
'menu.models.routes': 'Routes',
|
||||
'menu.modelCatalog': 'Catalog',
|
||||
'menu.resources': 'Resources',
|
||||
'menu.apikeys': 'API Keys',
|
||||
|
||||
@@ -13,6 +13,6 @@ export default {
|
||||
'providers.form.customConfig': 'Custom Configuration',
|
||||
'providers.form.model.test': 'Test',
|
||||
'providers.form.model.test.tips': 'Test Connection',
|
||||
'providers.form.endpoint.placeholder': 'provider/models',
|
||||
'providers.form.target.placeholder': 'provider/models',
|
||||
'providers.form.fallback.token': 'Fallback API Keys'
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
export default {
|
||||
'routes.title': 'Routes',
|
||||
'routes.button.add': 'Add Route',
|
||||
'routes.table.routeTargets': 'Route Targets',
|
||||
'routes.table.traffic': 'Traffic Share',
|
||||
'routes.table.setAsFallback': 'Set as Fallback',
|
||||
'routes.form.target.title': 'Route Targets',
|
||||
'routes.form.target.add': 'Add Route Target',
|
||||
'routes.form.target.fallback': 'Fallback Route Target',
|
||||
'routes.form.target.weight': 'Weight',
|
||||
'routes.form.target.model': 'Model',
|
||||
'routes.form.metadata.title': 'Metadata',
|
||||
'routes.form.metadata.add': 'Add Metadata',
|
||||
'routes.table.label.fallback': 'Fallback',
|
||||
'routes.form.metadata.size': 'Size',
|
||||
'routes.form.metadata.activeSize': 'Active Size',
|
||||
'routes.form.metadata.tags': 'Tags',
|
||||
'routes.form.metadata.maxTokens': 'Max Tokens',
|
||||
'routes.form.metadata.dimension': 'Dimensions',
|
||||
'routes.form.metadata.license': 'Licenses',
|
||||
'routes.form.metadata.releaseDate': 'Release Date',
|
||||
'routes.form.metadata.languages': 'Languages',
|
||||
'routes.form.metadata.icons': 'Icon',
|
||||
'routes.form.metadata.uploadIcon': 'Upload Icon'
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
export default {
|
||||
'accesses.title': 'Accesses',
|
||||
'accesses.button.add': 'Add Access',
|
||||
'accesses.table.accessPoints': 'Access Points',
|
||||
'accesses.table.traffic': 'Traffic Share',
|
||||
'accesses.table.setAsFallback': 'Set as Fallback',
|
||||
'accesses.form.endpoint.title': 'Endpoints',
|
||||
'accesses.form.endpoint.add': 'Add Endpoint',
|
||||
'accesses.form.endpoint.fallback': 'Fallback Endpoint',
|
||||
'accesses.form.endpoint.weight': 'Weight',
|
||||
'accesses.form.endpoint.model': 'Model',
|
||||
'accesses.form.metadata.title': 'Metadata',
|
||||
'accesses.form.metadata.add': 'Add Metadata',
|
||||
'accesses.table.label.fallback': 'Fallback',
|
||||
'accesses.form.metadata.size': 'Size',
|
||||
'accesses.form.metadata.activeSize': 'Active Size',
|
||||
'accesses.form.metadata.tags': 'Tags',
|
||||
'accesses.form.metadata.maxTokens': 'Max Tokens',
|
||||
'accesses.form.metadata.dimension': 'Dimensions',
|
||||
'accesses.form.metadata.license': 'Licenses',
|
||||
'accesses.form.metadata.releaseDate': 'Release Date',
|
||||
'accesses.form.metadata.languages': 'Languages',
|
||||
'accesses.form.metadata.icons': 'Icon',
|
||||
'accesses.form.metadata.uploadIcon': 'Upload Icon'
|
||||
};
|
||||
@@ -17,7 +17,7 @@ export default {
|
||||
'menu.models.benchmarkDetail': 'Benchmark Details',
|
||||
'menu.modelCatalog': 'カタログ',
|
||||
'menu.models.providers': 'Providers',
|
||||
'menu.models.accesses': 'Accesses',
|
||||
'menu.models.routes': 'Routes',
|
||||
'menu.resources': 'リソース',
|
||||
'menu.apikeys': 'APIキー',
|
||||
'menu.users': 'ユーザー',
|
||||
@@ -58,4 +58,5 @@ export default {
|
||||
// 15. 'menu.models.benchmark': 'Benchmarks',
|
||||
// 15. 'menu.models.provider': 'Provider',
|
||||
// 15. 'menu.models.providers': 'Provider',
|
||||
// 16. 'menu.models.routes': 'Routes',
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -13,6 +13,6 @@ export default {
|
||||
'providers.form.customConfig': 'Custom Configuration',
|
||||
'providers.form.model.test': 'Test',
|
||||
'providers.form.model.test.tips': 'Test Connection',
|
||||
'providers.form.endpoint.placeholder': 'provider/models',
|
||||
'providers.form.target.placeholder': 'provider/models',
|
||||
'providers.form.fallback.token': 'Fallback API Keys'
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
export default {
|
||||
'routes.title': 'Routes',
|
||||
'routes.button.add': 'Add Route',
|
||||
'routes.table.routeTargets': 'Route Targets',
|
||||
'routes.table.traffic': 'Traffic Share',
|
||||
'routes.table.setAsFallback': 'Set as Fallback',
|
||||
'routes.form.target.title': 'Route Targets',
|
||||
'routes.form.target.add': 'Add Route Target',
|
||||
'routes.form.target.fallback': 'Fallback Route Target',
|
||||
'routes.form.target.weight': 'Weight',
|
||||
'routes.form.target.model': 'Model',
|
||||
'routes.form.metadata.title': 'Metadata',
|
||||
'routes.form.metadata.add': 'Add Metadata',
|
||||
'routes.table.label.fallback': 'Fallback',
|
||||
'routes.form.metadata.size': 'Size',
|
||||
'routes.form.metadata.activeSize': 'Active Size',
|
||||
'routes.form.metadata.tags': 'Tags',
|
||||
'routes.form.metadata.maxTokens': 'Max Tokens',
|
||||
'routes.form.metadata.dimension': 'Dimensions',
|
||||
'routes.form.metadata.license': 'Licenses',
|
||||
'routes.form.metadata.releaseDate': 'Release Date',
|
||||
'routes.form.metadata.languages': 'Languages',
|
||||
'routes.form.metadata.icons': 'Icon',
|
||||
'routes.form.metadata.uploadIcon': 'Upload Icon'
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
export default {
|
||||
'accesses.title': 'Accesses',
|
||||
'accesses.button.add': 'Add Access',
|
||||
'accesses.table.accessPoints': 'Access Points',
|
||||
'accesses.table.traffic': 'Traffic Share',
|
||||
'accesses.table.setAsFallback': 'Set as Fallback',
|
||||
'accesses.form.endpoint.title': 'Endpoints',
|
||||
'accesses.form.endpoint.add': 'Add Endpoint',
|
||||
'accesses.form.endpoint.fallback': 'Fallback Endpoint',
|
||||
'accesses.form.endpoint.weight': 'Weight',
|
||||
'accesses.form.endpoint.model': 'Model',
|
||||
'accesses.form.metadata.title': 'Metadata',
|
||||
'accesses.form.metadata.add': 'Add Metadata',
|
||||
'accesses.table.label.fallback': 'Fallback',
|
||||
'accesses.form.metadata.size': 'Size',
|
||||
'accesses.form.metadata.activeSize': 'Active Size',
|
||||
'accesses.form.metadata.tags': 'Tags',
|
||||
'accesses.form.metadata.maxTokens': 'Max Tokens',
|
||||
'accesses.form.metadata.dimension': 'Dimensions',
|
||||
'accesses.form.metadata.license': 'Licenses',
|
||||
'accesses.form.metadata.releaseDate': 'Release Date',
|
||||
'accesses.form.metadata.languages': 'Languages',
|
||||
'accesses.form.metadata.icons': 'Icon',
|
||||
'accesses.form.metadata.uploadIcon': 'Upload Icon'
|
||||
};
|
||||
@@ -17,7 +17,7 @@ export default {
|
||||
'menu.models.benchmarkDetail': 'Benchmark Details',
|
||||
'menu.models.provider': 'Provider',
|
||||
'menu.models.providers': 'Providers',
|
||||
'menu.models.accesses': 'Accesses',
|
||||
'menu.models.routes': 'Routes',
|
||||
'menu.modelCatalog': 'Каталог',
|
||||
'menu.resources': 'Ресурсы',
|
||||
'menu.apikeys': 'API-ключи',
|
||||
@@ -42,16 +42,8 @@ export default {
|
||||
};
|
||||
|
||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
// 1. 'menu.models.benchmark': 'Benchmarks',
|
||||
// 2. 'menu.models.benchmarkDetail': 'Benchmark Details',
|
||||
// 1. 'menu.models.provider': 'Provider',
|
||||
=======
|
||||
// 1. 'menu.models.providers': 'Provider',
|
||||
>>>>>>> ddf1a270 (feat: provider lsit)
|
||||
=======
|
||||
// 1. 'menu.models.providers': 'Providers',
|
||||
// 2. 'menu.models.accesses': 'Accesses',
|
||||
>>>>>>> 11d2c02d (feat: add access list)
|
||||
// 3. 'menu.models.providers': 'Providers',
|
||||
// 4. 'menu.models.routes': 'Routes',
|
||||
// ========== End of To-Do List ==========
|
||||
|
||||
@@ -13,6 +13,6 @@ export default {
|
||||
'providers.form.customConfig': 'Custom Configuration',
|
||||
'providers.form.model.test': 'Test',
|
||||
'providers.form.model.test.tips': 'Test Connection',
|
||||
'providers.form.endpoint.placeholder': 'provider/models',
|
||||
'providers.form.target.placeholder': 'provider/models',
|
||||
'providers.form.fallback.token': 'Fallback API Keys'
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
export default {
|
||||
'routes.title': 'Routes',
|
||||
'routes.button.add': 'Add Route',
|
||||
'routes.table.routeTargets': 'Route Targets',
|
||||
'routes.table.traffic': 'Traffic Share',
|
||||
'routes.table.setAsFallback': 'Set as Fallback',
|
||||
'routes.form.target.title': 'Route Targets',
|
||||
'routes.form.target.add': 'Add Route Target',
|
||||
'routes.form.target.fallback': 'Fallback Route Target',
|
||||
'routes.form.target.weight': 'Weight',
|
||||
'routes.form.target.model': 'Model',
|
||||
'routes.form.metadata.title': 'Metadata',
|
||||
'routes.form.metadata.add': 'Add Metadata',
|
||||
'routes.table.label.fallback': 'Fallback',
|
||||
'routes.form.metadata.size': 'Size',
|
||||
'routes.form.metadata.activeSize': 'Active Size',
|
||||
'routes.form.metadata.tags': 'Tags',
|
||||
'routes.form.metadata.maxTokens': 'Max Tokens',
|
||||
'routes.form.metadata.dimension': 'Dimensions',
|
||||
'routes.form.metadata.license': 'Licenses',
|
||||
'routes.form.metadata.releaseDate': 'Release Date',
|
||||
'routes.form.metadata.languages': 'Languages',
|
||||
'routes.form.metadata.icons': 'Icon',
|
||||
'routes.form.metadata.uploadIcon': 'Upload Icon'
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
export default {
|
||||
'accesses.title': '接入',
|
||||
'accesses.button.add': '添加接入',
|
||||
'accesses.table.accessPoints': '接入点',
|
||||
'accesses.table.traffic': '流量',
|
||||
'accesses.table.setAsFallback': '降级',
|
||||
'accesses.form.endpoint.title': '接入点',
|
||||
'accesses.form.endpoint.add': '添加接入点',
|
||||
'accesses.form.endpoint.fallback': '降级接入点',
|
||||
'accesses.form.endpoint.weight': '权重',
|
||||
'accesses.form.endpoint.model': '模型',
|
||||
'accesses.form.metadata.title': '元数据',
|
||||
'accesses.form.metadata.add': '添加元数据',
|
||||
'accesses.table.label.fallback': '降级',
|
||||
'accesses.form.metadata.size': '参数量',
|
||||
'accesses.form.metadata.activeSize': '激活参数量',
|
||||
'accesses.form.metadata.tags': '标签',
|
||||
'accesses.form.metadata.maxTokens': '最大上下文长度',
|
||||
'accesses.form.metadata.dimension': '维度',
|
||||
'accesses.form.metadata.license': '许可证',
|
||||
'accesses.form.metadata.releaseDate': '发布日期',
|
||||
'accesses.form.metadata.languages': '语言',
|
||||
'accesses.form.metadata.icons': '图标',
|
||||
'accesses.form.metadata.uploadIcon': '上传图标'
|
||||
};
|
||||
@@ -16,7 +16,7 @@ export default {
|
||||
'menu.models.benchmark': '基准测试',
|
||||
'menu.models.benchmarkDetail': '基准测试详情',
|
||||
'menu.models.providers': '提供商',
|
||||
'menu.models.accesses': '接入',
|
||||
'menu.models.routes': '路由',
|
||||
'menu.modelCatalog': '模型库',
|
||||
'menu.models.catalog': '模型库',
|
||||
'menu.resources': '资源',
|
||||
|
||||
@@ -13,6 +13,6 @@ export default {
|
||||
'providers.form.customConfig': '自定义配置',
|
||||
'providers.form.model.test': '测试',
|
||||
'providers.form.model.test.tips': '测试连接',
|
||||
'providers.form.endpoint.placeholder': '提供商/模型',
|
||||
'providers.form.target.placeholder': '提供商/模型',
|
||||
'providers.form.fallback.token': '备用 API Key'
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
export default {
|
||||
'routes.title': '路由',
|
||||
'routes.button.add': '添加路由',
|
||||
'routes.table.routeTargets': '路由目标',
|
||||
'routes.table.traffic': '流量',
|
||||
'routes.table.setAsFallback': '降级',
|
||||
'routes.form.target.title': '路由目标',
|
||||
'routes.form.target.add': '添加路由目标',
|
||||
'routes.form.target.fallback': '降级路由目标',
|
||||
'routes.form.target.weight': '权重',
|
||||
'routes.form.target.model': '模型',
|
||||
'routes.form.metadata.title': '元数据',
|
||||
'routes.form.metadata.add': '添加元数据',
|
||||
'routes.table.label.fallback': '降级',
|
||||
'routes.form.metadata.size': '参数量',
|
||||
'routes.form.metadata.activeSize': '激活参数量',
|
||||
'routes.form.metadata.tags': '标签',
|
||||
'routes.form.metadata.maxTokens': '最大上下文长度',
|
||||
'routes.form.metadata.dimension': '维度',
|
||||
'routes.form.metadata.license': '许可证',
|
||||
'routes.form.metadata.releaseDate': '发布日期',
|
||||
'routes.form.metadata.languages': '语言',
|
||||
'routes.form.metadata.icons': '图标',
|
||||
'routes.form.metadata.uploadIcon': '上传图标'
|
||||
};
|
||||
@@ -3,7 +3,7 @@ import { downloadFile, listFiles, listModels } from '@huggingface/hub';
|
||||
import { PipelineType } from '@huggingface/tasks';
|
||||
import { request } from '@umijs/max';
|
||||
import qs from 'query-string';
|
||||
import { ACCESS_API } from '../../model-access/apis';
|
||||
import { MODEL_ROUTES } from '../../model-routes/apis';
|
||||
import {
|
||||
AccessControlFormData,
|
||||
BackendItem,
|
||||
@@ -419,7 +419,7 @@ export async function queryBackendList(params?: { cluster_id: number }) {
|
||||
}
|
||||
|
||||
export async function queryModelAccessUserList(id: number) {
|
||||
return request<{ items: UserListItem[] }>(`${ACCESS_API}/${id}/access`, {
|
||||
return request<{ items: UserListItem[] }>(`${MODEL_ROUTES}/${id}/access`, {
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
@@ -428,7 +428,7 @@ export async function updateModelAccessUser(params: {
|
||||
id: number;
|
||||
data: AccessControlFormData;
|
||||
}) {
|
||||
return request(`${ACCESS_API}/${params.id}/access`, {
|
||||
return request(`${MODEL_ROUTES}/${params.id}/access`, {
|
||||
method: 'POST',
|
||||
data: params.data
|
||||
});
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
import { request } from '@umijs/max';
|
||||
import { AccessItem, AccessPointItem, FormData } from '../config/types';
|
||||
|
||||
export const ACCESS_API = '/model-accesses';
|
||||
|
||||
export const ACCESS_POINTS_API = '/model-access-endpoints';
|
||||
|
||||
export async function queryModelAccesses(
|
||||
params: Global.SearchParams,
|
||||
options?: any
|
||||
) {
|
||||
return request<Global.PageResponse<AccessItem>>(ACCESS_API, {
|
||||
params,
|
||||
method: 'GET',
|
||||
cancelToken: options?.token
|
||||
});
|
||||
}
|
||||
|
||||
export async function createAccess(params: { data: FormData }) {
|
||||
return request(`${ACCESS_API}`, {
|
||||
method: 'POST',
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateAccess(params: { id: number; data: FormData }) {
|
||||
return request(`${ACCESS_API}/${params.id}`, {
|
||||
method: 'PUT',
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
|
||||
export async function deleteAccess(id: number) {
|
||||
return request(`${ACCESS_API}/${id}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
export async function queryAccessPoints(params: { id: number }, options?: any) {
|
||||
return request<Global.PageResponse<AccessPointItem>>(
|
||||
`${ACCESS_POINTS_API}?access_id=${params.id}`,
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
page: -1
|
||||
},
|
||||
cancelToken: options?.token
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export async function deleteAccessPoint(id: number) {
|
||||
return request(`${ACCESS_POINTS_API}/${id}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateAccessPoint(params: {
|
||||
id: number;
|
||||
data: Partial<AccessPointItem>;
|
||||
}) {
|
||||
return request(`${ACCESS_POINTS_API}/${params.id}`, {
|
||||
method: 'PUT',
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
|
||||
export async function setAccessPointAsFallback(params: {
|
||||
id: number;
|
||||
data: Partial<AccessPointItem>;
|
||||
}) {
|
||||
return request(`${ACCESS_POINTS_API}/${params.id}/set-fallback`, {
|
||||
method: 'POST',
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { queryAccessPoints } from '../apis';
|
||||
import { AccessPointItem } from '../config/types';
|
||||
|
||||
const useEditEndpoints = () => {
|
||||
const generateEndpointData = (endpoints: AccessPointItem[]) => {
|
||||
const fallbackEndpoint =
|
||||
endpoints?.filter(
|
||||
(ep) => ep.fallback_status_codes && ep.fallback_status_codes?.length > 0
|
||||
)?.[0] || null;
|
||||
|
||||
const endPoints = endpoints?.filter(
|
||||
(ep) =>
|
||||
!ep.fallback_status_codes || ep.fallback_status_codes?.length === 0
|
||||
);
|
||||
|
||||
return {
|
||||
endpoints: endPoints,
|
||||
fallbackEndpoint: fallbackEndpoint
|
||||
};
|
||||
};
|
||||
|
||||
const fetchEndpoints = async (accessId: number) => {
|
||||
try {
|
||||
const res = await queryAccessPoints({ id: accessId });
|
||||
return res.items || [];
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
generateEndpointData,
|
||||
fetchEndpoints
|
||||
};
|
||||
};
|
||||
|
||||
export default useEditEndpoints;
|
||||
@@ -0,0 +1,76 @@
|
||||
import { request } from '@umijs/max';
|
||||
import { FormData, RouteItem, RouteTarget } from '../config/types';
|
||||
|
||||
export const MODEL_ROUTES = '/model-routes';
|
||||
|
||||
export const MODEL_ROUTE_TARGETS = '/model-route-targets';
|
||||
|
||||
export async function queryModelRoutes(
|
||||
params: Global.SearchParams,
|
||||
options?: any
|
||||
) {
|
||||
return request<Global.PageResponse<RouteItem>>(MODEL_ROUTES, {
|
||||
params,
|
||||
method: 'GET',
|
||||
cancelToken: options?.token
|
||||
});
|
||||
}
|
||||
|
||||
export async function createModelRoute(params: { data: FormData }) {
|
||||
return request(`${MODEL_ROUTES}`, {
|
||||
method: 'POST',
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateModelRoute(params: { id: number; data: FormData }) {
|
||||
return request(`${MODEL_ROUTES}/${params.id}`, {
|
||||
method: 'PUT',
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
|
||||
export async function deleteModelRoute(id: number) {
|
||||
return request(`${MODEL_ROUTES}/${id}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
export async function queryRouteTargets(params: { id: number }, options?: any) {
|
||||
return request<Global.PageResponse<RouteTarget>>(
|
||||
`${MODEL_ROUTE_TARGETS}?route_id=${params.id}`,
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
page: -1
|
||||
},
|
||||
cancelToken: options?.token
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export async function deleteModelRouteTarget(id: number) {
|
||||
return request(`${MODEL_ROUTE_TARGETS}/${id}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateModelRouteTarget(params: {
|
||||
id: number;
|
||||
data: Partial<RouteTarget>;
|
||||
}) {
|
||||
return request(`${MODEL_ROUTE_TARGETS}/${params.id}`, {
|
||||
method: 'PUT',
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
|
||||
export async function setRouteTargetAsFallback(params: {
|
||||
id: number;
|
||||
data: Partial<RouteTarget>;
|
||||
}) {
|
||||
return request(`${MODEL_ROUTE_TARGETS}/${params.id}/set-fallback`, {
|
||||
method: 'POST',
|
||||
data: params.data
|
||||
});
|
||||
}
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
import { PageActionType } from '@/config/types';
|
||||
import FormDrawer from '@/pages/_components/form-drawer';
|
||||
import React, { useRef } from 'react';
|
||||
import { FormData, AccessItem as ListItem } from '../config/types';
|
||||
import { FormData, RouteItem as ListItem } from '../config/types';
|
||||
|
||||
import ModelAccessForm from '../forms';
|
||||
import ModelRouteForm from '../forms';
|
||||
|
||||
type AddModalProps = {
|
||||
title: string;
|
||||
@@ -46,7 +46,7 @@ const AddProvider: React.FC<AddModalProps> = ({
|
||||
onSubmit={handleSubmit}
|
||||
width={600}
|
||||
>
|
||||
<ModelAccessForm
|
||||
<ModelRouteForm
|
||||
ref={form}
|
||||
action={action}
|
||||
currentData={currentData}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import FormDrawer from '@/pages/_components/form-drawer';
|
||||
import React, { useRef } from 'react';
|
||||
import { FormData, AccessItem as ListItem } from '../config/types';
|
||||
import { FormData, RouteItem as ListItem } from '../config/types';
|
||||
import FallbackSettings from '../forms/fallback-settings';
|
||||
|
||||
type AddModalProps = {
|
||||
+13
-14
@@ -9,8 +9,8 @@ import { Col, Row } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { EndpointStatus, EndpointStatusLabelMap } from '../config';
|
||||
import { AccessPointItem } from '../config/types';
|
||||
import { TargetStatus, TargetStatusValueMap } from '../config';
|
||||
import { RouteTarget } from '../config/types';
|
||||
const CellContent = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -18,7 +18,7 @@ const CellContent = styled.div`
|
||||
`;
|
||||
|
||||
interface ProviderModelProps {
|
||||
dataList: AccessPointItem[];
|
||||
dataList: RouteTarget[];
|
||||
onSelect: (val: any, record: any) => void;
|
||||
sourceModels: any[];
|
||||
}
|
||||
@@ -32,7 +32,7 @@ interface AccessItemProps {
|
||||
export const childActionList = [
|
||||
{
|
||||
key: 'fallback',
|
||||
label: 'accesses.table.setAsFallback',
|
||||
label: 'routes.table.setAsFallback',
|
||||
icon: <IconFont type="icon-shield" />
|
||||
},
|
||||
{
|
||||
@@ -45,7 +45,7 @@ export const childActionList = [
|
||||
}
|
||||
];
|
||||
|
||||
const AccessItem: React.FC<AccessItemProps> = ({
|
||||
const RouteItem: React.FC<AccessItemProps> = ({
|
||||
onSelect,
|
||||
data,
|
||||
sourceModels
|
||||
@@ -82,7 +82,7 @@ const AccessItem: React.FC<AccessItemProps> = ({
|
||||
<CellContent>
|
||||
{data.weight > 0 && (
|
||||
<AutoTooltip ghost>
|
||||
{intl.formatMessage({ id: 'accesses.form.endpoint.weight' })}:{' '}
|
||||
{intl.formatMessage({ id: 'routes.form.target.weight' })}:{' '}
|
||||
{data.weight}
|
||||
</AutoTooltip>
|
||||
)}
|
||||
@@ -95,7 +95,7 @@ const AccessItem: React.FC<AccessItemProps> = ({
|
||||
)}
|
||||
<span>
|
||||
{intl.formatMessage({
|
||||
id: 'accesses.table.label.fallback'
|
||||
id: 'routes.table.label.fallback'
|
||||
})}
|
||||
</span>
|
||||
</>
|
||||
@@ -107,8 +107,8 @@ const AccessItem: React.FC<AccessItemProps> = ({
|
||||
<AutoTooltip ghost>
|
||||
<StatusTag
|
||||
statusValue={{
|
||||
status: EndpointStatus[data.state],
|
||||
text: EndpointStatusLabelMap[data.state],
|
||||
status: TargetStatus[data.state],
|
||||
text: TargetStatusValueMap[data.state],
|
||||
message: ''
|
||||
}}
|
||||
/>
|
||||
@@ -140,24 +140,23 @@ const AccessItem: React.FC<AccessItemProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const AccessPoints: React.FC<ProviderModelProps> = ({
|
||||
const RouteTargets: React.FC<ProviderModelProps> = ({
|
||||
dataList,
|
||||
onSelect,
|
||||
sourceModels
|
||||
}) => {
|
||||
console.log('AccessPoints dataList:', dataList);
|
||||
return (
|
||||
<div>
|
||||
{dataList.map((item, index) => (
|
||||
<AccessItem
|
||||
<RouteItem
|
||||
data={item}
|
||||
key={index}
|
||||
onSelect={onSelect}
|
||||
sourceModels={sourceModels}
|
||||
></AccessItem>
|
||||
></RouteItem>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AccessPoints;
|
||||
export default RouteTargets;
|
||||
@@ -2,19 +2,19 @@ import icons from '@/components/icon-font/icons';
|
||||
import { StatusMaps } from '@/config';
|
||||
import { StatusType } from '@/config/types';
|
||||
|
||||
export const EndpointsStatusValueMap: Record<string, string> = {
|
||||
export const TargetStatusValueMap: Record<string, string> = {
|
||||
Active: 'active',
|
||||
Unavailable: 'unavailable'
|
||||
};
|
||||
|
||||
export const EndpointStatusLabelMap = {
|
||||
[EndpointsStatusValueMap.Active]: 'Active',
|
||||
[EndpointsStatusValueMap.Unavailable]: 'Unavailable'
|
||||
export const TargetStatusLabelMap = {
|
||||
[TargetStatusValueMap.Active]: 'Active',
|
||||
[TargetStatusValueMap.Unavailable]: 'Unavailable'
|
||||
};
|
||||
|
||||
export const EndpointStatus: Record<string, StatusType> = {
|
||||
[EndpointsStatusValueMap.Active]: StatusMaps.success,
|
||||
[EndpointsStatusValueMap.Unavailable]: StatusMaps.error
|
||||
export const TargetStatus: Record<string, StatusType> = {
|
||||
[TargetStatusValueMap.Active]: StatusMaps.success,
|
||||
[TargetStatusValueMap.Unavailable]: StatusMaps.error
|
||||
};
|
||||
|
||||
// actions for each row
|
||||
@@ -4,13 +4,13 @@ export interface FormData {
|
||||
categories: any[];
|
||||
meta: Record<string, any>;
|
||||
generic_proxy: boolean;
|
||||
fallback_endpoint: {
|
||||
fallback_target: {
|
||||
provider_model_name?: string;
|
||||
model_id?: number;
|
||||
provider_id?: number;
|
||||
fallback_status_codes?: string[];
|
||||
};
|
||||
endpoints: {
|
||||
targets: {
|
||||
provider_model_name?: string;
|
||||
weight?: number | null;
|
||||
model_id?: number;
|
||||
@@ -19,7 +19,7 @@ export interface FormData {
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface AccessItem {
|
||||
export interface RouteItem {
|
||||
id: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
@@ -29,12 +29,12 @@ export interface AccessItem {
|
||||
categories: string[];
|
||||
meta: Record<string, any>;
|
||||
created_by_model: boolean;
|
||||
endpoints: number;
|
||||
ready_endpoints: number;
|
||||
targets: number;
|
||||
ready_targets: number;
|
||||
access_policy: string;
|
||||
}
|
||||
|
||||
export interface AccessPointItem {
|
||||
export interface RouteTarget {
|
||||
id: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
@@ -44,7 +44,7 @@ export interface AccessPointItem {
|
||||
model_id: number;
|
||||
provider_id: number;
|
||||
name: string;
|
||||
access_id: number;
|
||||
route_id: number;
|
||||
state: string;
|
||||
fallback_status_codes: string[];
|
||||
}
|
||||
@@ -14,10 +14,10 @@ import {
|
||||
useRef,
|
||||
useState
|
||||
} from 'react';
|
||||
import { FormData, AccessItem as ListItem } from '../config/types';
|
||||
import useEditEndpoints from '../hooks/use-edit-endpoints';
|
||||
import { FormData, RouteItem as ListItem } from '../config/types';
|
||||
import useEditTargets from '../hooks/use-edit-targets';
|
||||
import Basic from './basic';
|
||||
import Endpoints from './endpoints';
|
||||
import Targets from './targets';
|
||||
|
||||
interface ProviderFormProps {
|
||||
ref?: any;
|
||||
@@ -29,7 +29,7 @@ interface ProviderFormProps {
|
||||
const TABKeysMap = {
|
||||
BASIC: 'basic',
|
||||
METADATA: 'metadata',
|
||||
ENDPOINTS: 'endpoints',
|
||||
TARGETS: 'targets',
|
||||
ADVANCED: 'advanced'
|
||||
};
|
||||
|
||||
@@ -40,8 +40,8 @@ const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
const [activeKey, setActiveKey] = useState<string[]>([TABKeysMap.BASIC]);
|
||||
const [form] = Form.useForm();
|
||||
const scrollTabsRef = useRef<any>(null);
|
||||
const endpointsRef = useRef<any>(null);
|
||||
const { generateEndpointData, fetchEndpoints } = useEditEndpoints();
|
||||
const targetsRef = useRef<any>(null);
|
||||
const { generateTargetData, fetchTargets } = useEditTargets();
|
||||
const segmentOptions = [
|
||||
{
|
||||
value: TABKeysMap.BASIC,
|
||||
@@ -50,10 +50,10 @@ const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
field: 'name'
|
||||
},
|
||||
{
|
||||
value: TABKeysMap.ENDPOINTS,
|
||||
label: intl.formatMessage({ id: 'accesses.form.endpoint.title' }),
|
||||
value: TABKeysMap.TARGETS,
|
||||
label: intl.formatMessage({ id: 'routes.form.target.title' }),
|
||||
icon: <IconFont type="icon-language" />,
|
||||
field: 'endpoints'
|
||||
field: 'targets'
|
||||
}
|
||||
];
|
||||
|
||||
@@ -61,26 +61,25 @@ const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
setActiveKey(key);
|
||||
};
|
||||
|
||||
const formatEndpoints = (values: FormData) => {
|
||||
console.log('formatEndpoints values:', values);
|
||||
let endPoints = [...(values.endpoints || [])];
|
||||
let fallbackEndpoint = values.fallback_endpoint;
|
||||
const formatTargets = (values: FormData) => {
|
||||
let targetList = [...(values.targets || [])];
|
||||
let fallbackTarget = values.fallback_target;
|
||||
|
||||
if (fallbackEndpoint) {
|
||||
const exsitinged = endPoints.find((ep) => {
|
||||
if (fallbackEndpoint!.model_id) {
|
||||
return ep.model_id === fallbackEndpoint!.model_id;
|
||||
if (fallbackTarget) {
|
||||
const exsitinged = targetList.find((ep) => {
|
||||
if (fallbackTarget!.model_id) {
|
||||
return ep.model_id === fallbackTarget!.model_id;
|
||||
}
|
||||
return (
|
||||
ep.provider_id === fallbackEndpoint!.provider_id &&
|
||||
ep.provider_model_name === fallbackEndpoint!.provider_model_name
|
||||
ep.provider_id === fallbackTarget!.provider_id &&
|
||||
ep.provider_model_name === fallbackTarget!.provider_model_name
|
||||
);
|
||||
});
|
||||
if (exsitinged) {
|
||||
endPoints = endPoints.map((ep) => {
|
||||
targetList = targetList.map((ep) => {
|
||||
if (
|
||||
ep.model_id === fallbackEndpoint.model_id ||
|
||||
ep.provider_model_name === fallbackEndpoint.provider_model_name
|
||||
ep.model_id === fallbackTarget.model_id ||
|
||||
ep.provider_model_name === fallbackTarget.provider_model_name
|
||||
) {
|
||||
return {
|
||||
...ep,
|
||||
@@ -92,22 +91,22 @@ const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
}
|
||||
|
||||
if (!exsitinged) {
|
||||
endPoints.push({
|
||||
...fallbackEndpoint,
|
||||
targetList.push({
|
||||
...fallbackTarget,
|
||||
weight: 0,
|
||||
fallback_status_codes: ['4xx', '5xx']
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return endPoints;
|
||||
return targetList;
|
||||
};
|
||||
|
||||
const handleOnFinish = (values: FormData) => {
|
||||
const endpoints = formatEndpoints(values);
|
||||
const targets = formatTargets(values);
|
||||
const data = {
|
||||
..._.omit(values, ['endpoints', 'fallback_endpoint']),
|
||||
endpoints: endpoints
|
||||
..._.omit(values, ['targets', 'fallback_target']),
|
||||
targets: targets
|
||||
};
|
||||
console.log('data=========', data);
|
||||
onFinish(data);
|
||||
@@ -119,26 +118,19 @@ const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
|
||||
useEffect(() => {
|
||||
const initEditionForm = async () => {
|
||||
const endpointList = await fetchEndpoints(currentData!.id);
|
||||
const { endpoints, fallbackEndpoint } =
|
||||
generateEndpointData(endpointList);
|
||||
console.log(
|
||||
'endpoints:',
|
||||
endpoints,
|
||||
'fallbackEndpoint:',
|
||||
fallbackEndpoint
|
||||
);
|
||||
const targetList = await fetchTargets(currentData!.id);
|
||||
const { targets, fallbackTarget } = generateTargetData(targetList);
|
||||
|
||||
// init form values
|
||||
form.setFieldsValue({
|
||||
...currentData,
|
||||
endpoints: endpoints,
|
||||
fallback_endpoint: fallbackEndpoint
|
||||
targets: targets,
|
||||
fallback_target: fallbackTarget
|
||||
});
|
||||
|
||||
// init endpoints form list
|
||||
endpointsRef.current?.initDataList(
|
||||
endpoints?.map((ep) => ({
|
||||
// init targets form list
|
||||
targetsRef.current?.initDataList(
|
||||
targets?.map((ep) => ({
|
||||
weight: ep.weight,
|
||||
value: ep.model_id
|
||||
? ['deployments', ep.model_id]
|
||||
@@ -147,14 +139,11 @@ const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
);
|
||||
|
||||
// init fallback value
|
||||
if (fallbackEndpoint) {
|
||||
endpointsRef.current?.initFallbackValues({
|
||||
value: fallbackEndpoint.model_id
|
||||
? ['deployments', fallbackEndpoint.model_id]
|
||||
: [
|
||||
fallbackEndpoint.provider_id,
|
||||
fallbackEndpoint.provider_model_name
|
||||
]
|
||||
if (fallbackTarget) {
|
||||
targetsRef.current?.initFallbackValues({
|
||||
value: fallbackTarget.model_id
|
||||
? ['deployments', fallbackTarget.model_id]
|
||||
: [fallbackTarget.provider_id, fallbackTarget.provider_model_name]
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -202,10 +191,10 @@ const AccessForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||
onChange={handleOnCollapseChange}
|
||||
items={[
|
||||
{
|
||||
key: TABKeysMap.ENDPOINTS,
|
||||
label: intl.formatMessage({ id: 'accesses.form.endpoint.title' }),
|
||||
key: TABKeysMap.TARGETS,
|
||||
label: intl.formatMessage({ id: 'routes.form.target.title' }),
|
||||
forceRender: true,
|
||||
children: <Endpoints ref={endpointsRef}></Endpoints>
|
||||
children: <Targets ref={targetsRef}></Targets>
|
||||
}
|
||||
]}
|
||||
></CollapsePanel>
|
||||
+9
-9
@@ -64,7 +64,7 @@ const MetaData = () => {
|
||||
>
|
||||
<SealInputNumber
|
||||
min={0}
|
||||
label={`${intl.formatMessage({ id: 'accesses.form.metadata.size' })} (B)`}
|
||||
label={`${intl.formatMessage({ id: 'routes.form.metadata.size' })} (B)`}
|
||||
></SealInputNumber>
|
||||
</Form.Item>
|
||||
<Form.Item<FormData>
|
||||
@@ -74,7 +74,7 @@ const MetaData = () => {
|
||||
<SealInputNumber
|
||||
min={0}
|
||||
label={`${intl.formatMessage({
|
||||
id: 'accesses.form.metadata.activeSize'
|
||||
id: 'routes.form.metadata.activeSize'
|
||||
})} (B)`}
|
||||
></SealInputNumber>
|
||||
</Form.Item>
|
||||
@@ -83,7 +83,7 @@ const MetaData = () => {
|
||||
<Form.Item<FormData> name={['meta', 'max_tokens']}>
|
||||
<SealInput.Input
|
||||
label={intl.formatMessage({
|
||||
id: 'accesses.form.metadata.maxTokens'
|
||||
id: 'routes.form.metadata.maxTokens'
|
||||
})}
|
||||
placeholder={intl.formatMessage(
|
||||
{ id: 'common.help.eg' },
|
||||
@@ -100,7 +100,7 @@ const MetaData = () => {
|
||||
step={1}
|
||||
precision={0}
|
||||
label={intl.formatMessage({
|
||||
id: 'accesses.form.metadata.dimension'
|
||||
id: 'routes.form.metadata.dimension'
|
||||
})}
|
||||
></SealInputNumber>
|
||||
</Form.Item>
|
||||
@@ -108,7 +108,7 @@ const MetaData = () => {
|
||||
<Form.Item<FormData> name={['meta', 'release_date']}>
|
||||
<SealInput.Input
|
||||
label={intl.formatMessage({
|
||||
id: 'accesses.form.metadata.releaseDate'
|
||||
id: 'routes.form.metadata.releaseDate'
|
||||
})}
|
||||
placeholder={intl.formatMessage(
|
||||
{ id: 'common.help.eg' },
|
||||
@@ -126,7 +126,7 @@ const MetaData = () => {
|
||||
</Form.Item>
|
||||
<Form.Item<FormData> name={['meta', 'licenses']} data-field="metadata">
|
||||
<ListInput
|
||||
label={intl.formatMessage({ id: 'accesses.form.metadata.license' })}
|
||||
label={intl.formatMessage({ id: 'routes.form.metadata.license' })}
|
||||
btnText={intl.formatMessage({ id: 'common.button.addLabel' })}
|
||||
dataList={[]}
|
||||
onChange={(list: string[]) => handleMetadataChange(list, 'licenses')}
|
||||
@@ -134,7 +134,7 @@ const MetaData = () => {
|
||||
</Form.Item>
|
||||
<Form.Item<FormData> name={['meta', 'languages']} data-field="metadata">
|
||||
<ListInput
|
||||
label={intl.formatMessage({ id: 'accesses.form.metadata.languages' })}
|
||||
label={intl.formatMessage({ id: 'routes.form.metadata.languages' })}
|
||||
btnText={intl.formatMessage({ id: 'common.button.addLabel' })}
|
||||
dataList={[]}
|
||||
onChange={(list: string[]) => handleMetadataChange(list, 'languages')}
|
||||
@@ -143,7 +143,7 @@ const MetaData = () => {
|
||||
<Form.Item<FormData> name={['meta', 'icon']} data-field="metadata">
|
||||
<IconBox>
|
||||
<span className="icon">
|
||||
{intl.formatMessage({ id: 'accesses.form.metadata.icons' })}
|
||||
{intl.formatMessage({ id: 'routes.form.metadata.icons' })}
|
||||
</span>
|
||||
<UploadWrapper>
|
||||
<UploadImg
|
||||
@@ -161,7 +161,7 @@ const MetaData = () => {
|
||||
) : (
|
||||
<Button size="middle" variant="dashed" color="default">
|
||||
{intl.formatMessage({
|
||||
id: 'accesses.form.metadata.uploadIcon'
|
||||
id: 'routes.form.metadata.uploadIcon'
|
||||
})}
|
||||
</Button>
|
||||
)}
|
||||
+28
-33
@@ -7,7 +7,7 @@ import _ from 'lodash';
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { FormData } from '../config/types';
|
||||
import useEndpointSourceModels from '../hooks/use-endpoint-source-models';
|
||||
import useTargetSourceModels from '../hooks/use-target-source-models';
|
||||
|
||||
const Inner = styled.div`
|
||||
display: flex;
|
||||
@@ -28,12 +28,11 @@ const Inner = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const EndpointsForm = forwardRef((props, ref) => {
|
||||
const TargetsForm = forwardRef((props, ref) => {
|
||||
const intl = useIntl();
|
||||
const { sourceModels, loading, fetchSourceModels } =
|
||||
useEndpointSourceModels();
|
||||
const { sourceModels, loading, fetchSourceModels } = useTargetSourceModels();
|
||||
const form = Form.useFormInstance<FormData>();
|
||||
const endpoints = Form.useWatch('endpoints', form) || [];
|
||||
const targets = Form.useWatch('targets', form) || [];
|
||||
const [fallbackValues, setFallbackValues] = useState<{ value: any[] }>({
|
||||
value: []
|
||||
});
|
||||
@@ -58,20 +57,16 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
}
|
||||
}));
|
||||
|
||||
const handleEndpointsChange = (
|
||||
value: any[],
|
||||
index: number,
|
||||
options: any[]
|
||||
) => {
|
||||
const handleTargetsChange = (value: any[], index: number, options: any[]) => {
|
||||
const selectedOption =
|
||||
options?.find?.((opt) => opt.value === value[1]) || {};
|
||||
const endpointList = [...endpoints];
|
||||
endpointList[index] = {
|
||||
weight: endpointList[index]?.weight || null,
|
||||
const targetList = [...targets];
|
||||
targetList[index] = {
|
||||
weight: targetList[index]?.weight || null,
|
||||
...selectedOption?.data
|
||||
};
|
||||
|
||||
form.setFieldValue('endpoints', [...endpointList]);
|
||||
form.setFieldValue('targets', [...targetList]);
|
||||
|
||||
const newDataList = [...dataList];
|
||||
newDataList[index] = {
|
||||
@@ -96,9 +91,9 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
const newDataList = dataList.filter((_, i) => i !== index);
|
||||
setDataList(newDataList);
|
||||
|
||||
const endpointList = [...endpoints];
|
||||
endpointList.splice(index, 1);
|
||||
form.setFieldValue('endpoints', [...endpointList]);
|
||||
const targetList = [...targets];
|
||||
targetList.splice(index, 1);
|
||||
form.setFieldValue('targets', [...targetList]);
|
||||
};
|
||||
|
||||
const handleFallbackChange = (value: any[], options?: any[]) => {
|
||||
@@ -106,7 +101,7 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
options?.find?.((opt) => opt.value === value[1]) || {};
|
||||
|
||||
console.log('fallback selected option data:', value);
|
||||
form.setFieldValue('fallback_endpoint', {
|
||||
form.setFieldValue('fallback_target', {
|
||||
...selectedOption?.data
|
||||
});
|
||||
setFallbackValues({
|
||||
@@ -115,13 +110,13 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
};
|
||||
|
||||
const handleOnWeightChange = (value: any, index: number) => {
|
||||
const endpointList = [...endpoints];
|
||||
if (endpointList[index]) {
|
||||
endpointList[index] = {
|
||||
...endpointList[index],
|
||||
const targetList = [...targets];
|
||||
if (targetList[index]) {
|
||||
targetList[index] = {
|
||||
...targetList[index],
|
||||
weight: value
|
||||
};
|
||||
form.setFieldValue('endpoints', [...endpointList]);
|
||||
form.setFieldValue('targets', [...targetList]);
|
||||
}
|
||||
|
||||
const newDataList = [...dataList];
|
||||
@@ -139,8 +134,8 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
return (
|
||||
<>
|
||||
<Form.Item
|
||||
name="endpoints"
|
||||
data-field="endpoints"
|
||||
name="targets"
|
||||
data-field="targets"
|
||||
rules={[
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
@@ -173,7 +168,7 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
}
|
||||
}}
|
||||
dataList={dataList}
|
||||
btnText={intl.formatMessage({ id: 'accesses.form.endpoint.add' })}
|
||||
btnText={intl.formatMessage({ id: 'routes.form.target.add' })}
|
||||
onAdd={handleOnAdd}
|
||||
onDelete={handleOnDelete}
|
||||
>
|
||||
@@ -186,7 +181,7 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
multiple={false}
|
||||
alwaysFocus={true}
|
||||
onChange={(value, options) =>
|
||||
handleEndpointsChange(value, index, options)
|
||||
handleTargetsChange(value, index, options)
|
||||
}
|
||||
classNames={{
|
||||
popup: {
|
||||
@@ -195,7 +190,7 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
}}
|
||||
maxTagCount={1}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'providers.form.endpoint.placeholder'
|
||||
id: 'providers.form.target.placeholder'
|
||||
})}
|
||||
value={item.value}
|
||||
options={sourceModels}
|
||||
@@ -209,14 +204,14 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
value={item.weight}
|
||||
onChange={(value) => handleOnWeightChange(value, index)}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'accesses.form.endpoint.weight'
|
||||
id: 'routes.form.target.weight'
|
||||
})}
|
||||
></SealInput.Number>
|
||||
</>
|
||||
)}
|
||||
</MetadataList>
|
||||
</Form.Item>
|
||||
<Form.Item name="fallback_endpoint">
|
||||
<Form.Item name="fallback_target">
|
||||
<div>
|
||||
<SealCascader
|
||||
showSearch
|
||||
@@ -229,10 +224,10 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
}
|
||||
}}
|
||||
label={intl.formatMessage({
|
||||
id: 'accesses.form.endpoint.fallback'
|
||||
id: 'routes.form.target.fallback'
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'providers.form.endpoint.placeholder'
|
||||
id: 'providers.form.target.placeholder'
|
||||
})}
|
||||
maxTagCount={1}
|
||||
value={fallbackValues.value}
|
||||
@@ -247,4 +242,4 @@ const EndpointsForm = forwardRef((props, ref) => {
|
||||
);
|
||||
});
|
||||
|
||||
export default EndpointsForm;
|
||||
export default TargetsForm;
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { PageAction } from '@/config';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { useState } from 'react';
|
||||
import { AccessItem as ListItem } from '../config/types';
|
||||
import { RouteItem as ListItem } from '../config/types';
|
||||
|
||||
const useAccessControl = () => {
|
||||
const [openModalStatus, setOpenModalStatus] = useState<{
|
||||
+7
-7
@@ -1,9 +1,9 @@
|
||||
import { PageAction } from '@/config';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import { useState } from 'react';
|
||||
import { AccessItem as ListItem } from '../config/types';
|
||||
import { RouteItem as ListItem } from '../config/types';
|
||||
|
||||
const useCreateAccess = (options?: { refresh: () => void }) => {
|
||||
const useCreateRoute = (options?: { refresh: () => void }) => {
|
||||
const [openModalStatus, setOpenModalStatus] = useState<{
|
||||
open: boolean;
|
||||
action: PageActionType;
|
||||
@@ -39,11 +39,11 @@ const useCreateAccess = (options?: { refresh: () => void }) => {
|
||||
};
|
||||
|
||||
return {
|
||||
openAccessModalStatus: openModalStatus,
|
||||
setOpenAccessModalStatus: setOpenModalStatus,
|
||||
openAccessModal: openModal,
|
||||
closeAccessModal: closeModal
|
||||
openRouteModalStatus: openModalStatus,
|
||||
setOpenRouteModalStatus: setOpenModalStatus,
|
||||
openRouteModal: openModal,
|
||||
closeRouteModal: closeModal
|
||||
};
|
||||
};
|
||||
|
||||
export default useCreateAccess;
|
||||
export default useCreateRoute;
|
||||
@@ -0,0 +1,37 @@
|
||||
import { queryRouteTargets } from '../apis';
|
||||
import { RouteTarget } from '../config/types';
|
||||
|
||||
const useEditTargets = () => {
|
||||
const generateTargetData = (targetList: RouteTarget[]) => {
|
||||
const fallbackTarget =
|
||||
targetList?.filter(
|
||||
(ep) => ep.fallback_status_codes && ep.fallback_status_codes?.length > 0
|
||||
)?.[0] || null;
|
||||
|
||||
const targets = targetList?.filter(
|
||||
(ep) =>
|
||||
!ep.fallback_status_codes || ep.fallback_status_codes?.length === 0
|
||||
);
|
||||
|
||||
return {
|
||||
targets: targets,
|
||||
fallbackTarget: fallbackTarget
|
||||
};
|
||||
};
|
||||
|
||||
const fetchTargets = async (accessId: number) => {
|
||||
try {
|
||||
const res = await queryRouteTargets({ id: accessId });
|
||||
return res.items || [];
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
generateTargetData,
|
||||
fetchTargets
|
||||
};
|
||||
};
|
||||
|
||||
export default useEditTargets;
|
||||
+9
-9
@@ -8,11 +8,11 @@ import { useIntl } from '@umijs/max';
|
||||
import dayjs from 'dayjs';
|
||||
import { useMemo } from 'react';
|
||||
import { rowActionList } from '../config';
|
||||
import { AccessItem } from '../config/types';
|
||||
import { RouteItem } from '../config/types';
|
||||
|
||||
const useAccessColumns = (
|
||||
handleSelect: (val: string, record: AccessItem) => void,
|
||||
onCellClick?: (record: AccessItem, dataIndex: string) => void
|
||||
handleSelect: (val: string, record: RouteItem) => void,
|
||||
onCellClick?: (record: RouteItem, dataIndex: string) => void
|
||||
): SealColumnProps[] => {
|
||||
const intl = useIntl();
|
||||
|
||||
@@ -23,7 +23,7 @@ const useAccessColumns = (
|
||||
dataIndex: 'name',
|
||||
sorter: tableSorter(1),
|
||||
span: 5,
|
||||
render: (text: string, record: AccessItem) => (
|
||||
render: (text: string, record: RouteItem) => (
|
||||
<span className="flex-center" style={{ maxWidth: '100%' }}>
|
||||
<AutoTooltip ghost title={text}>
|
||||
<span className="m-r-5">{text}</span>
|
||||
@@ -33,12 +33,12 @@ const useAccessColumns = (
|
||||
)
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: 'accesses.table.accessPoints' }),
|
||||
dataIndex: 'endpoints',
|
||||
title: intl.formatMessage({ id: 'routes.table.routeTargets' }),
|
||||
dataIndex: 'targets',
|
||||
span: 10,
|
||||
render: (value: number, record: AccessItem) => (
|
||||
render: (value: number, record: RouteItem) => (
|
||||
<span>
|
||||
{record.ready_endpoints} / {value}
|
||||
{record.ready_targets} / {value}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
@@ -57,7 +57,7 @@ const useAccessColumns = (
|
||||
title: intl.formatMessage({ id: 'common.table.operation' }),
|
||||
dataIndex: 'operations',
|
||||
span: 4,
|
||||
render: (value: string, record: AccessItem) => (
|
||||
render: (value: string, record: RouteItem) => (
|
||||
<DropdownButtons
|
||||
items={rowActionList}
|
||||
onSelect={(val) => handleSelect(val, record)}
|
||||
+2
-2
@@ -15,7 +15,7 @@ type CascaderOption<T extends object = EmptyObject> = {
|
||||
children?: CascaderOption<T>[];
|
||||
} & Partial<T>;
|
||||
|
||||
const useEndpointSourceModels = () => {
|
||||
const useTargetSourceModels = () => {
|
||||
const intl = useIntl();
|
||||
const [sourceModels, setSourceModels] = useState<CascaderOption[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
@@ -88,4 +88,4 @@ const useEndpointSourceModels = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export default useEndpointSourceModels;
|
||||
export default useTargetSourceModels;
|
||||
@@ -20,23 +20,23 @@ import NoResult from '../_components/no-result';
|
||||
import PageBox from '../_components/page-box';
|
||||
import AccessControlModal from '../llmodels/components/access-control-modal';
|
||||
import {
|
||||
ACCESS_API,
|
||||
ACCESS_POINTS_API,
|
||||
createAccess,
|
||||
deleteAccess,
|
||||
deleteAccessPoint,
|
||||
queryAccessPoints,
|
||||
queryModelAccesses,
|
||||
setAccessPointAsFallback,
|
||||
updateAccess
|
||||
MODEL_ROUTES,
|
||||
MODEL_ROUTE_TARGETS,
|
||||
createModelRoute,
|
||||
deleteModelRoute,
|
||||
deleteModelRouteTarget,
|
||||
queryModelRoutes,
|
||||
queryRouteTargets,
|
||||
setRouteTargetAsFallback,
|
||||
updateModelRoute
|
||||
} from './apis';
|
||||
import AccessPoints from './components/access-points';
|
||||
import AddAccessModal from './components/add-access-modal';
|
||||
import { FormData, AccessItem as ListItem } from './config/types';
|
||||
import useAccessColumns from './hooks/use-access-columns';
|
||||
import AddRouteModal from './components/add-route-modal';
|
||||
import RouteTargets from './components/route-targets';
|
||||
import { FormData, RouteItem as ListItem } from './config/types';
|
||||
import useAccessControl from './hooks/use-access-control';
|
||||
import useCreateAccess from './hooks/use-create-access';
|
||||
import useEndpointSourceModels from './hooks/use-endpoint-source-models';
|
||||
import useCreateRoute from './hooks/use-create-route';
|
||||
import useRoutesColumns from './hooks/use-routes-columns';
|
||||
import useTargetSourceModels from './hooks/use-target-source-models';
|
||||
|
||||
const Accesses: React.FC = () => {
|
||||
const {
|
||||
@@ -52,31 +52,31 @@ const Accesses: React.FC = () => {
|
||||
handleSearch,
|
||||
handleNameChange
|
||||
} = useTableFetch<ListItem>({
|
||||
fetchAPI: queryModelAccesses,
|
||||
deleteAPI: deleteAccess,
|
||||
fetchAPI: queryModelRoutes,
|
||||
deleteAPI: deleteModelRoute,
|
||||
watch: true,
|
||||
API: ACCESS_API,
|
||||
contentForDelete: 'menu.models.access'
|
||||
API: MODEL_ROUTES,
|
||||
contentForDelete: 'menu.models.routes'
|
||||
});
|
||||
const { watchDataList: allAccessPoints, deleteItemFromCache } =
|
||||
useWatchList(ACCESS_POINTS_API);
|
||||
const { watchDataList: allRouteTargets, deleteItemFromCache } =
|
||||
useWatchList(MODEL_ROUTE_TARGETS);
|
||||
const [expandAtom] = useAtom(expandKeysAtom);
|
||||
const { handleExpandChange, handleExpandAll, expandedRowKeys } =
|
||||
useExpandedRowKeys(expandAtom);
|
||||
const intl = useIntl();
|
||||
const { openAccessModalStatus, openAccessModal, closeAccessModal } =
|
||||
useCreateAccess();
|
||||
const { openRouteModalStatus, openRouteModal, closeRouteModal } =
|
||||
useCreateRoute();
|
||||
const {
|
||||
openAccessControlModal,
|
||||
closeAccessControlModal,
|
||||
openAccessControlModalStatus
|
||||
} = useAccessControl();
|
||||
const { sourceModels, fetchSourceModels } = useEndpointSourceModels();
|
||||
const { sourceModels, fetchSourceModels } = useTargetSourceModels();
|
||||
|
||||
const handleClickDropdown = () => {
|
||||
openAccessModal(
|
||||
openRouteModal(
|
||||
PageAction.CREATE,
|
||||
intl.formatMessage({ id: 'accesses.button.add' })
|
||||
intl.formatMessage({ id: 'routes.button.add' })
|
||||
);
|
||||
};
|
||||
|
||||
@@ -85,30 +85,30 @@ const Accesses: React.FC = () => {
|
||||
...data
|
||||
};
|
||||
try {
|
||||
if (openAccessModalStatus.action === PageAction.EDIT) {
|
||||
await updateAccess({
|
||||
if (openRouteModalStatus.action === PageAction.EDIT) {
|
||||
await updateModelRoute({
|
||||
data: params,
|
||||
id: openAccessModalStatus.currentData!.id
|
||||
id: openRouteModalStatus.currentData!.id
|
||||
});
|
||||
}
|
||||
if (openAccessModalStatus.action === PageAction.CREATE) {
|
||||
await createAccess({
|
||||
if (openRouteModalStatus.action === PageAction.CREATE) {
|
||||
await createModelRoute({
|
||||
data: params
|
||||
});
|
||||
}
|
||||
fetchData();
|
||||
closeAccessModal();
|
||||
closeRouteModal();
|
||||
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
const handleModalCancel = () => {
|
||||
console.log('handleModalCancel');
|
||||
closeAccessModal();
|
||||
closeRouteModal();
|
||||
};
|
||||
|
||||
const handleEditProvider = (row: ListItem) => {
|
||||
openAccessModal(
|
||||
openRouteModal(
|
||||
PageAction.EDIT,
|
||||
intl.formatMessage({ id: 'common.button.edit.item' }, { name: row.name }),
|
||||
row
|
||||
@@ -146,7 +146,7 @@ const Accesses: React.FC = () => {
|
||||
const params = {
|
||||
id: row.id
|
||||
};
|
||||
const res = await queryAccessPoints(params, {
|
||||
const res = await queryRouteTargets(params, {
|
||||
token: options?.token
|
||||
});
|
||||
|
||||
@@ -158,14 +158,14 @@ const Accesses: React.FC = () => {
|
||||
handleTableChange({}, {}, order, { action: 'sort' });
|
||||
};
|
||||
|
||||
const handleDeleteEndpoint = (row: any) => {
|
||||
const handleDeleteTarget = (row: any) => {
|
||||
modalRef.current?.show({
|
||||
content: 'accesses.table.accessPoints',
|
||||
content: 'routes.table.routeTargets',
|
||||
okText: 'common.button.delete',
|
||||
operation: 'common.delete.single.confirm',
|
||||
name: row.name,
|
||||
async onOk() {
|
||||
await deleteAccessPoint(row.id);
|
||||
await deleteModelRouteTarget(row.id);
|
||||
deleteItemFromCache?.(row.id);
|
||||
}
|
||||
});
|
||||
@@ -174,7 +174,7 @@ const Accesses: React.FC = () => {
|
||||
const onChildSelect = useMemoizedFn(async (val: any, record: any) => {
|
||||
try {
|
||||
if (val === 'fallback') {
|
||||
await setAccessPointAsFallback({
|
||||
await setRouteTargetAsFallback({
|
||||
id: record.id,
|
||||
data: {
|
||||
fallback_status_codes: ['4xx', '5xx']
|
||||
@@ -182,7 +182,7 @@ const Accesses: React.FC = () => {
|
||||
});
|
||||
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||
} else if (val === 'delete') {
|
||||
handleDeleteEndpoint(record);
|
||||
handleDeleteTarget(record);
|
||||
}
|
||||
} catch (error) {}
|
||||
});
|
||||
@@ -192,7 +192,7 @@ const Accesses: React.FC = () => {
|
||||
options: { parent?: any; [key: string]: any }
|
||||
) => {
|
||||
return (
|
||||
<AccessPoints
|
||||
<RouteTargets
|
||||
dataList={list}
|
||||
onSelect={onChildSelect}
|
||||
sourceModels={sourceModels}
|
||||
@@ -201,14 +201,14 @@ const Accesses: React.FC = () => {
|
||||
};
|
||||
|
||||
const setDisableExpand = (record: any) => {
|
||||
return !record?.endpoints;
|
||||
return !record?.targets;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchSourceModels();
|
||||
}, []);
|
||||
|
||||
const columns = useAccessColumns(handleSelect);
|
||||
const columns = useRoutesColumns(handleSelect);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -218,7 +218,7 @@ const Accesses: React.FC = () => {
|
||||
marginBottom={22}
|
||||
marginTop={30}
|
||||
widths={{ input: 300 }}
|
||||
buttonText={intl.formatMessage({ id: 'accesses.button.add' })}
|
||||
buttonText={intl.formatMessage({ id: 'routes.button.add' })}
|
||||
rowSelection={rowSelection}
|
||||
handleInputChange={handleNameChange}
|
||||
handleSearch={handleSearch}
|
||||
@@ -227,7 +227,7 @@ const Accesses: React.FC = () => {
|
||||
></FilterBar>
|
||||
<TableContext.Provider
|
||||
value={{
|
||||
allChildren: allAccessPoints,
|
||||
allChildren: allRouteTargets,
|
||||
setDisableExpand: setDisableExpand
|
||||
}}
|
||||
>
|
||||
@@ -277,14 +277,14 @@ const Accesses: React.FC = () => {
|
||||
></SealTable>
|
||||
</TableContext.Provider>
|
||||
</PageBox>
|
||||
<AddAccessModal
|
||||
open={openAccessModalStatus.open}
|
||||
action={openAccessModalStatus.action}
|
||||
title={openAccessModalStatus.title}
|
||||
currentData={openAccessModalStatus.currentData}
|
||||
<AddRouteModal
|
||||
open={openRouteModalStatus.open}
|
||||
action={openRouteModalStatus.action}
|
||||
title={openRouteModalStatus.title}
|
||||
currentData={openRouteModalStatus.currentData}
|
||||
onCancel={handleModalCancel}
|
||||
onOk={handleModalOk}
|
||||
></AddAccessModal>
|
||||
></AddRouteModal>
|
||||
<AccessControlModal
|
||||
onCancel={closeAccessControlModal}
|
||||
title={openAccessControlModalStatus.title}
|
||||
Reference in New Issue
Block a user