Repair settings: dropdown for fixed-choice settings (canonical source_selection)
The canonical source_selection setting was rendering as a free-text box — easy
to typo an invalid mode. Added a generic choice mechanism so it's a dropdown:
- RepairJob.setting_options: {key: [allowed values]} (default {} — opt-in).
- CanonicalVersionResolveJob declares source_selection's three modes.
- repair_worker.get_all_job_info() includes setting_options in the job payload.
- enrichment.js renders a <select> (options prettified, current value selected)
for any key listed in setting_options; everything else renders by value type
as before. The save path already reads <select>.value as a string, so no
change needed there.
Generic — any future job can get dropdowns the same way. Jobs that don't
declare setting_options are untouched (empty dict -> existing input rendering).
Tests: source_selection exposes the 3 options and its default is one of them.
23 repair-job/worker + canonical tests pass (other jobs unaffected).
This commit is contained in:
parent
2fcdfd3145
commit
dfa5204e0a
5 changed files with 30 additions and 0 deletions
|
|
@ -100,6 +100,9 @@ class RepairJob(ABC):
|
|||
default_enabled: bool = False
|
||||
default_interval_hours: int = 24
|
||||
default_settings: Dict[str, Any] = {}
|
||||
# Optional {setting_key: [allowed values]} — the UI renders a dropdown for
|
||||
# these instead of a free-text box. Keys not listed render by value type.
|
||||
setting_options: Dict[str, list] = {}
|
||||
auto_fix: bool = False
|
||||
|
||||
@abstractmethod
|
||||
|
|
|
|||
|
|
@ -101,6 +101,10 @@ class CanonicalVersionResolveJob(RepairJob):
|
|||
# source matches the files best, regardless of which it is).
|
||||
'source_selection': 'active_preferred',
|
||||
}
|
||||
# Render source_selection as a dropdown (not a text box) in the settings UI.
|
||||
setting_options = {
|
||||
'source_selection': ['active_preferred', 'active_only', 'best_fit'],
|
||||
}
|
||||
auto_fix = True
|
||||
|
||||
def _get_settings(self, context: JobContext) -> dict:
|
||||
|
|
|
|||
|
|
@ -371,6 +371,9 @@ class RepairWorker:
|
|||
'interval_hours': config['interval_hours'],
|
||||
'settings': config['settings'],
|
||||
'default_settings': job.default_settings.copy(),
|
||||
# Per-setting choice lists so the UI can render a dropdown
|
||||
# instead of a free-text box (e.g. canonical source_selection).
|
||||
'setting_options': dict(getattr(job, 'setting_options', {}) or {}),
|
||||
'last_run': last_run,
|
||||
'next_run': next_run,
|
||||
'is_running': self._current_job_id == job_id,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ def test_source_selection_defaults_to_active_preferred():
|
|||
assert CanonicalVersionResolveJob.default_settings["source_selection"] == "active_preferred"
|
||||
|
||||
|
||||
def test_source_selection_exposes_dropdown_options():
|
||||
# The UI renders a <select> for keys listed in setting_options.
|
||||
opts = CanonicalVersionResolveJob.setting_options.get("source_selection")
|
||||
assert opts == ["active_preferred", "active_only", "best_fit"]
|
||||
# default must be one of the offered options
|
||||
assert CanonicalVersionResolveJob.default_settings["source_selection"] in opts
|
||||
|
||||
|
||||
def test_describe_pin_is_judgeable():
|
||||
desc = _describe_pin({
|
||||
"source": "deezer", "album_id": "665666731", "score": 1.0,
|
||||
|
|
|
|||
|
|
@ -1705,6 +1705,18 @@ async function loadRepairJobs() {
|
|||
return `<div class="repair-setting-section">${val}</div>`;
|
||||
}
|
||||
const label = _prettifyRepairSettingKey(key);
|
||||
// Dropdown when the job declares allowed values for this key.
|
||||
const opts = job.setting_options && job.setting_options[key];
|
||||
if (Array.isArray(opts) && opts.length) {
|
||||
const optionsHtml = opts.map(o =>
|
||||
`<option value="${o}"${o === val ? ' selected' : ''}>${_prettifyRepairSettingKey(String(o))}</option>`
|
||||
).join('');
|
||||
return `<div class="repair-setting-row">
|
||||
<label>${label}</label>
|
||||
<select class="repair-setting-input"
|
||||
data-job="${job.job_id}" data-key="${key}">${optionsHtml}</select>
|
||||
</div>`;
|
||||
}
|
||||
const inputType = typeof val === 'boolean' ? 'checkbox' :
|
||||
typeof val === 'number' ? 'number' : 'text';
|
||||
const inputVal = inputType === 'checkbox' ?
|
||||
|
|
|
|||
Loading…
Reference in a new issue