Skip to content

Commit 0e41078

Browse files
author
FolderView Plus Test
committed
Refine Docker Orbit view layout
1 parent fb0ca9e commit 0e41078

9 files changed

Lines changed: 166 additions & 274 deletions

archive/folderview.plus-2026.04.15.26.txz.sha256

Lines changed: 0 additions & 1 deletion
This file was deleted.
-14 MB
Binary file not shown.

archive/folderview.plus-2026.04.15.27.txz.sha256

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bdcca6bfb4289fbcc23b4ad082dd0bd1875fcbe1b0aa744c82ac9e2ffa025eaf folderview.plus-2026.04.17.07.txz

folderview.plus.plg

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66
<!ENTITY launch "Settings/FolderViewPlus">
77
<!ENTITY plugdir "/usr/local/emhttp/plugins/&name;">
88
<!ENTITY pluginURL "https://raw.githubusercontent.com/&github;/dev/folderview.plus.plg">
9-
<!ENTITY version "2026.04.17.05">
10-
<!ENTITY md5 "e386a9b65c23d7270be1efc998727a66">
9+
<!ENTITY version "2026.04.17.07">
10+
<!ENTITY md5 "fe2b921cf12506977195f20b1a18d485">
1111
]>
1212

1313
<PLUGIN name="&name;" author="&author;" version="&version;" launch="&launch;" pluginURL="&pluginURL;" icon="folder-icon.png" support="https://forums.unraid.net/topic/197631-plugin-folderview-plus/" min="7.0.0">
1414
<CHANGES>
1515

16+
###2026.04.17.07
17+
- UX: Simplified Docker Orbit view by removing the top stats strip and left-side folder rail, leaving a cleaner centered stage plus inspector layout.
18+
- UX: Orbit member tiles now share the same surface treatment as the center folder and sit on a cleaner circular orbit with improved spacing and less aggressive highlight styling.
19+
20+
1621
###2026.04.17.05
1722
- Fix: Docker support-bundle snapshots, trace storage caps, and rendered-state diagnostics.
1823
- Fix: Docker runtime rows, folder state, and container interactions.

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/scripts/docker.runtime.orbit-view.js

Lines changed: 42 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@
475475
const baseCapacity = Math.max(4, Number(options.baseCapacity || 6));
476476
const capacityStep = Math.max(0, Number(options.capacityStep || 2));
477477
const angleOffset = Number(options.angleOffset || -90);
478+
const nodeDiameter = Math.max(80, Number(options.nodeDiameter || 120));
478479
const nodes = [];
479480
const rings = [];
480481
let index = 0;
@@ -500,7 +501,8 @@
500501
return {
501502
nodes,
502503
rings,
503-
lastRadius: rings.length ? rings[rings.length - 1].radius : Math.max(0, startRadius - ringStep)
504+
lastRadius: rings.length ? rings[rings.length - 1].radius : Math.max(0, startRadius - ringStep),
505+
nodeDiameter
504506
};
505507
};
506508

@@ -520,41 +522,6 @@
520522
root.innerHTML = `<div class="fv-docker-orbit-shell"><div class="fv-docker-orbit-empty"><h3>Orbit view failed to load</h3><p>${escapeHtml(message || 'Unknown error.')}</p><button type="button" class="fv-docker-orbit-button is-primary" data-fv-orbit-action="refresh">Retry</button></div></div>`;
521523
};
522524

