import { t } from './i18n.js';
// HTML escape helper — prevents XSS when inserting user data into innerHTML
export function esc(str) {
if (str == null) return '';
return String(str).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"').replace(/'/g,''');
}
// v4 liveness badge. The patch4 server derives a 3-state liveness — 'healthy' / 'degraded'
// (temporarily reconnecting) / 'offline' — and emits it as `data.liveness` on dashboard:device-status.
// It is present on SOME emits only (the plain reconnect + disconnect emits, and any device object read
// from the DB, carry just the binary `status`), so we DEGRADE to the binary status when liveness is
// absent — nothing ever renders blank. 'provisioning' is a lifecycle state (never-paired), kept
// distinct from liveness. livenessState() is pure (unit-testable); livenessBadge() adds the i18n label.
const LIVENESS_LABEL_KEY = {
healthy: 'device.liveness.healthy',
degraded: 'device.liveness.degraded',
offline: 'device.liveness.offline',
provisioning: 'dashboard.awaiting_pairing',
};
export function livenessState(data) {
const lv = data && data.liveness;
if (lv === 'healthy' || lv === 'degraded' || lv === 'offline') return lv; // 3-state signal present
const st = data && data.status; // backward-compat: derive from binary status
if (st === 'provisioning') return 'provisioning';
if (st === 'online') return 'healthy';
if (st === 'offline') return 'offline';
return 'offline'; // unknown / no data yet -> safe default, never blank
}
export function livenessBadge(data) {
const state = livenessState(data);
return { state, label: t(LIVENESS_LABEL_KEY[state]) };
}
// Phase 2.1: the Phase 1 schema migration renamed the legacy 'superadmin'
// role to 'platform_admin'. Existing frontend checks still match the old
// string; this helper accepts both so we don't have to splatter the array
// at every call site. Use everywhere the UI gates on platform-level access.
export function isPlatformAdmin(user) {
return !!(user && (user.role === 'superadmin' || user.role === 'platform_admin'));
}