import { APP_VERSION } from '../../app/config.js'; export function renderSettingsPage() { return `

Client Settings

Connection & workspace

These values are stored locally and reused to start the Tryton user application flow.

Leave empty to use the same origin as this deployed Lonc frontend.
Only the first 16 characters are shown for identification.

App update

Check for the latest deployed build and force-refresh this installed app when needed.

Current version
Server version

Integration notes

  • Connection uses Tryton user application keys for the kitchen application.
  • Leaving the server URL empty makes API calls use same-origin relative paths.
  • Kitchen-scoped requests are built as /{database}/kitchen/{kitchenId}/....
  • Label preview accepts image blobs, image URLs, or SVG payloads.
`; } export function settingsPageData(store) { return { form: { baseUrl: store.config.baseUrl || '', database: store.config.database || '', }, update: { currentVersion: APP_VERSION, serverVersion: null, serverBuildTime: null, statusText: 'Ready to check for updates.', statusType: 'secondary', isChecking: false, isApplying: false, }, get userLogin() { return store.session?.userLogin || ''; }, get maskedApplicationKey() { const key = store.session?.applicationKey || ''; return key ? `${key.slice(0, 16)}...` : ''; }, save() { store.setConfig({ baseUrl: this.form.baseUrl.trim(), database: this.form.database.trim(), }); store.addAlert({ type: 'success', message: 'Settings saved locally.' }); }, formatBuildTime(value) { const date = new Date(value); if (Number.isNaN(date.getTime())) { return value; } return date.toLocaleString(); }, updateStatusClass() { switch (this.update.statusType) { case 'success': return 'text-success'; case 'warning': return 'text-warning'; case 'danger': return 'text-danger'; default: return 'text-body-secondary'; } }, async initUpdatePanel() { await this.checkForUpdates(); }, async checkForUpdates() { if (!window.__loncApp?.checkForAppUpdate) { this.update.statusText = 'Service worker updates are not available in this browser.'; this.update.statusType = 'warning'; return; } this.update.isChecking = true; this.update.statusText = 'Checking for updates...'; this.update.statusType = 'secondary'; try { const result = await window.__loncApp.checkForAppUpdate(); this.update.currentVersion = result.currentVersion || APP_VERSION; this.update.serverVersion = result.serverVersion || null; this.update.serverBuildTime = result.serverBuildTime || null; if (result.updateAvailable) { this.update.statusText = 'Update available. Use "Update app" to refresh this installed build.'; this.update.statusType = 'warning'; } else if (result.serverError) { this.update.statusText = `No update signal from server (${result.serverError}).`; this.update.statusType = 'secondary'; } else { this.update.statusText = 'This app is up to date.'; this.update.statusType = 'success'; } } catch (error) { const message = error instanceof Error ? error.message : 'Unknown update check error.'; this.update.statusText = `Update check failed: ${message}`; this.update.statusType = 'danger'; } finally { this.update.isChecking = false; } }, async applyUpdate() { if (!window.__loncApp?.applyAppUpdate) { this.update.statusText = 'Update action is not available in this browser.'; this.update.statusType = 'warning'; return; } this.update.isApplying = true; this.update.statusText = 'Applying update and refreshing app...'; this.update.statusType = 'warning'; try { await window.__loncApp.applyAppUpdate(); } catch (error) { const message = error instanceof Error ? error.message : 'Unknown update error.'; this.update.statusText = `Update failed: ${message}`; this.update.statusType = 'danger'; this.update.isApplying = false; } }, }; }