mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-19 03:00:49 +08:00
feat: add model search functionality with UI components and internationalization support
This commit is contained in:
6
i18n.js
6
i18n.js
@@ -224,6 +224,9 @@ const i18n = {
|
|||||||
'ai_providers.openai_models_fetch_error': '获取模型失败',
|
'ai_providers.openai_models_fetch_error': '获取模型失败',
|
||||||
'ai_providers.openai_models_fetch_back': '返回编辑',
|
'ai_providers.openai_models_fetch_back': '返回编辑',
|
||||||
'ai_providers.openai_models_fetch_apply': '添加所选模型',
|
'ai_providers.openai_models_fetch_apply': '添加所选模型',
|
||||||
|
'ai_providers.openai_models_search_label': '搜索模型',
|
||||||
|
'ai_providers.openai_models_search_placeholder': '按名称、别名或描述筛选',
|
||||||
|
'ai_providers.openai_models_search_empty': '没有匹配的模型,请更换关键字试试。',
|
||||||
'ai_providers.openai_models_fetch_invalid_url': '请先填写有效的 Base URL',
|
'ai_providers.openai_models_fetch_invalid_url': '请先填写有效的 Base URL',
|
||||||
'ai_providers.openai_models_fetch_added': '已添加 {count} 个新模型',
|
'ai_providers.openai_models_fetch_added': '已添加 {count} 个新模型',
|
||||||
'ai_providers.openai_edit_modal_title': '编辑OpenAI兼容提供商',
|
'ai_providers.openai_edit_modal_title': '编辑OpenAI兼容提供商',
|
||||||
@@ -843,6 +846,9 @@ const i18n = {
|
|||||||
'ai_providers.openai_models_fetch_error': 'Failed to fetch models',
|
'ai_providers.openai_models_fetch_error': 'Failed to fetch models',
|
||||||
'ai_providers.openai_models_fetch_back': 'Back to edit',
|
'ai_providers.openai_models_fetch_back': 'Back to edit',
|
||||||
'ai_providers.openai_models_fetch_apply': 'Add selected models',
|
'ai_providers.openai_models_fetch_apply': 'Add selected models',
|
||||||
|
'ai_providers.openai_models_search_label': 'Search models',
|
||||||
|
'ai_providers.openai_models_search_placeholder': 'Filter by name, alias, or description',
|
||||||
|
'ai_providers.openai_models_search_empty': 'No models match your search. Try a different keyword.',
|
||||||
'ai_providers.openai_models_fetch_invalid_url': 'Please enter a valid Base URL first',
|
'ai_providers.openai_models_fetch_invalid_url': 'Please enter a valid Base URL first',
|
||||||
'ai_providers.openai_models_fetch_added': '{count} new models added',
|
'ai_providers.openai_models_fetch_added': '{count} new models added',
|
||||||
'ai_providers.openai_edit_modal_title': 'Edit OpenAI Compatible Provider',
|
'ai_providers.openai_edit_modal_title': 'Edit OpenAI Compatible Provider',
|
||||||
|
|||||||
@@ -1152,6 +1152,10 @@ function ensureOpenAIModelDiscoveryCard(manager) {
|
|||||||
<button type="button" class="btn btn-secondary" id="openai-model-discovery-refresh">${i18n.t('ai_providers.openai_models_fetch_refresh')}</button>
|
<button type="button" class="btn btn-secondary" id="openai-model-discovery-refresh">${i18n.t('ai_providers.openai_models_fetch_refresh')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="openai-model-discovery-search">${i18n.t('ai_providers.openai_models_search_label')}</label>
|
||||||
|
<input type="text" id="openai-model-discovery-search" placeholder="${i18n.t('ai_providers.openai_models_search_placeholder')}">
|
||||||
|
</div>
|
||||||
<div id="openai-model-discovery-status" class="model-discovery-status"></div>
|
<div id="openai-model-discovery-status" class="model-discovery-status"></div>
|
||||||
<div id="openai-model-discovery-list" class="model-discovery-list"></div>
|
<div id="openai-model-discovery-list" class="model-discovery-list"></div>
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
@@ -1174,6 +1178,13 @@ function ensureOpenAIModelDiscoveryCard(manager) {
|
|||||||
bind('openai-model-discovery-cancel', () => manager.closeOpenAIModelDiscovery());
|
bind('openai-model-discovery-cancel', () => manager.closeOpenAIModelDiscovery());
|
||||||
bind('openai-model-discovery-refresh', () => manager.refreshOpenAIModelDiscovery());
|
bind('openai-model-discovery-refresh', () => manager.refreshOpenAIModelDiscovery());
|
||||||
bind('openai-model-discovery-apply', () => manager.applyOpenAIModelDiscoverySelection());
|
bind('openai-model-discovery-apply', () => manager.applyOpenAIModelDiscoverySelection());
|
||||||
|
const searchInput = document.getElementById('openai-model-discovery-search');
|
||||||
|
if (searchInput) {
|
||||||
|
searchInput.addEventListener('input', (event) => {
|
||||||
|
const query = event?.target?.value || '';
|
||||||
|
manager.setOpenAIModelDiscoverySearch(query);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return overlay;
|
return overlay;
|
||||||
}
|
}
|
||||||
@@ -1185,10 +1196,30 @@ export function setOpenAIModelDiscoveryStatus(message = '', type = 'info') {
|
|||||||
status.className = `model-discovery-status ${type}`;
|
status.className = `model-discovery-status ${type}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setOpenAIModelDiscoverySearch(query = '') {
|
||||||
|
if (!this.openAIModelDiscoveryContext) return;
|
||||||
|
const normalized = (query || '').trim();
|
||||||
|
this.openAIModelDiscoveryContext.modelSearchQuery = normalized;
|
||||||
|
const models = this.openAIModelDiscoveryContext.discoveredModels || [];
|
||||||
|
this.renderOpenAIModelDiscoveryList(models);
|
||||||
|
}
|
||||||
|
|
||||||
export function renderOpenAIModelDiscoveryList(models = []) {
|
export function renderOpenAIModelDiscoveryList(models = []) {
|
||||||
const list = document.getElementById('openai-model-discovery-list');
|
const list = document.getElementById('openai-model-discovery-list');
|
||||||
if (!list) return;
|
if (!list) return;
|
||||||
|
|
||||||
|
const context = this.openAIModelDiscoveryContext || {};
|
||||||
|
const filter = (context.modelSearchQuery || '').trim().toLowerCase();
|
||||||
|
const filtered = models
|
||||||
|
.map((model, index) => ({ model, index }))
|
||||||
|
.filter(({ model }) => {
|
||||||
|
if (!filter) return true;
|
||||||
|
const name = (model?.name || '').toLowerCase();
|
||||||
|
const alias = (model?.alias || '').toLowerCase();
|
||||||
|
const desc = (model?.description || '').toLowerCase();
|
||||||
|
return name.includes(filter) || alias.includes(filter) || desc.includes(filter);
|
||||||
|
});
|
||||||
|
|
||||||
if (!models.length) {
|
if (!models.length) {
|
||||||
list.innerHTML = `
|
list.innerHTML = `
|
||||||
<div class="model-discovery-empty">
|
<div class="model-discovery-empty">
|
||||||
@@ -1199,10 +1230,20 @@ export function renderOpenAIModelDiscoveryList(models = []) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list.innerHTML = models.map((model, index) => {
|
if (!filtered.length) {
|
||||||
const name = this.escapeHtml(model.name || '');
|
list.innerHTML = `
|
||||||
const alias = model.alias ? `<span class="model-discovery-alias">${this.escapeHtml(model.alias)}</span>` : '';
|
<div class="model-discovery-empty">
|
||||||
const desc = model.description ? `<div class="model-discovery-desc">${this.escapeHtml(model.description)}</div>` : '';
|
<i class="fas fa-search"></i>
|
||||||
|
<span>${i18n.t('ai_providers.openai_models_search_empty')}</span>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.innerHTML = filtered.map(({ model, index }) => {
|
||||||
|
const name = this.escapeHtml(model?.name || '');
|
||||||
|
const alias = model?.alias ? `<span class="model-discovery-alias">${this.escapeHtml(model.alias)}</span>` : '';
|
||||||
|
const desc = model?.description ? `<div class="model-discovery-desc">${this.escapeHtml(model.description)}</div>` : '';
|
||||||
return `
|
return `
|
||||||
<label class="model-discovery-row">
|
<label class="model-discovery-row">
|
||||||
<input type="checkbox" class="model-discovery-checkbox" data-model-index="${index}">
|
<input type="checkbox" class="model-discovery-checkbox" data-model-index="${index}">
|
||||||
@@ -1244,13 +1285,18 @@ export function openOpenAIModelDiscovery(mode = 'new') {
|
|||||||
...context,
|
...context,
|
||||||
endpoint,
|
endpoint,
|
||||||
headers,
|
headers,
|
||||||
discoveredModels: []
|
discoveredModels: [],
|
||||||
|
modelSearchQuery: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
const urlInput = document.getElementById('openai-model-discovery-url');
|
const urlInput = document.getElementById('openai-model-discovery-url');
|
||||||
if (urlInput) {
|
if (urlInput) {
|
||||||
urlInput.value = endpoint;
|
urlInput.value = endpoint;
|
||||||
}
|
}
|
||||||
|
const searchInput = document.getElementById('openai-model-discovery-search');
|
||||||
|
if (searchInput) {
|
||||||
|
searchInput.value = '';
|
||||||
|
}
|
||||||
|
|
||||||
this.renderOpenAIModelDiscoveryList([]);
|
this.renderOpenAIModelDiscoveryList([]);
|
||||||
this.setOpenAIModelDiscoveryStatus(i18n.t('ai_providers.openai_models_fetch_loading'), 'info');
|
this.setOpenAIModelDiscoveryStatus(i18n.t('ai_providers.openai_models_fetch_loading'), 'info');
|
||||||
@@ -1688,6 +1734,7 @@ export const aiProvidersModule = {
|
|||||||
refreshOpenAIModelDiscovery,
|
refreshOpenAIModelDiscovery,
|
||||||
renderOpenAIModelDiscoveryList,
|
renderOpenAIModelDiscoveryList,
|
||||||
setOpenAIModelDiscoveryStatus,
|
setOpenAIModelDiscoveryStatus,
|
||||||
|
setOpenAIModelDiscoverySearch,
|
||||||
applyOpenAIModelDiscoverySelection,
|
applyOpenAIModelDiscoverySelection,
|
||||||
closeOpenAIModelDiscovery,
|
closeOpenAIModelDiscovery,
|
||||||
addModelField,
|
addModelField,
|
||||||
|
|||||||
Reference in New Issue
Block a user