наблюдаемость: завершить базовый контур Community
Добавить структурированные журналы, метрики, трассировку и безопасный канал критических ошибок. Усилить границы рантайма, тесты, проверку зависимостей и сценарии развёртывания.
This commit is contained in:
@@ -97,8 +97,8 @@
|
||||
</div>
|
||||
<div class="danger-zone-action">
|
||||
<div class="danger-zone-text">
|
||||
<div class="danger-zone-title" data-i18n="workspace_setup.danger.export_title">Export all data</div>
|
||||
<div class="danger-zone-desc" data-i18n="workspace_setup.danger.export_body">Download a JSON snapshot of workspace settings, operations, agents, secrets, usage data and agent access keys.</div>
|
||||
<div class="danger-zone-title" data-i18n="workspace_setup.danger.export_title">Export workspace catalog</div>
|
||||
<div class="danger-zone-desc" data-i18n="workspace_setup.danger.export_body">Download a non-restorable JSON catalog of workspace settings, operation summaries, agent summaries and API key metadata.</div>
|
||||
</div>
|
||||
<button class="btn-danger" id="export-workspace-btn" type="button" data-i18n="workspace_setup.export">Export</button>
|
||||
</div>
|
||||
|
||||
+4
-4
@@ -442,8 +442,8 @@ var TRANSLATIONS = {
|
||||
'workspace_setup.create.subtitle': 'This Community installation uses one workspace for MCP operations and agents.',
|
||||
'workspace_setup.create.footer': 'This Community installation uses one workspace.',
|
||||
'workspace_setup.danger.title': 'Danger zone',
|
||||
'workspace_setup.danger.export_title': 'Export all data',
|
||||
'workspace_setup.danger.export_body': 'Download a JSON snapshot of workspace settings, operations, agents, secrets, usage data and agent access keys.',
|
||||
'workspace_setup.danger.export_title': 'Export workspace catalog',
|
||||
'workspace_setup.danger.export_body': 'Download a non-restorable JSON catalog of workspace settings, operation summaries, agent summaries and API key metadata.',
|
||||
'workspace_setup.export': 'Export',
|
||||
'workspace_setup.role.owner': 'Owner',
|
||||
'workspace_setup.role.admin': 'Admin',
|
||||
@@ -1334,8 +1334,8 @@ var TRANSLATIONS = {
|
||||
'workspace_setup.create.subtitle': 'В Community используется один воркспейс для MCP-операций и агентов.',
|
||||
'workspace_setup.create.footer': 'В Community используется один воркспейс.',
|
||||
'workspace_setup.danger.title': 'Опасная зона',
|
||||
'workspace_setup.danger.export_title': 'Экспортировать все данные',
|
||||
'workspace_setup.danger.export_body': 'Скачать JSON-снимок настроек воркспейса, операций, агентов, секретов, данных использования и ключей доступа агентов.',
|
||||
'workspace_setup.danger.export_title': 'Экспорт каталога рабочего пространства',
|
||||
'workspace_setup.danger.export_body': 'Скачать невосстанавливаемый JSON-каталог настроек рабочего пространства, сводок операций и агентов, а также метаданных ключей API.',
|
||||
'workspace_setup.export': 'Экспорт',
|
||||
'workspace_setup.role.owner': 'Владелец',
|
||||
'workspace_setup.role.admin': 'Администратор',
|
||||
|
||||
+40
-4
@@ -8,6 +8,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
openId: null,
|
||||
liveMode: true,
|
||||
timer: null,
|
||||
searchTimer: null,
|
||||
refreshPromise: null,
|
||||
workspaceId: null,
|
||||
loading: false,
|
||||
loadError: '',
|
||||
@@ -457,7 +459,13 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
|
||||
async function refreshOperationalData() {
|
||||
await Promise.all([loadLogs(), loadApprovals()]);
|
||||
if (state.refreshPromise) {
|
||||
return state.refreshPromise;
|
||||
}
|
||||
state.refreshPromise = Promise.all([loadLogs(), loadApprovals()]).finally(function () {
|
||||
state.refreshPromise = null;
|
||||
});
|
||||
return state.refreshPromise;
|
||||
}
|
||||
|
||||
async function loadLogDetail(logId) {
|
||||
@@ -494,10 +502,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
function startPolling() {
|
||||
stopPolling();
|
||||
if (!state.liveMode) {
|
||||
if (!state.liveMode || document.hidden) {
|
||||
return;
|
||||
}
|
||||
state.timer = setInterval(refreshOperationalData, 4000);
|
||||
state.timer = setTimeout(async function poll() {
|
||||
state.timer = null;
|
||||
await refreshOperationalData();
|
||||
startPolling();
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
function toggleLive() {
|
||||
@@ -526,7 +538,13 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
if (logSearch) {
|
||||
logSearch.addEventListener('input', function () {
|
||||
state.search = this.value.trim();
|
||||
loadLogs();
|
||||
if (state.searchTimer) {
|
||||
clearTimeout(state.searchTimer);
|
||||
}
|
||||
state.searchTimer = setTimeout(function () {
|
||||
state.searchTimer = null;
|
||||
loadLogs();
|
||||
}, 250);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -572,6 +590,24 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
refreshOperationalData();
|
||||
});
|
||||
|
||||
document.addEventListener('visibilitychange', function () {
|
||||
if (document.hidden) {
|
||||
stopPolling();
|
||||
return;
|
||||
}
|
||||
if (state.liveMode) {
|
||||
refreshOperationalData().finally(startPolling);
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('pagehide', function () {
|
||||
stopPolling();
|
||||
if (state.searchTimer) {
|
||||
clearTimeout(state.searchTimer);
|
||||
state.searchTimer = null;
|
||||
}
|
||||
});
|
||||
|
||||
setLiveState();
|
||||
startPolling();
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ async function exportWorkspaceSnapshot() {
|
||||
var slug = workspaceFormState.workspaceRecord && workspaceFormState.workspaceRecord.workspace
|
||||
? workspaceFormState.workspaceRecord.workspace.slug
|
||||
: tKey('settings.nav.workspace');
|
||||
downloadJsonFile(slug + '-snapshot.json', snapshot);
|
||||
downloadJsonFile(slug + '-catalog-snapshot.json', snapshot);
|
||||
} catch (error) {
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.error(error.message || tKey('workspace_setup.export_error'), tKey('workspace_setup.export_error_title'));
|
||||
|
||||
Generated
+4
-4
@@ -9,7 +9,7 @@
|
||||
"@fontsource/inter": "5.2.8",
|
||||
"@fontsource/jetbrains-mono": "5.2.8",
|
||||
"alpinejs": "3.15.12",
|
||||
"js-yaml": "5.2.1"
|
||||
"js-yaml": "5.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.61.1",
|
||||
@@ -580,9 +580,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.1.tgz",
|
||||
"integrity": "sha512-zfLtNfQqxVqq3uaTqSkh4x4hZw3KHobGUA0fJUj4wawW8bsQLTVqpHdXSIzidh7o+4lEW36tANuAGdaFx6Zgnw==",
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.2.tgz",
|
||||
"integrity": "sha512-dayzUzKkJ1MkuUtZglSebU43utNXH0OWQByK9rKOOuYIO8M5TV1y+n8ALMdG0rdzBnfNkOmZEqrURepb0ejqBw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"@fontsource/inter": "5.2.8",
|
||||
"@fontsource/jetbrains-mono": "5.2.8",
|
||||
"alpinejs": "3.15.12",
|
||||
"js-yaml": "5.2.1"
|
||||
"js-yaml": "5.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.61.1",
|
||||
|
||||
@@ -161,15 +161,15 @@ test('wizard builds visual request mappings from JSON sample and path params', a
|
||||
|
||||
await page.goto('/wizard/');
|
||||
await page.locator('[data-testid="wizard-protocol-rest"]').click();
|
||||
await page.evaluate(() => window.CrankWizardShell.doGoToStep(2));
|
||||
await page.evaluate(() => window.CrankWizardShell.goToStep(2));
|
||||
await expect(page.locator('#step-panel-2')).toBeVisible();
|
||||
await page.locator('#endpoint-path').fill('/rates/{date}');
|
||||
|
||||
await page.evaluate(() => window.CrankWizardShell.doGoToStep(3));
|
||||
await page.evaluate(() => window.CrankWizardShell.goToStep(3));
|
||||
await expect(page.locator('#step-panel-3-rest')).toBeVisible();
|
||||
await page.locator('.method-card[data-method="GET"]').click();
|
||||
|
||||
await page.evaluate(() => window.CrankWizardShell.doGoToStep(5));
|
||||
await page.evaluate(() => window.CrankWizardShell.goToStep(5));
|
||||
await expect(page.locator('#step-panel-5')).toBeVisible();
|
||||
|
||||
await page.locator('#wizard-input-sample').fill(JSON.stringify({
|
||||
|
||||
@@ -11,6 +11,12 @@ test('workspace and settings pages show live session data', async ({ page }) =>
|
||||
await expect(page.locator('#section-members')).toHaveCount(0);
|
||||
await expect(page.locator('#section-invite')).toHaveCount(0);
|
||||
await expect(page.locator('#delete-workspace-btn')).toHaveCount(0);
|
||||
await expect(page.locator('[data-i18n="workspace_setup.danger.export_title"]')).toHaveText(
|
||||
localized('Export workspace catalog', 'Экспорт каталога рабочего пространства'),
|
||||
);
|
||||
await expect(page.locator('[data-i18n="workspace_setup.danger.export_body"]')).not.toContainText(
|
||||
localized('all data', 'все данные'),
|
||||
);
|
||||
|
||||
await page.goto('/settings');
|
||||
await expect(page.locator('.page-title')).toHaveText(localized('Account settings', 'Настройки аккаунта'));
|
||||
|
||||
Reference in New Issue
Block a user