Polish community UI copy and cleanup
Deploy / deploy (push) Successful in 1m36s
CI / Rust Checks (push) Successful in 4m50s
CI / UI Checks (push) Successful in 5s
CI / Deployment Manifests (push) Successful in 2s
CI / Frontend E2E (push) Failing after 5m5s

This commit is contained in:
github-ops
2026-06-19 21:15:02 +00:00
parent 66dd0deee5
commit d072d142ca
57 changed files with 710 additions and 6773 deletions
-48
View File
@@ -1,6 +1,5 @@
var KEYS = [];
var AGENTS = [];
var capabilities = null;
var currentWorkspaceId = null;
var currentAgentId = null;
var selectedScopes = new Set(['read']);
@@ -21,10 +20,6 @@ function tfKey(key, vars) {
return window.tf ? tf(key, vars) : tKey(key);
}
function capabilityLabel(key) {
return tKey('settings.capability.' + key);
}
function buildIconSvg(href, width, height) {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('width', String(width));
@@ -114,47 +109,6 @@ async function loadKeys() {
}
}
async function loadCapabilities() {
if (!window.CrankApi || typeof window.CrankApi.getCapabilities !== 'function') {
return;
}
try {
capabilities = await window.CrankApi.getCapabilities();
} catch (_error) {
capabilities = null;
}
renderMachineAccessSummary();
}
function renderMachineAccessSummary() {
var title = document.getElementById('machine-access-title');
var subtitle = document.getElementById('machine-access-subtitle');
var summary = document.getElementById('machine-access-summary');
var note = document.getElementById('machine-access-note');
if (!title || !subtitle || !summary || !note) {
return;
}
if (!capabilities) {
summary.textContent = tKey('apikeys.machine_access.summary_default');
note.textContent = tKey('apikeys.machine_access.note');
return;
}
var accessModes = (capabilities.machine_access_modes || []).map(capabilityLabel).join(', ');
var securityLevels = (capabilities.supported_security_levels || []).map(capabilityLabel).join(', ');
title.textContent = tKey('apikeys.machine_access.title_' + capabilities.edition);
subtitle.textContent = tKey('apikeys.machine_access.subtitle_' + capabilities.edition);
summary.textContent = tfKey('apikeys.machine_access.summary', {
access_modes: accessModes || capabilityLabel('none'),
security_levels: securityLevels || capabilityLabel('none'),
});
note.textContent = tKey('apikeys.machine_access.note_' + capabilities.edition);
}
function setTableLoading(on) {
var tbody = document.getElementById('keys-tbody');
if (!on) return;
@@ -611,10 +565,8 @@ function copyPrefix(prefix) {
document.addEventListener('DOMContentLoaded', async function() {
await (window.whenWorkspacesReady ? window.whenWorkspacesReady() : Promise.resolve());
await loadCapabilities();
await loadKeys();
window.addEventListener('crank:workspacechange', function() {
loadCapabilities();
loadKeys();
});
});
+3
View File
@@ -298,6 +298,9 @@
listAuthProfiles: function(workspaceId) {
return get('/workspaces/' + encodeURIComponent(workspaceId) + '/auth-profiles');
},
createAuthProfile: function(workspaceId, payload) {
return post('/workspaces/' + encodeURIComponent(workspaceId) + '/auth-profiles', payload);
},
listUpstreams: function(workspaceId) {
return get('/workspaces/' + encodeURIComponent(workspaceId) + '/upstreams');
},
+1 -22
View File
@@ -99,7 +99,6 @@ document.addEventListener('alpine:init', function() {
pageSize: PAGE_SIZE_DESKTOP,
search: '',
tab: 'all',
filterProtocol: null,
filterCategory: null,
filterAgent: null,
sort: 'created_desc',
@@ -201,10 +200,6 @@ document.addEventListener('alpine:init', function() {
});
}
if (this.filterProtocol) {
filtered = filtered.filter(function(operation) { return operation.protocol === this.filterProtocol; }, this);
}
if (this.filterCategory) {
filtered = filtered.filter(function(operation) { return operation.category === this.filterCategory; }, this);
}
@@ -222,7 +217,6 @@ document.addEventListener('alpine:init', function() {
var key = [
this._opsVersion,
this.search.trim(),
this.filterProtocol || '',
this.filterCategory || '',
this.filterAgent || '',
].join('|');
@@ -315,7 +309,6 @@ document.addEventListener('alpine:init', function() {
get activeChips() {
var chips = [];
if (this.filterProtocol) chips.push({ key: 'protocol', label: this.tfKey('ops.filter.protocol', { value: this.filterProtocol.toUpperCase() }) });
if (this.filterCategory) chips.push({ key: 'category', label: this.tfKey('ops.filter.category', { value: this.filterCategory }) });
if (this.filterAgent) {
var agent = this.activeAgents.find(function(item) { return item.agent_id === this.filterAgent; }, this);
@@ -325,18 +318,16 @@ document.addEventListener('alpine:init', function() {
},
get hasActiveFilters() {
return !!(this.filterProtocol || this.filterCategory || this.filterAgent || this.search.trim());
return !!(this.filterCategory || this.filterAgent || this.search.trim());
},
clearChip(key) {
if (key === 'protocol') this.filterProtocol = null;
if (key === 'category') this.filterCategory = null;
if (key === 'agent') this.filterAgent = null;
this.page = 1;
},
clearAllFilters() {
this.filterProtocol = null;
this.filterCategory = null;
this.filterAgent = null;
this.search = '';
@@ -392,12 +383,6 @@ document.addEventListener('alpine:init', function() {
this.page = 1;
},
setProtocol(value) {
this.filterProtocol = this.filterProtocol === value ? null : value;
this.openDropdown = null;
this.page = 1;
},
setCategory(value) {
this.filterCategory = this.filterCategory === value ? null : value;
this.openDropdown = null;
@@ -415,12 +400,6 @@ document.addEventListener('alpine:init', function() {
this.page = 1;
},
clearProtocol() {
this.filterProtocol = null;
this.openDropdown = null;
this.page = 1;
},
clearCategory() {
this.filterCategory = null;
this.openDropdown = null;
+320 -392
View File
File diff suppressed because it is too large Load Diff
-42
View File
@@ -85,47 +85,6 @@ function populateCurrentSession(session) {
});
}
function capabilityLabel(key) {
return tKey('settings.capability.' + key);
}
function populateNotificationsCapabilityHint(capabilities) {
var title = document.getElementById('settings-notifications-capability-title');
var body = document.getElementById('settings-notifications-capability-body');
if (!title || !body || !capabilities) {
return;
}
title.textContent = tKey('settings.notifications.capability_title_' + capabilities.edition);
body.textContent = tfKey('settings.notifications.capability_body_' + capabilities.edition, {
edition: capabilities.edition,
});
}
function populateCapabilities(capabilities) {
var title = document.getElementById('settings-security-capability-title');
var body = document.getElementById('settings-security-capability-body');
if (!title || !body || !capabilities) {
return;
}
var protocols = (capabilities.supported_protocols || []).map(capabilityLabel).join(', ');
var accessModes = (capabilities.machine_access_modes || []).map(capabilityLabel).join(', ');
var securityLevels = (capabilities.supported_security_levels || []).map(capabilityLabel).join(', ');
var limits = capabilities.limits || {};
title.textContent = tKey('settings.security.capability_title_' + capabilities.edition);
body.textContent = tfKey('settings.security.capability_summary', {
protocols: protocols || capabilityLabel('none'),
access_modes: accessModes || capabilityLabel('none'),
security_levels: securityLevels || capabilityLabel('none'),
max_workspaces: limits.max_workspaces == null ? capabilityLabel('unlimited') : String(limits.max_workspaces),
max_users: limits.max_users_per_workspace == null ? capabilityLabel('unlimited') : String(limits.max_users_per_workspace),
max_agents: limits.max_agents_per_workspace == null ? capabilityLabel('unlimited') : String(limits.max_agents_per_workspace),
});
populateNotificationsCapabilityHint(capabilities);
}
function populateProfile(session) {
if (!session || !session.user) {
return;
@@ -166,7 +125,6 @@ async function loadCapabilities() {
try {
settingsCapabilities = await window.CrankApi.getCapabilities();
populateCapabilities(settingsCapabilities);
} catch (_error) {
}
}
+20
View File
@@ -104,6 +104,15 @@ async function loadWizardAuthResources() {
renderAuthProfileOptions();
}
async function refreshWizardAuthResources() {
var previousUpstream = selectedUpstreamId;
await loadWizardAuthResources();
renderDropdownList('');
if (previousUpstream && upstreams.some(function(item) { return item.id === previousUpstream; })) {
pickUpstream(previousUpstream);
}
}
function renderAuthProfileOptions() {
var profileSelect = document.getElementById('new-upstream-auth-profile');
var secretSelect = document.getElementById('new-auth-profile-secret-id');
@@ -186,6 +195,17 @@ function updateUpstreamAuthUi() {
if (existingGroup) existingGroup.hidden = mode !== 'existing';
if (createGroup) createGroup.hidden = mode !== 'create';
updateAuthProfileCreateUi();
if (mode === 'existing' || mode === 'create') {
void refreshWizardAuthResources();
}
}
function refreshWizardAuthResourcesOnFocus() {
var mode = textValue('new-upstream-auth-mode') || 'none';
var form = document.getElementById('upstream-new-form');
if (form && !form.hidden && (mode === 'existing' || mode === 'create')) {
void refreshWizardAuthResources();
}
}
function buildUpstreamTriggerContent(name, url) {
+4 -3
View File
@@ -101,6 +101,7 @@ async function initWizardPage() {
bindWizardLiveActions();
updateUpstreamAuthUi();
renderEditionCapabilityHints(editionCapabilities);
window.addEventListener('focus', refreshWizardAuthResourcesOnFocus);
var quickSecretModal = document.getElementById('quick-secret-modal');
var quickSecretClose = document.getElementById('quick-secret-close-btn');
@@ -178,9 +179,9 @@ if (window.CrankDiagnostics && typeof window.CrankDiagnostics.bootstrap === 'fun
var METHOD_CALLOUTS = {
GET: null,
DELETE: null,
POST: { icon: 'info', text: { en: { title: 'POST selected — body encoding required.', body: 'In step 4 you will define the JSON schema for the body payload. Crank will automatically serialize MCP tool arguments into the format you specify.' }, ru: { title: 'Выбран POST — требуется кодирование тела запроса.', body: 'На шаге 4 вы зададите JSON-схему для body payload. Crank автоматически сериализует аргументы MCP-инструмента в выбранный формат.' } } },
PUT: { icon: 'info', text: { en: { title: 'PUT selected — full-resource replacement.', body: 'The request body must contain a complete resource representation. Define the body schema in step 4.' }, ru: { title: 'Выбран PUT — полная замена ресурса.', body: 'Request body должен содержать полное представление ресурса. Задайте body schema на шаге 4.' } } },
PATCH: { icon: 'info', text: { en: { title: 'PATCH selected — partial update.', body: 'Only include the fields you want to modify in the body schema defined in step 4.' }, ru: { title: 'Выбран PATCH — частичное обновление.', body: 'В body schema на шаге 4 включайте только те поля, которые хотите изменить.' } } },
POST: { icon: 'info', text: { en: { title: 'POST selected — request body is required.', body: 'In step 4 you will define the JSON schema for the request body. Crank will convert MCP tool parameters into the selected format.' }, ru: { title: 'Выбран POST — требуется тело запроса.', body: 'На шаге 4 вы зададите JSON-схему тела запроса. Crank преобразует параметры MCP инструмента в выбранный формат.' } } },
PUT: { icon: 'info', text: { en: { title: 'PUT selected — full-resource replacement.', body: 'The request body must contain a complete resource representation. Define the request schema in step 4.' }, ru: { title: 'Выбран PUT — полная замена ресурса.', body: 'Тело запроса должно содержать полное представление ресурса. Задайте схему запроса на шаге 4.' } } },
PATCH: { icon: 'info', text: { en: { title: 'PATCH selected — partial update.', body: 'Only include the fields you want to modify in the request schema defined in step 4.' }, ru: { title: 'Выбран PATCH — частичное обновление.', body: 'В схему запроса на шаге 4 включайте только те поля, которые хотите изменить.' } } },
};
function buildWizardIconSvg(href, width, height) {