// Recent activity view for tester/admin auditing
import { api } from './api.js';
import { state } from './state.js';
import { escHtml, formatDateTime } from './utils.js';
const ACTION_LABELS = {
adobe_connected: 'Adobe connected',
adobe_disconnected: 'Adobe disconnected',
docusign_authorization_requested: 'DocuSign auth requested',
docusign_authorization_started: 'DocuSign auth started',
docusign_connected: 'DocuSign connected',
docusign_account_selected: 'DocuSign account selected',
docusign_disconnected: 'DocuSign disconnected',
migration_run: 'Migration run',
migration_batch_started: 'Batch migration started',
migration_batch_completed: 'Batch migration completed',
verification_sent: 'Verification sent',
verification_voided: 'Verification voided',
};
const ACTIVITY_SCOPE_KEY = 'migrator_activity_scope';
export async function renderActivity() {
const outlet = document.getElementById('router-outlet');
outlet.innerHTML = `
`;
const showAll = state.auth.isAdmin && localStorage.getItem(ACTIVITY_SCOPE_KEY) === 'all';
try {
const data = await api.audit.recent(150, showAll);
const events = data.events || [];
const isAdmin = !!data.is_admin;
const scope = data.scope || 'session';
outlet.innerHTML = `
${events.length === 0 ? `
๐งพ
No activity yet
Recent tester actions will appear here after people connect and use the app.
` : `
| Time |
Action |
DocuSign |
Adobe |
Session |
IP |
Details |
${events.map(renderEventRow).join('')}
`}
`;
document.getElementById('btn-toggle-activity-scope')?.addEventListener('click', () => {
localStorage.setItem(ACTIVITY_SCOPE_KEY, scope === 'all' ? 'session' : 'all');
renderActivity();
});
} catch (e) {
outlet.innerHTML = `โFailed to load activity: ${escHtml(e.message)}
`;
}
}
function renderEventRow(event) {
const docusignLabel = event.docusign_account_name || event.docusign_user_name || event.docusign_user_email || 'โ';
const adobeLabel = event.adobe_account_name || event.adobe_user_name || event.adobe_user_email || 'โ';
const sessionId = event.session_id ? `${event.session_id.slice(0, 10)}โฆ` : 'โ';
const detailText = formatDetails(event.details);
return `
| ${escHtml(formatDateTime(event.timestamp))} |
${escHtml(ACTION_LABELS[event.action] || event.action || 'Activity')} |
${escHtml(docusignLabel)}
${escHtml(event.docusign_account_id || event.docusign_user_email || '')}
|
${escHtml(adobeLabel)}
${escHtml(event.adobe_account_id || event.adobe_user_email || '')}
|
${escHtml(sessionId)} |
${escHtml(event.ip || 'โ')} |
${escHtml(detailText)} |
`;
}
function formatDetails(details) {
if (!details || typeof details !== 'object') {
return 'โ';
}
const parts = Object.entries(details)
.filter(([, value]) => value !== null && value !== undefined && value !== '')
.map(([key, value]) => `${humanizeKey(key)}: ${formatValue(value)}`);
return parts.length ? parts.join(' | ') : 'โ';
}
function humanizeKey(key) {
return key.replace(/_/g, ' ');
}
function formatValue(value) {
if (typeof value === 'boolean') {
return value ? 'yes' : 'no';
}
return String(value);
}