file manager: expand/collapse all + auto-expand on filter

- "Expand all" / "Collapse all" links in the sort row: expand-all walks
  the directory tree loading children on demand (skipping DFs the probe
  found absent), collapse-all resets every directory.
- Selecting any filter but "All" auto-expands the tree so the matched
  files are visible (pysimFsAutoExpandForFilter, wired into the two
  filter setters).
- i18n EN/RU for the two links.

Frontend 1163 tests green (+2).  (Version/sw bump still deferred.)
This commit is contained in:
catarrh committed 2026-10-26 15:05:49 +03:00
1 parent cc7c23a9c7
commit 4a4232de5c
3 files changed
+95 -6

No files matched your search

+43
View File
@@ -1117,6 +1117,9 @@
<span data-l10n="Sort:">Sort:</span>
<span class="pysim-fs-sort-pill px-2 py-0.5 rounded cursor-pointer bg-blue-600 text-white" data-fs-sort="fid" onclick="pysimFsSetSort('fid')">FID</span>
<span class="pysim-fs-sort-pill px-2 py-0.5 rounded cursor-pointer bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300" data-fs-sort="name" onclick="pysimFsSetSort('name')" data-l10n="Name">Name</span>
<span class="mx-1 text-gray-400 dark:text-slate-600">·</span>
<button type="button" onclick="pysimFsExpandAll()" class="text-xs text-blue-600 dark:text-blue-400 hover:underline" data-l10n="Expand all">Expand all</button>
<button type="button" onclick="pysimFsCollapseAll()" class="text-xs text-blue-600 dark:text-blue-400 hover:underline" data-l10n="Collapse all">Collapse all</button>
</div>
<div class="flex items-center gap-1 mb-1 text-gray-500 dark:text-slate-400">
<span data-l10n="Filter:">Filter:</span>
@@ -16339,6 +16342,7 @@ function pysimFsFilterSetEntry(entry, on) {
localStorage.setItem('simple_fs_filter', JSON.stringify(Array.from(pysimFsFilter)));
pysimFsFilterRender();
pysimFsRenderTree();
pysimFsAutoExpandForFilter();
}
// The cross-reference inverted to service number -> feature name, per file
@@ -16382,6 +16386,7 @@ function pysimFsSetFilterToService(table, n) {
localStorage.setItem('simple_fs_filter', JSON.stringify(Array.from(pysimFsFilter)));
pysimFsFilterRender();
pysimFsRenderTree();
pysimFsAutoExpandForFilter();
}
// Whether a file node passes the active filter. An empty selection and
@@ -16684,6 +16689,42 @@ async function pysimFsToggleDir(path) {
if (node.expanded) pysimRefresh();
}
// Expand every directory that exists (skipping ones the probe already found
// absent), loading children on demand. Also the auto-action after a filter
// narrows to a specific category, so the matched files are visible.
async function pysimFsExpandAll() {
const stack = [pysimFsTreeRoot];
while (stack.length) {
const node = stack.pop();
if (!node || !node.isDir) continue;
if (node.exists === false) continue;
if (!node.children) {
await pysimFsLoadChildren(node);
if (node.exists === false) continue;
}
node.expanded = true;
for (const c of (node.children || [])) if (c.isDir) stack.push(c);
}
pysimFsRenderTree();
}
function pysimFsCollapseAll() {
const stack = [pysimFsTreeRoot];
while (stack.length) {
const node = stack.pop();
if (!node || !node.isDir) continue;
node.expanded = false;
for (const c of (node.children || [])) if (c.isDir) stack.push(c);
}
pysimFsRenderTree();
}
// A filter that narrows to a specific category expands the tree so the
// matched files are shown; "All"/empty leaves the tree as-is.
function pysimFsAutoExpandForFilter() {
if (pysimFsFilter.size > 0 && !pysimFsFilter.has(FS_FILTER_ALL)) pysimFsExpandAll();
}
let pysimFsSelected = null;
function pysimFsInfoHtml(sel, name, opts) {
@@ -28074,6 +28115,8 @@ const LANG_RU = {
'CB-related': 'Связанное с CB',
'Custom files': 'Пользовательские файлы',
'Selected: {n}': 'Выбрано: {n}',
'Expand all': 'Развернуть все',
'Collapse all': 'Свернуть все',
'Probe all files': 'Проверить все файлы',
'Feature': 'Функция',
'SST': 'SST',