feat: polish alpine settings and wizard feedback
This commit is contained in:
+33
-64
@@ -5,16 +5,6 @@ function settingsWorkspaceId() {
|
||||
return workspace ? workspace.id : null;
|
||||
}
|
||||
|
||||
function downloadSettingsJson(fileName, value) {
|
||||
var blob = new Blob([JSON.stringify(value, null, 2)], { type: 'application/json;charset=utf-8' });
|
||||
var url = URL.createObjectURL(blob);
|
||||
var link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = fileName;
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
function initials(displayName, email) {
|
||||
var source = displayName || email || 'Crank';
|
||||
return source
|
||||
@@ -34,6 +24,37 @@ function setStatus(id, text, isError) {
|
||||
: 'var(--text-muted)';
|
||||
}
|
||||
|
||||
function titleCaseRole(role) {
|
||||
return String(role || 'viewer').replace(/^\w/, function(character) {
|
||||
return character.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
function populateCurrentSession(session) {
|
||||
var summary = document.getElementById('settings-session-summary');
|
||||
if (!summary) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(session && session.user)) {
|
||||
summary.textContent = 'Session details are unavailable. Use Log out to revoke the current browser session.';
|
||||
return;
|
||||
}
|
||||
|
||||
var membership = null;
|
||||
if (Array.isArray(session.memberships)) {
|
||||
membership = session.memberships.find(function(item) {
|
||||
return item.workspace && item.workspace.id === session.current_workspace_id;
|
||||
}) || session.memberships[0] || null;
|
||||
}
|
||||
|
||||
var workspaceLabel = membership && membership.workspace
|
||||
? (membership.workspace.display_name || membership.workspace.slug || membership.workspace.id)
|
||||
: 'current workspace';
|
||||
var roleLabel = membership ? titleCaseRole(membership.role) : 'Viewer';
|
||||
summary.textContent = session.user.email + ' · ' + roleLabel + ' in ' + workspaceLabel + '. Use Log out to revoke the current browser session.';
|
||||
}
|
||||
|
||||
function populateProfile(session) {
|
||||
if (!session || !session.user) {
|
||||
return;
|
||||
@@ -52,6 +73,8 @@ function populateProfile(session) {
|
||||
if (email) {
|
||||
email.value = user.email || '';
|
||||
}
|
||||
|
||||
populateCurrentSession(session);
|
||||
}
|
||||
|
||||
async function loadProfile() {
|
||||
@@ -285,65 +308,11 @@ async function loadWorkspaceSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
function bindDangerZoneActions() {
|
||||
var renameButton = document.getElementById('settings-ws-rename-btn');
|
||||
var exportButton = document.getElementById('settings-ws-export-btn');
|
||||
var deleteButton = document.getElementById('settings-ws-delete-btn');
|
||||
|
||||
if (renameButton && renameButton.dataset.bound !== 'true') {
|
||||
renameButton.dataset.bound = 'true';
|
||||
renameButton.addEventListener('click', function() {
|
||||
document.getElementById('settings-ws-slug').focus();
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.info('Update the workspace slug above and save changes to rename it.', 'Rename workspace');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (exportButton && exportButton.dataset.bound !== 'true') {
|
||||
exportButton.dataset.bound = 'true';
|
||||
exportButton.addEventListener('click', async function() {
|
||||
var workspaceId = settingsWorkspaceId();
|
||||
if (!workspaceId || !window.CrankApi) return;
|
||||
try {
|
||||
var snapshot = await window.CrankApi.exportWorkspace(workspaceId);
|
||||
var workspace = window.getCurrentWorkspace ? window.getCurrentWorkspace() : null;
|
||||
downloadSettingsJson((workspace ? workspace.slug : 'workspace') + '-snapshot.json', snapshot);
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.success('Workspace export downloaded.', 'Export complete');
|
||||
}
|
||||
} catch (error) {
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.error(error.message || 'Failed to export workspace', 'Export failed');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (deleteButton && deleteButton.dataset.bound !== 'true') {
|
||||
deleteButton.dataset.bound = 'true';
|
||||
deleteButton.addEventListener('click', async function() {
|
||||
var workspaceId = settingsWorkspaceId();
|
||||
if (!workspaceId || !window.CrankApi || !window.CrankAuth) return;
|
||||
if (!window.confirm('Delete workspace? This cannot be undone.')) return;
|
||||
try {
|
||||
await window.CrankApi.deleteWorkspace(workspaceId);
|
||||
await window.CrankAuth.logout();
|
||||
} catch (error) {
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.error(error.message || 'Failed to delete workspace', 'Delete failed');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
injectLanguageSwitcher();
|
||||
bindSectionNavigation();
|
||||
loadProfile();
|
||||
bindProfileSave();
|
||||
bindPasswordSave();
|
||||
bindDangerZoneActions();
|
||||
loadWorkspaceSettings();
|
||||
});
|
||||
|
||||
+52
-9
@@ -1352,19 +1352,19 @@ function prefillWizardFromEdit(detail, versionDocument) {
|
||||
}
|
||||
|
||||
function bindWizardLiveActions() {
|
||||
bindClick('wizard-upload-input-sample', uploadInputSampleFromWizard);
|
||||
bindClick('wizard-upload-output-sample', uploadOutputSampleFromWizard);
|
||||
bindClick('wizard-generate-draft', generateDraftFromWizard);
|
||||
bindClick('wizard-run-test', runWizardTest);
|
||||
bindLiveAction('wizard-upload-input-sample', 'Saving input sample…', uploadInputSampleFromWizard);
|
||||
bindLiveAction('wizard-upload-output-sample', 'Saving output sample…', uploadOutputSampleFromWizard);
|
||||
bindLiveAction('wizard-generate-draft', 'Generating draft…', generateDraftFromWizard);
|
||||
bindLiveAction('wizard-run-test', 'Running test…', runWizardTest);
|
||||
bindClick('wizard-copy-test-response', copyTestResponseToOutputSample);
|
||||
bindClick('wizard-export-yaml', exportWizardYaml);
|
||||
bindClick('wizard-import-yaml', importWizardYaml);
|
||||
bindClick('wizard-publish-operation', publishWizardOperation);
|
||||
bindLiveAction('wizard-export-yaml', 'Exporting YAML…', exportWizardYaml);
|
||||
bindLiveAction('wizard-import-yaml', 'Importing YAML…', importWizardYaml);
|
||||
bindLiveAction('wizard-publish-operation', 'Publishing operation…', publishWizardOperation);
|
||||
bindClick('wizard-select-descriptor-set', function() {
|
||||
var input = document.getElementById('wizard-descriptor-set-input');
|
||||
if (input) input.click();
|
||||
});
|
||||
bindClick('wizard-upload-descriptor-set', uploadDescriptorSetAndDiscover);
|
||||
bindLiveAction('wizard-upload-descriptor-set', 'Uploading descriptor set…', uploadDescriptorSetAndDiscover);
|
||||
bindClick('wizard-import-yaml-file-trigger', function() {
|
||||
var input = document.getElementById('wizard-import-yaml-file');
|
||||
if (input) input.click();
|
||||
@@ -1386,6 +1386,48 @@ function bindClick(id, handler) {
|
||||
});
|
||||
}
|
||||
|
||||
function bindLiveAction(id, busyLabel, handler) {
|
||||
var element = document.getElementById(id);
|
||||
if (!element) return;
|
||||
element.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
runWizardLiveAction(element, busyLabel, handler);
|
||||
});
|
||||
}
|
||||
|
||||
async function runWizardLiveAction(button, busyLabel, handler) {
|
||||
if (!button || button.dataset.busy === 'true') {
|
||||
return;
|
||||
}
|
||||
|
||||
var originalLabel = button.textContent;
|
||||
button.dataset.busy = 'true';
|
||||
button.disabled = true;
|
||||
button.classList.add('is-busy');
|
||||
button.textContent = busyLabel;
|
||||
|
||||
try {
|
||||
await handler();
|
||||
} catch (error) {
|
||||
showWizardLiveStatus(
|
||||
'Live action failed',
|
||||
error && error.message ? error.message : 'The backend request failed. Review the draft and try again.',
|
||||
true
|
||||
);
|
||||
if (window.CrankUi) {
|
||||
window.CrankUi.error(
|
||||
error && error.message ? error.message : 'The backend request failed. Review the draft and try again.',
|
||||
'Wizard action failed'
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
button.dataset.busy = 'false';
|
||||
button.disabled = false;
|
||||
button.classList.remove('is-busy');
|
||||
button.textContent = originalLabel;
|
||||
}
|
||||
}
|
||||
|
||||
function updateWizardProtocolVisibility() {
|
||||
var grpcTools = document.getElementById('wizard-grpc-live-tools');
|
||||
if (grpcTools) grpcTools.style.display = wizardProtocol === 'grpc' ? '' : 'none';
|
||||
@@ -1399,7 +1441,8 @@ function showWizardLiveStatus(title, text, isError) {
|
||||
titleEl.textContent = title;
|
||||
textEl.textContent = text;
|
||||
root.style.display = '';
|
||||
root.style.borderColor = isError ? 'rgba(248, 113, 113, 0.35)' : '';
|
||||
root.classList.toggle('is-error', !!isError);
|
||||
root.classList.toggle('is-success', !isError);
|
||||
}
|
||||
|
||||
function currentDraftVersion() {
|
||||
|
||||
Reference in New Issue
Block a user