fix(regions): allow clearing the default region in Region Registry

Click the already-selected radio to clear the default; new
DELETE /api/regions/default endpoint also pushes an empty CMD 63 to
the firmware so its persistent default is wiped too.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-04-24 21:39:17 +02:00
parent e293de2a76
commit d77d86087d
3 changed files with 71 additions and 2 deletions

View File

@@ -4070,6 +4070,43 @@ def set_channel_scope_api(index):
return jsonify({'success': False, 'error': str(e)}), 500
@api_bp.route('/regions/default', methods=['DELETE'])
def clear_default_region_api():
"""Clear the default-region flag in the DB and the firmware default (CMD 63).
If the firmware push fails the DB flag is still cleared; we return 200 with
a non-blocking `warning` so the UI can toast it.
"""
try:
db = _get_db()
if not db:
return jsonify({'success': False, 'error': 'Database not available'}), 500
had_default = db.get_default_region() is not None
db.set_default_region(None)
warning = None
if had_default:
dm = _get_dm()
if dm and dm.is_connected:
try:
res = dm.set_default_flood_scope('', '')
if not res.get('success'):
warning = f"{res.get('error')} Your choice is saved locally."
except Exception as e:
warning = f"Could not clear firmware default: {e}. Your choice is saved locally."
else:
warning = 'Device disconnected — choice saved locally; firmware default not updated.'
out = {'success': True}
if warning:
out['warning'] = warning
return jsonify(out), 200
except Exception as e:
logger.error(f"Error clearing default region: {e}")
return jsonify({'success': False, 'error': str(e)}), 500
@api_bp.route('/regions/<int:region_id>/default', methods=['POST'])
def set_default_region_api(region_id):
"""Mark a region as default in the DB AND push it to the firmware (CMD 63).

View File

@@ -2871,7 +2871,8 @@ function renderRegionsList() {
<div class="form-check mb-0">
<input class="form-check-input" type="radio" name="regionDefault"
id="regionDefault_${r.id}" ${isDefault}
onchange="setDefaultRegion(${r.id})">
title="Click again to clear the default"
onclick="handleRegionRadioClick(${r.id}, this)">
</div>
<div class="flex-grow-1">
<div><strong>${escapeHtml(r.name)}</strong></div>
@@ -2927,6 +2928,17 @@ async function deleteRegion(id, name) {
}
}
function handleRegionRadioClick(id, inputEl) {
// Click on the already-selected default clears the default; otherwise sets it.
const wasDefault = (window.regionRegistry || []).some(r => r.id === id && r.is_default);
if (wasDefault) {
inputEl.checked = false;
clearDefaultRegion();
} else {
setDefaultRegion(id);
}
}
async function setDefaultRegion(id) {
try {
const resp = await fetch(`/api/regions/${id}/default`, { method: 'POST' });
@@ -2948,6 +2960,26 @@ async function setDefaultRegion(id) {
}
}
async function clearDefaultRegion() {
try {
const resp = await fetch('/api/regions/default', { method: 'DELETE' });
const data = await resp.json().catch(() => ({}));
if (!resp.ok || !data.success) {
showNotification(data.error || 'Failed to clear default region', 'danger');
await loadRegions(); // snap UI back to server truth
return;
}
if (data.warning) {
showNotification(data.warning, 'warning');
}
(window.regionRegistry || []).forEach(r => { r.is_default = 0; });
} catch (e) {
console.error('Error clearing default region:', e);
showNotification('Network error clearing default', 'danger');
await loadRegions();
}
}
// ================================================================
// Per-channel region picker (Manage Channels > row > pin icon)
// ================================================================

View File

@@ -792,7 +792,7 @@
</div>
</form>
<div class="form-text small">
Tip: pick the default region via the radio button. The default is also pushed to the firmware so any untagged channel uses it.
Tip: pick the default region via the radio button. Click the selected radio again to clear it. The default is also pushed to the firmware so any untagged channel uses it.
</div>
</div>
</div>