Files
workorders/web/app.mjs
T

85 lines
3.1 KiB
JavaScript

import { setToken } from './lib/api.mjs';
import './components/wo-list.mjs';
import './components/wo-form.mjs';
// ── Keycloak init ─────────────────────────────────────────────────────────────
const keycloak = new Keycloak({
url: window.KEYCLOAK_URL || 'http://localhost:8180',
realm: window.KEYCLOAK_REALM || 'workorders',
clientId: window.KEYCLOAK_CLIENT_ID || 'workorders-app',
});
keycloak.init({
onLoad: 'login-required',
pkceMethod: 'S256',
checkLoginIframe: false,
})
.then(authenticated => {
if (!authenticated) { keycloak.login(); return; }
setToken(keycloak.token);
// Refresh token before it expires
setInterval(async () => {
try { await keycloak.updateToken(60); setToken(keycloak.token); }
catch { keycloak.login(); }
}, 30_000);
window.addEventListener('auth:expired', () => keycloak.login());
renderApp(keycloak);
})
.catch(() => document.getElementById('app').innerHTML =
'<p style="color:red;padding:2rem">Failed to connect to authentication server.</p>');
// ── App shell ─────────────────────────────────────────────────────────────────
function renderApp(kc) {
const app = document.getElementById('app');
const userName = kc.tokenParsed?.name || kc.tokenParsed?.preferred_username || 'User';
// Nav
const nav = document.createElement('nav');
nav.innerHTML = `
<span class="brand">Work Orders</span>
<span class="spacer"></span>
<span class="user-info">${userName}</span>
<button id="logout" style="background:transparent;border:1px solid rgba(255,255,255,.4);color:#fff;padding:.3rem .8rem;font-size:.85rem">Logout</button>`;
document.body.insertBefore(nav, app);
nav.querySelector('#logout').addEventListener('click', () => kc.logout());
showList();
app.addEventListener('wo:select', e => showDetail(e.detail.id));
app.addEventListener('wo:cancel', () => showList());
app.addEventListener('wo:saved', () => showList());
document.addEventListener('keydown', e => { if (e.key === 'Escape') showList(); });
}
function showList() {
const app = document.getElementById('app');
app.innerHTML = `
<div class="page-header">
<h1>Work Orders</h1>
<button id="new-wo">+ New Work Order</button>
</div>
<wo-list id="wo-list"></wo-list>`;
app.querySelector('#new-wo').addEventListener('click', showCreate);
}
function showCreate() {
const app = document.getElementById('app');
app.innerHTML = `
<div class="page-header"><h1>New Work Order</h1></div>
<div class="card"><wo-form></wo-form></div>`;
}
function showDetail(id) {
const app = document.getElementById('app');
app.innerHTML = `
<div class="page-header">
<h1>Edit Work Order</h1>
<button id="back" class="secondary">← Back</button>
</div>
<div class="card"><wo-form wo-id="${id}"></wo-form></div>`;
app.querySelector('#back').addEventListener('click', showList);
}