Summary
Introduce a unified Preferences dialog for DataLab-Web, mirroring DataLab Qt's settings system. Accessible from File > Preferences… (consistent with the desktop application).
Motivation
A handful of behaviours are already configurable through ad-hoc UI bits (theme toggle, HDF5 import flags, Results tab auto-switch). As the number of tunable behaviours grows, a single discoverable entry point becomes worthwhile.
When to implement
Implement this once ~8–10 preferences are genuinely worth exposing and wiring to runtime behaviour. Below that threshold, prefer inline controls (theme toggle in the menu bar, checkbox in the HDF5 import dialog, etc.).
Candidates ordered by perceived value:
| Option |
Category |
Effect to wire |
| Colour mode (auto / light / dark) |
general |
ThemeProvider.setMode |
| Auto-switch to Results tab after analysis |
proc |
App-level side panel switch |
| Clear workspace before HDF5 import |
io |
h5_browser_import |
| Use full HDF5 path as object title |
io |
import_nodes |
| Append HDF5 file name to object title |
io |
import_nodes |
| Auto-downsampling of large signals |
view |
Plotly backend threshold |
| Lock image aspect ratio to 1:1 |
view |
Plotly yaxis.scaleanchor |
| Eliminate outliers on image import |
view |
Percentile clip |
| FFT shift by default |
proc |
Default param in FFT wrapper |
| Auto-normalise convolution kernels |
proc |
Default param in convolution |
| Console log level |
console |
console.* wrapper |
| Keep analysis results in metadata |
proc |
Metadata purge policy |
| Pairwise n→1 mode |
proc |
⚠ requires implementing the dispatch in processor.py first |
Design
- Python source of truth: one
guidata.dataset.DataSet subclass per category, with a category_id class attribute. The JSON schema is produced via dataset_to_schema_with_values and rendered by the existing DataSetForm.
- Persistence: a single JSON blob in
localStorage under datalab-web:preferences, namespaced by category_id. Persist only diffs vs defaults, so future default changes propagate naturally.
- Runtime coupling: a
PreferencesProvider loads from localStorage on mount, pushes overrides to Pyodide once runtime.status === "ready", and mirrors general.color_mode to ThemeProvider.setMode (with auto → system mapping).
- Menu entry: File > Preferences… (match DataLab Qt; not
Edit).
- Dialog: left-rail tab layout with fixed dimensions (e.g.
width: 720, content area height: 320, overflowY: auto) so the action buttons don't reflow when switching tabs. Selected tab styled with var(--accent) + white text, like menu items.
- Buttons: Export… / Import… / Restore defaults / Cancel / OK.
- JSON export: export the full effective state (defaults + overrides + unsaved edits), not the diff — otherwise an untouched configuration produces
{} and re-import isn't deterministic across default changes.
- JSON import: validate the root shape, drop unknown categories with a user-visible warning, filter unknown keys server-side.
Acceptance criteria
References
- Qt implementation:
datalab/gui/settings.py (DataLab desktop)
Summary
Introduce a unified Preferences dialog for DataLab-Web, mirroring DataLab Qt's settings system. Accessible from File > Preferences… (consistent with the desktop application).
Motivation
A handful of behaviours are already configurable through ad-hoc UI bits (theme toggle, HDF5 import flags, Results tab auto-switch). As the number of tunable behaviours grows, a single discoverable entry point becomes worthwhile.
When to implement
Implement this once ~8–10 preferences are genuinely worth exposing and wiring to runtime behaviour. Below that threshold, prefer inline controls (theme toggle in the menu bar, checkbox in the HDF5 import dialog, etc.).
Candidates ordered by perceived value:
generalThemeProvider.setModeprocioh5_browser_importioimport_nodesioimport_nodesviewviewyaxis.scaleanchorviewprocprocconsoleconsole.*wrapperprocprocprocessor.pyfirstDesign
guidata.dataset.DataSetsubclass per category, with acategory_idclass attribute. The JSON schema is produced viadataset_to_schema_with_valuesand rendered by the existingDataSetForm.localStorageunderdatalab-web:preferences, namespaced bycategory_id. Persist only diffs vs defaults, so future default changes propagate naturally.PreferencesProviderloads fromlocalStorageon mount, pushes overrides to Pyodide onceruntime.status === "ready", and mirrorsgeneral.color_modetoThemeProvider.setMode(withauto → systemmapping).Edit).width: 720, content areaheight: 320,overflowY: auto) so the action buttons don't reflow when switching tabs. Selected tab styled withvar(--accent)+ white text, like menu items.{}and re-import isn't deterministic across default changes.Acceptance criteria
try: _PREFS except NameError: …).References
datalab/gui/settings.py(DataLab desktop)