523-
const renderNavigatorTree = (snapshot, folderModels) => {
524-
const rootIds = snapshot.orderedFolderIds.filter((folderId) => !snapshot.hierarchy.parentById?.[folderId]);
525-
const renderNode = (folderId) => {
526-
const model = folderModels[folderId];
527-
if (!model) {
528-
return '';
529-
}
530-
const selected = folderId === selectedFolderId;
531-
const children = Array.isArray(snapshot.hierarchy.childrenById?.[folderId])
532-
? snapshot.hierarchy.childrenById[folderId].filter((childId) => Object.prototype.hasOwnProperty.call(folderModels, childId))
533-
: [];
534-
return `
535-
<li class="fv-docker-orbit-nav-item">
536-
<button
537-
type="button"
538-
class="fv-docker-orbit-nav-button${selected ? ' is-selected' : ''}"
539-
data-fv-orbit-action="select-folder"
540-
data-folder-id="${escapeHtml(folderId)}"
541-
style="--fv-docker-orbit-depth:${Number(model.depth || 0)};"
542-
>
543-
<img src="${model.icon}" class="fv-docker-orbit-nav-icon" alt="" loading="lazy" onerror='this.src="${DEFAULT_FOLDER_ICON}"'>
544-
<span class="fv-docker-orbit-nav-copy">
545-
<span class="fv-docker-orbit-nav-name">${escapeHtml(model.name)}</span>
546-
<span class="fv-docker-orbit-nav-meta">${model.branchMemberCount} in branch${model.updates > 0 ? ` • ${model.updates} updates` : ''}</span>
547-
</span>
548-
</button>
549-
${children.length ? `<ul class="fv-docker-orbit-nav-branch">${children.map(renderNode).join('')}</ul>` : ''}
550-
</li>
551-
`;
552-
};
553-
return rootIds.length
554-
? `<ul class="fv-docker-orbit-nav-tree">${rootIds.map(renderNode).join('')}</ul>`
555-
: '<div class="fv-docker-orbit-nav-empty">No folders yet.</div>';
556-
};
557-
558525
const renderSnapshot = (snapshot) => {
559526
const root = ensureRoot();
560527
if (!(root instanceof HTMLElement)) {
@@ -594,30 +561,52 @@
594561
}
595562
const selectedMember = selectedMembers.find((member) => member.name === selectedMemberName) || null;
596563
const breadcrumbs = buildBreadcrumbs(selectedFolderId, snapshot, folderModels);
564+
const relatedFolderIds = (() => {
565+
if (selectedFolder.childIds.length) {
566+
return selectedFolder.childIds.slice();
567+
}
568+
if (selectedFolder.parentId) {
569+
return (snapshot.hierarchy.childrenById?.[selectedFolder.parentId] || [])
570+
.filter((folderId) => folderId !== selectedFolderId && Object.prototype.hasOwnProperty.call(folderModels, folderId));
571+
}
572+
return orderedIds
573+
.filter((folderId) => folderId !== selectedFolderId && !folderModels[folderId]?.parentId);
574+
})();
575+
const relatedFolders = relatedFolderIds
576+
.map((folderId) => folderModels[folderId])
577+
.filter(Boolean)
578+
.map((model) => ({
579+
folderId: model.folderId,
580+
name: model.name,
581+
icon: model.icon,
582+
count: model.branchMemberCount,
583+
running: model.running,
584+
updates: model.updates
585+
}));
597586
const memberOrbit = layoutOrbitNodes(selectedFolder.directMembers, {
598-
startRadius: 190,
599-
ringStep: 88,
600-
baseCapacity: 6,
587+
startRadius: 256,
588+
ringStep: 132,
589+
baseCapacity: 8,
601590
capacityStep: 2
602591
});
603-
const childOrbit = layoutOrbitNodes(selectedFolder.childFolders, {
604-
startRadius: Math.max(memberOrbit.lastRadius + 124, 320),
605-
ringStep: 102,
606-
baseCapacity: 8,
592+
const relatedFolderOrbit = layoutOrbitNodes(relatedFolders, {
593+
startRadius: Math.max(memberOrbit.lastRadius + 176, 420),
594+
ringStep: 148,
595+
baseCapacity: 10,
607596
capacityStep: 2
608597
});
609-
const stageRadius = Math.max(220, memberOrbit.lastRadius, childOrbit.lastRadius);
610-
const stageSize = Math.max(760, (stageRadius + 180) * 2);
611-
const ringMarkup = [...memberOrbit.rings, ...childOrbit.rings]
598+
const stageRadius = Math.max(
599+
260,
600+
memberOrbit.lastRadius + (memberOrbit.nodeDiameter / 2),
601+
relatedFolderOrbit.lastRadius + (relatedFolderOrbit.nodeDiameter / 2)
602+
);
603+
const stageSize = Math.max(920, (stageRadius * 2) + 260);
604+
const ringMarkup = [...memberOrbit.rings, ...relatedFolderOrbit.rings]
612605
.map((ring) => ring.radius)
613606
.filter((radius, index, values) => values.indexOf(radius) === index)
614607
.sort((left, right) => left - right)
615608
.map((radius) => `<div class="fv-docker-orbit-ring" style="width:${radius * 2}px;height:${radius * 2}px;"></div>`)
616609
.join('');
617-
const runtimeEntries = Object.values(snapshot.runtimeInfoByName || {});
618-
const cardsWithUpdates = orderedIds.filter((folderId) => folderModels[folderId]?.updates > 0).length;
619-
const runningContainers = runtimeEntries.filter((entry) => resolveContainerState(entry) === 'running').length;
620-
const updateReadyContainers = runtimeEntries.filter((entry) => containerHasUpdate(entry)).length;
621610
const inspectorBody = selectedMember ? `
622611
<div class="fv-docker-orbit-inspector-card is-member ${escapeHtml(selectedMember.stateMeta.state)}">
623612
<div class="fv-docker-orbit-inspector-head">
@@ -653,25 +642,14 @@
653642
<div class="fv-docker-orbit-header">
654643
<div class="fv-docker-orbit-header-copy">
655644
<h2>Docker Orbit View</h2>
656-
<p>Centered folder control with orbiting containers and child folders for faster branch navigation.</p>
645+
<p>Centered folder control with orbiting containers and related folders for faster branch navigation.</p>
657646
</div>
658647
<div class="fv-docker-orbit-toolbar">
659648
<button type="button" class="fv-docker-orbit-button" data-fv-orbit-action="refresh">Refresh</button>
660-
<button type="button" class="fv-docker-orbit-button is-primary" data-fv-orbit-action="create-folder">Add Folder</button>
649+
<button type="button" class="fv-docker-orbit-button" data-fv-orbit-action="create-folder">Add Folder</button>
661650
</div>
662651
</div>
663-
<div class="fv-docker-orbit-overview">
664-
<div class="fv-docker-orbit-overview-card"><span class="fv-docker-orbit-overview-value">${orderedIds.length}</span><span class="fv-docker-orbit-overview-label">folders</span></div>
665-
<div class="fv-docker-orbit-overview-card"><span class="fv-docker-orbit-overview-value">${runtimeEntries.length}</span><span class="fv-docker-orbit-overview-label">containers</span></div>
666-
<div class="fv-docker-orbit-overview-card"><span class="fv-docker-orbit-overview-value">${runningContainers}</span><span class="fv-docker-orbit-overview-label">running</span></div>
667-
<div class="fv-docker-orbit-overview-card"><span class="fv-docker-orbit-overview-value">${cardsWithUpdates}</span><span class="fv-docker-orbit-overview-label">folders with updates</span></div>
668-
<div class="fv-docker-orbit-overview-card"><span class="fv-docker-orbit-overview-value">${updateReadyContainers}</span><span class="fv-docker-orbit-overview-label">update ready</span></div>
669-
</div>
670652
<div class="fv-docker-orbit-layout">
671-
<aside class="fv-docker-orbit-nav">
672-
<div class="fv-docker-orbit-panel-title">Folders</div>
673-
${renderNavigatorTree(snapshot, folderModels)}
674-
</aside>
675653
<section class="fv-docker-orbit-main">
676654
<div class="fv-docker-orbit-breadcrumbs">
677655
${breadcrumbs.map((crumb, index) => `
@@ -727,7 +705,7 @@
727705
${member.updateReady ? '<span class="fv-docker-orbit-node-update">update</span>' : ''}
728706
</button>
729707
`).join('')}
730-
${childOrbit.nodes.map((child) => `
708+
${relatedFolderOrbit.nodes.map((child) => `
731709
<button
732710
type="button"
733711
class="fv-docker-orbit-node is-folder"

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/styles/docker.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,6 @@ body.fvplus-privacy-docker-runtime .fv-docker-tree-explorer-node-copy,
314314
body.fvplus-privacy-docker-runtime .fv-docker-tree-explorer-detail-title,
315315
body.fvplus-privacy-docker-runtime .fv-docker-tree-explorer-child-copy,
316316
body.fvplus-privacy-docker-runtime .fv-docker-tree-explorer-member-pill,
317-
body.fvplus-privacy-docker-runtime .fv-docker-orbit-nav-copy,
318317
body.fvplus-privacy-docker-runtime .fv-docker-orbit-folder-title,
319318
body.fvplus-privacy-docker-runtime .fv-docker-orbit-member-name,
320319
body.fvplus-privacy-docker-runtime .fv-docker-orbit-inspector-title {

0 commit comments

Comments
 (0)