feat(deploy): reliability API routes, atomic releases, version single-source
This commit is contained in:
@@ -269,7 +269,7 @@
|
||||
<script src="js/xterm-addon-fit.min.js"></script>
|
||||
<script src="js/terminal.js?v=20260820-4"></script>
|
||||
<script src="js/pager.js?v=20260820-4"></script>
|
||||
<script src="js/views.js?v=20260822-1"></script>
|
||||
<script src="js/views.js?v=20260822-2"></script>
|
||||
<script src="js/app.js?v=20260822-1"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3920,6 +3920,43 @@ views.settings = (root) => {
|
||||
overlay.appendChild(restoreBtn);
|
||||
loadOverlay();
|
||||
|
||||
const profiles = settingsCard(box, 'Reliability Profiles',
|
||||
'Snapshots of the PineAP, wireless, and network UCI config. Save one before risky changes; restoring rolls the config back and reloads the radios.');
|
||||
const profBody = h('div', { class: 'settings-table-wrap', text: 'Loading…' });
|
||||
profiles.appendChild(profBody);
|
||||
function loadProfiles() {
|
||||
PagerAPI.get('/api/reliability/profiles').then((r) => {
|
||||
const names = (r.data || {}).profiles || [];
|
||||
profBody.innerHTML = '';
|
||||
if (!names.length) {
|
||||
profBody.appendChild(h('div', { class: 'empty', text: 'No saved profiles yet.' }));
|
||||
return;
|
||||
}
|
||||
profBody.appendChild(table([
|
||||
{ label: 'Profile', key: 'name' },
|
||||
{ label: '', render: (row) => {
|
||||
const doRestore = btn('Restore', () => runAction(doRestore,
|
||||
() => PagerAPI.post('/api/reliability/restore', { name: row.name })
|
||||
.then(() => App.toast('Profile restored; radios reloaded')), 'Restoring…'), 'ghost');
|
||||
return doRestore;
|
||||
} }
|
||||
], names.map((name) => ({ name }))));
|
||||
}).catch(() => { profBody.textContent = 'Unable to load profiles.'; });
|
||||
}
|
||||
const profName = h('input', { placeholder: 'e.g. pre-evilwpa', maxlength: '64',
|
||||
autocomplete: 'off' });
|
||||
const profSave = btn('Save Profile', () => {
|
||||
const name = profName.value.trim();
|
||||
if (!name) { App.toast('Profile name is required', 'error'); return; }
|
||||
return runAction(profSave, () => PagerAPI.post('/api/reliability/profile', { name })
|
||||
.then(() => { profName.value = ''; App.toast('Config profile saved'); loadProfiles(); }), 'Saving…');
|
||||
});
|
||||
profiles.appendChild(h('div', { class: 'settings-form-grid' },
|
||||
h('label', {}, 'Profile Name', profName)));
|
||||
profiles.appendChild(h('div', { class: 'settings-actions' }, profSave,
|
||||
btn('Refresh', () => { loadProfiles(); }, 'ghost')));
|
||||
loadProfiles();
|
||||
|
||||
settingsCard(box, 'Button Script', 'The Mark VII button script has no safe Pager equivalent. Pager buttons remain managed by the native input and payload-launcher system.');
|
||||
|
||||
const resources = settingsCard(box, 'Resources');
|
||||
|
||||
Reference in New Issue
Block a user