feat: localize operations catalog
This commit is contained in:
@@ -21,6 +21,30 @@ var TRANSLATIONS = {
|
||||
'ops.loading': 'Loading operations…',
|
||||
'ops.empty.title': 'No operations found',
|
||||
'ops.empty.sub': 'Try adjusting your search or filters.',
|
||||
'ops.empty.initial.title': 'No operations yet',
|
||||
'ops.empty.initial.sub': 'Create the first operation in this workspace to expose a live MCP tool.',
|
||||
'ops.error.title': 'Backend connection failed',
|
||||
'ops.delete.confirm': 'Delete this operation? This cannot be undone.',
|
||||
'ops.delete.success.title': 'Operation deleted',
|
||||
'ops.delete.success.message': '{name} was deleted.',
|
||||
'ops.delete.error.title': 'Delete failed',
|
||||
'ops.delete.error.message': 'Failed to delete operation',
|
||||
'ops.action.edit': 'Edit operation',
|
||||
'ops.action.delete':'Delete operation',
|
||||
'ops.stats.synced': 'Catalog synced with backend',
|
||||
'ops.stats.none': 'No operations yet',
|
||||
'ops.stats.share': '{value}% of total',
|
||||
'ops.stats.no_published': 'No published tools yet',
|
||||
'ops.stats.requests_rollup': 'Summed from operation usage',
|
||||
'ops.stats.no_traffic': 'No traffic recorded today',
|
||||
'ops.stats.latency_weighted': "Weighted by today's calls",
|
||||
'ops.stats.latency_waiting': 'Waiting for runtime samples',
|
||||
'ops.results': 'Showing {shown} of {total}',
|
||||
'ops.range': 'Showing {from}–{to} of {total} operations',
|
||||
'ops.filter.protocol': 'Protocol: {value}',
|
||||
'ops.filter.category': 'Category: {value}',
|
||||
'ops.filter.agent': 'Agent: {value}',
|
||||
'ops.no_active_agents': 'No active agents',
|
||||
|
||||
// Stats
|
||||
'stats.total': 'Total operations',
|
||||
@@ -40,9 +64,12 @@ var TRANSLATIONS = {
|
||||
'filter.protocol': 'Protocol',
|
||||
'filter.status': 'Status',
|
||||
'filter.category': 'Category',
|
||||
'filter.agent': 'Agent',
|
||||
'filter.showing': 'Showing',
|
||||
'filter.of': 'of',
|
||||
'filter.clear': 'Clear filter',
|
||||
'filter.clear_all': 'Clear all',
|
||||
'filter.remove': 'Remove filter',
|
||||
'sort.created_desc':'Sort: Last created',
|
||||
'sort.created_asc': 'Sort: Oldest first',
|
||||
'sort.name_asc': 'Sort: Name A–Z',
|
||||
@@ -147,6 +174,30 @@ var TRANSLATIONS = {
|
||||
'ops.loading': 'Загрузка операций…',
|
||||
'ops.empty.title': 'Операции не найдены',
|
||||
'ops.empty.sub': 'Попробуйте изменить поисковый запрос или фильтры.',
|
||||
'ops.empty.initial.title': 'Операций пока нет',
|
||||
'ops.empty.initial.sub': 'Создайте первую операцию в этом воркспейсе, чтобы открыть живой MCP-инструмент.',
|
||||
'ops.error.title': 'Не удалось подключиться к backend',
|
||||
'ops.delete.confirm': 'Удалить эту операцию? Действие нельзя отменить.',
|
||||
'ops.delete.success.title': 'Операция удалена',
|
||||
'ops.delete.success.message': 'Операция {name} удалена.',
|
||||
'ops.delete.error.title': 'Не удалось удалить',
|
||||
'ops.delete.error.message': 'Не удалось удалить операцию',
|
||||
'ops.action.edit': 'Редактировать операцию',
|
||||
'ops.action.delete':'Удалить операцию',
|
||||
'ops.stats.synced': 'Каталог синхронизирован с backend',
|
||||
'ops.stats.none': 'Операций пока нет',
|
||||
'ops.stats.share': '{value}% от общего числа',
|
||||
'ops.stats.no_published': 'Опубликованных инструментов пока нет',
|
||||
'ops.stats.requests_rollup': 'Сумма по статистике операций',
|
||||
'ops.stats.no_traffic': 'Трафик сегодня не зафиксирован',
|
||||
'ops.stats.latency_weighted': 'Взвешено по сегодняшним вызовам',
|
||||
'ops.stats.latency_waiting': 'Ожидание runtime-метрик',
|
||||
'ops.results': 'Показано {shown} из {total}',
|
||||
'ops.range': 'Показано {from}–{to} из {total} операций',
|
||||
'ops.filter.protocol': 'Протокол: {value}',
|
||||
'ops.filter.category': 'Категория: {value}',
|
||||
'ops.filter.agent': 'Агент: {value}',
|
||||
'ops.no_active_agents': 'Нет активных агентов',
|
||||
|
||||
// Stats
|
||||
'stats.total': 'Всего операций',
|
||||
@@ -166,9 +217,12 @@ var TRANSLATIONS = {
|
||||
'filter.protocol': 'Протокол',
|
||||
'filter.status': 'Статус',
|
||||
'filter.category': 'Категория',
|
||||
'filter.agent': 'Агент',
|
||||
'filter.showing': 'Показано',
|
||||
'filter.of': 'из',
|
||||
'filter.clear': 'Сбросить',
|
||||
'filter.clear_all': 'Сбросить все',
|
||||
'filter.remove': 'Убрать фильтр',
|
||||
'sort.created_desc':'Сначала новые',
|
||||
'sort.created_asc': 'Сначала старые',
|
||||
'sort.name_asc': 'Название А–Я',
|
||||
@@ -263,6 +317,12 @@ function t(key) {
|
||||
return tr[key] !== undefined ? tr[key] : (TRANSLATIONS.en[key] !== undefined ? TRANSLATIONS.en[key] : key);
|
||||
}
|
||||
|
||||
function tf(key, vars) {
|
||||
return Object.keys(vars || {}).reduce(function(result, name) {
|
||||
return result.replaceAll('{' + name + '}', vars[name]);
|
||||
}, t(key));
|
||||
}
|
||||
|
||||
function applyLang() {
|
||||
// text content
|
||||
document.querySelectorAll('[data-i18n]').forEach(function(el) {
|
||||
@@ -272,6 +332,10 @@ function applyLang() {
|
||||
document.querySelectorAll('[data-i18n-ph]').forEach(function(el) {
|
||||
el.placeholder = t(el.getAttribute('data-i18n-ph'));
|
||||
});
|
||||
// title
|
||||
document.querySelectorAll('[data-i18n-title]').forEach(function(el) {
|
||||
el.title = t(el.getAttribute('data-i18n-title'));
|
||||
});
|
||||
// highlight active language button in settings
|
||||
var lang = localStorage.getItem('crank_lang') || 'en';
|
||||
document.querySelectorAll('.lang-btn').forEach(function(btn) {
|
||||
|
||||
Reference in New Issue
Block a user