adobe-to-docusign-migrator/web/static/js/settings.js

289 lines
13 KiB
JavaScript

// Settings view — verification defaults, migration defaults, connection info
import { api } from './api.js';
import { escHtml } from './utils.js';
import { disconnectPlatform, showDocusignAccountPicker, switchAccount } from './auth.js';
import { navigate } from './router.js';
import { resetQuickStart } from './help.js';
const SETTINGS_KEY = 'migrator_settings';
export function loadSettings() {
try { return JSON.parse(localStorage.getItem(SETTINGS_KEY)) || {}; }
catch { return {}; }
}
export function saveSettings(settings) {
localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));
}
export function renderSettings() {
const outlet = document.getElementById('router-outlet');
const s = loadSettings();
outlet.innerHTML = `
<div class="page-header">
<div>
<div class="page-title">Settings</div>
<div class="page-subtitle">Configure verification defaults and migration behavior</div>
</div>
</div>
<!-- Verification defaults -->
<div class="settings-section">
<div class="settings-section-header">
<div class="settings-section-title">Verification</div>
<div class="settings-section-sub">Default recipient for test envelopes. The same name and email are used for every recipient role on the template during a test send.</div>
</div>
<div class="settings-section-body">
<div class="setting-row">
<div class="setting-body">
<div class="setting-label">Test Recipient Name</div>
<div class="setting-desc">Pre-filled in the Send Test dialog on the Verification screen and reused for all recipient roles in the template.</div>
</div>
<div class="setting-control" style="min-width:240px">
<input type="text" class="form-input" id="set-recipient-name"
value="${escHtml(s.testRecipientName || '')}"
placeholder="e.g. Test User" />
</div>
</div>
<div class="setting-row">
<div class="setting-body">
<div class="setting-label">Test Recipient Email</div>
<div class="setting-desc">Pre-filled in the Send Test dialog and used on every recipient role when sending a verification envelope.</div>
</div>
<div class="setting-control" style="min-width:240px">
<input type="email" class="form-input" id="set-recipient-email"
value="${escHtml(s.testRecipientEmail || '')}"
placeholder="e.g. test@example.com" />
</div>
</div>
<div class="setting-row">
<div class="setting-body">
<div class="setting-label">Auto-Void Timer (hours)</div>
<div class="setting-desc">Reminder to void test envelopes after this many hours (display only — no automatic action)</div>
</div>
<div class="setting-control">
<input type="number" class="form-input" id="set-auto-void"
value="${s.autoVoidHours ?? 24}" min="1" max="168" style="width:80px" />
</div>
</div>
</div>
</div>
<!-- Migration defaults -->
<div class="settings-section">
<div class="settings-section-header">
<div class="settings-section-title">Migration Defaults</div>
<div class="settings-section-sub">Pre-set options in the migration options modal</div>
</div>
<div class="settings-section-body">
<div class="setting-row">
<div class="setting-body">
<div class="setting-label">Overwrite Existing by Default</div>
<div class="setting-desc">When on, the Overwrite Existing toggle in the migration modal starts enabled</div>
</div>
<div class="setting-control">
<button class="toggle ${s.defaultOverwrite ? 'on' : ''}" id="set-overwrite"
role="switch" aria-checked="${!!s.defaultOverwrite}"></button>
</div>
</div>
<div class="setting-row">
<div class="setting-body">
<div class="setting-label">Include Documents by Default</div>
<div class="setting-desc">Embed PDFs in the Docusign template payload</div>
</div>
<div class="setting-control">
<button class="toggle ${s.defaultIncludeDocs !== false ? 'on' : ''}" id="set-include-docs"
role="switch" aria-checked="${s.defaultIncludeDocs !== false}"></button>
</div>
</div>
</div>
</div>
<!-- Connection info (read-only) -->
<div class="settings-section">
<div class="settings-section-header">
<div class="settings-section-title">Connections</div>
<div class="settings-section-sub">Current platform connection status and account actions</div>
</div>
<div class="settings-section-body" id="settings-conn-info">
<div style="padding:8px 0;font-size:13px;color:var(--text-muted)">Loading…</div>
</div>
</div>
<div class="settings-section">
<div class="settings-section-header">
<div class="settings-section-title">Help & Onboarding</div>
<div class="settings-section-sub">Make it easy to get oriented again or share the app with a first-time tester</div>
</div>
<div class="settings-section-body">
<div class="setting-row">
<div class="setting-body">
<div class="setting-label">Open Full Help</div>
<div class="setting-desc">See the in-app guide with the recommended first-time flow and screen-by-screen overview.</div>
</div>
<div class="setting-control">
<button class="btn btn-secondary" id="btn-open-help">Open Help</button>
</div>
</div>
<div class="setting-row">
<div class="setting-body">
<div class="setting-label">Show Quick Start Again</div>
<div class="setting-desc">Re-enable the Templates quick-start card if you dismissed it earlier.</div>
</div>
<div class="setting-control">
<button class="btn btn-primary" id="btn-reset-quick-start">Show Quick Start</button>
</div>
</div>
</div>
</div>
<!-- Save -->
<div style="display:flex;gap:8px;align-items:center">
<button class="btn btn-primary" id="btn-save-settings">Save Settings</button>
<span id="save-confirm" style="font-size:13px;color:var(--success);display:none">✓ Saved</span>
</div>
`;
// Wire toggles
document.querySelectorAll('.toggle').forEach(btn => {
btn.addEventListener('click', () => {
btn.classList.toggle('on');
btn.setAttribute('aria-checked', btn.classList.contains('on'));
});
});
// Save
document.getElementById('btn-save-settings')?.addEventListener('click', () => {
const updated = {
testRecipientName: document.getElementById('set-recipient-name')?.value.trim() || '',
testRecipientEmail: document.getElementById('set-recipient-email')?.value.trim() || '',
autoVoidHours: parseInt(document.getElementById('set-auto-void')?.value) || 24,
defaultOverwrite: document.getElementById('set-overwrite')?.classList.contains('on') || false,
defaultIncludeDocs: document.getElementById('set-include-docs')?.classList.contains('on') !== false,
};
saveSettings(updated);
const confirm = document.getElementById('save-confirm');
if (confirm) {
confirm.style.display = 'inline';
setTimeout(() => { confirm.style.display = 'none'; }, 2500);
}
});
document.getElementById('btn-open-help')?.addEventListener('click', () => {
navigate('#/help');
});
document.getElementById('btn-reset-quick-start')?.addEventListener('click', () => {
resetQuickStart();
navigate('#/templates');
});
// Load connection info
_loadConnInfo();
}
async function _loadConnInfo() {
const connEl = document.getElementById('settings-conn-info');
if (!connEl) return;
try {
const data = await api.auth.status();
connEl.innerHTML = `
<div class="conn-info-row">
<span class="conn-info-label">Adobe Sign</span>
<span class="conn-info-value">${data.adobe ? `Connected${data.adobe_account_name ? `${escHtml(data.adobe_account_name)}` : ''}` : 'Not connected'}</span>
<span class="conn-info-status">
<span class="badge ${data.adobe ? 'badge-green' : 'badge-gray'}">${data.adobe ? '● Connected' : '○ Disconnected'}</span>
</span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">Docusign</span>
<span class="conn-info-value">${data.docusign ? (data.docusign_account_selection_required ? 'Connected — account selection required' : `Connected${data.docusign_account_name ? `${escHtml(data.docusign_account_name)}` : ''}`) : 'Not connected'}</span>
<span class="conn-info-status">
<span class="badge ${data.docusign ? (data.docusign_account_selection_required ? 'badge-amber' : 'badge-green') : 'badge-gray'}">${data.docusign ? (data.docusign_account_selection_required ? '● Choose account' : '● Connected') : '○ Disconnected'}</span>
</span>
</div>
<div class="conn-info-row conn-info-actions">
<span class="conn-info-label">Adobe Actions</span>
<span class="conn-info-value">
<button class="btn btn-secondary" id="btn-disconnect-adobe" ${data.adobe ? '' : 'disabled'}>Disconnect Adobe Sign</button>
</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row conn-info-actions">
<span class="conn-info-label">Docusign Actions</span>
<span class="conn-info-value" style="display:flex;gap:8px;flex-wrap:wrap">
<button class="btn btn-secondary" id="btn-disconnect-docusign" ${data.docusign ? '' : 'disabled'}>Disconnect Docusign</button>
<button class="btn btn-primary" id="btn-switch-docusign" ${data.docusign ? '' : 'disabled'}>Switch Docusign Account</button>
<button class="btn btn-secondary" id="btn-choose-docusign-account" ${data.docusign ? '' : 'disabled'}>Choose Account</button>
</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">Adobe Auth Mode</span>
<span class="conn-info-value mono">${escHtml(data.adobe_auth_mode || '—')}</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">Docusign Auth Mode</span>
<span class="conn-info-value mono">${escHtml(data.docusign_auth_mode || '—')}</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">Browser Session ID</span>
<span class="conn-info-value mono">${escHtml(data.session_id || '—')}</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">Admin Access</span>
<span class="conn-info-value">${data.is_admin ? 'Yes — this session can view all audit logs.' : 'No — this session can only view its own audit logs.'}</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">Switch Account Note</span>
<span class="conn-info-value">Use <strong>Choose Account</strong> or <strong>Switch Docusign Account</strong> to select from the DocuSign accounts available to this login. The picker is sorted alphabetically and supports search.</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">Adobe Account ID</span>
<span class="conn-info-value mono">${escHtml(data.adobe_account_id || '—')}</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">Docusign Account ID</span>
<span class="conn-info-value mono">${escHtml(data.docusign_account_id || '—')}</span>
<span class="conn-info-status"></span>
</div>
<div class="conn-info-row">
<span class="conn-info-label">API Environment</span>
<span class="conn-info-value mono">${escHtml(data.base_url || '—')}</span>
<span class="conn-info-status"></span>
</div>
`;
} catch (e) {
connEl.innerHTML = `<div class="callout error"><span class="callout-icon">❌</span>Failed to load connection info: ${escHtml(e.message)}</div>`;
return;
}
document.getElementById('btn-disconnect-adobe')?.addEventListener('click', async () => {
await disconnectPlatform('adobe');
await _loadConnInfo();
});
document.getElementById('btn-disconnect-docusign')?.addEventListener('click', async () => {
await disconnectPlatform('docusign');
await _loadConnInfo();
});
document.getElementById('btn-switch-docusign')?.addEventListener('click', async () => {
await switchAccount('docusign');
});
document.getElementById('btn-choose-docusign-account')?.addEventListener('click', async () => {
await showDocusignAccountPicker({ forceRefresh: true });
});
if (data.docusign && data.docusign_account_selection_required) {
await showDocusignAccountPicker();
}
}