diff --git a/frontend/index.html b/frontend/index.html
index dc88fe8..b0f1832 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -1179,6 +1179,7 @@
+
@@ -23909,10 +23910,12 @@ function pysimServicesFsRender() {
async function pysimServicesFsCheck() {
const statusEl = document.getElementById('pysim-services-fs-status');
const reportEl = document.getElementById('pysim-services-fs-report');
+ const spinEl = document.getElementById('pysim-services-fs-spin');
if (_pysimServicesFsBusy || !reportEl) return;
const setStatus = text => { if (statusEl) statusEl.textContent = text; };
if (_pysimFsProbe) { setStatus(t('A file probe is already running')); return; }
_pysimServicesFsBusy = true;
+ if (spinEl) spinEl.classList.remove('hidden');
_pysimServicesFsReport = null;
reportEl.innerHTML = '';
setStatus(t('Loading...'));
@@ -23943,6 +23946,7 @@ async function pysimServicesFsCheck() {
esc(t('Error') + ': ' + ((e && e.message) ? e.message : String(e))) + '
';
} finally {
setStatus('');
+ if (spinEl) spinEl.classList.add('hidden');
_pysimServicesFsBusy = false;
}
}
diff --git a/frontend/tests/services.test.js b/frontend/tests/services.test.js
index 6771b1d..4afab5d 100644
--- a/frontend/tests/services.test.js
+++ b/frontend/tests/services.test.js
@@ -666,6 +666,7 @@ test('the Services pill carries the Check filesystem action and its report panel
assert.match(pill, /id="pysim-services-fs-btn"[^>]*data-needs="card"[^>]*onclick="pysimServicesFsCheck\(\)"/);
assert.match(pill, /data-l10n="Check filesystem"/);
assert.match(pill, /id="pysim-services-fs-status"/);
+ assert.match(pill, /id="pysim-services-fs-spin"[^>]*class="hidden animate-spin/);
assert.match(pill, /id="pysim-services-fs-report"/);
});
@@ -680,6 +681,10 @@ test('the check probes the tree once per loaded session and keeps the report acr
const fn = extractFunc(html, 'pysimServicesFsCheck');
assert.ok(fn.indexOf('await pysimFsRefresh()') > 0, fn);
assert.ok(fn.indexOf('await pysimFsProbeAll()') > 0, fn);
+ // a throbber shows while the scan runs and hides when it settles
+ assert.ok(fn.indexOf('pysim-services-fs-spin') > 0, fn);
+ assert.ok(fn.indexOf("spinEl.classList.remove('hidden')") > 0, fn);
+ assert.ok(fn.indexOf("spinEl.classList.add('hidden')") > 0, fn);
assert.ok(fn.indexOf('servicesFsDeclaredTrees(cache.files)') > 0, fn);
assert.ok(fn.indexOf('await servicesPathIndex()') > 0, fn);
assert.ok(fn.indexOf('index.size') > 0, 'an unloadable list is an error, not a wall of unchecked rows');