Skip to content

Commit c52d831

Browse files
feat: show started/paused/stopped folder state totals
1 parent 41b5936 commit c52d831

4 files changed

Lines changed: 62 additions & 20 deletions

File tree

185 KB
Binary file not shown.

folderview.plus.plg

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,20 @@
66
<!ENTITY launch "Settings/FolderViewPlus">
77
<!ENTITY plugdir "/usr/local/emhttp/plugins/&name;">
88
<!ENTITY pluginURL "https://raw.githubusercontent.com/&github;/main/folderview.plus.plg">
9-
<!ENTITY version "2026.03.05.7">
10-
<!ENTITY md5 "25a9ae78f4bb55c1283543a9f5d25d9f">
9+
<!ENTITY version "2026.03.05.8">
10+
<!ENTITY md5 "c4ca972ced30d8cab3c4ac07354a9b07">
1111
]>
1212

1313
<PLUGIN name="&name;" author="&author;" version="&version;" launch="&launch;" pluginURL="&pluginURL;" icon="folder-open-o" support="https://github.com/alexphillips-dev/FolderView-Plus/issues" min="7.0.0">
1414
<CHANGES>
1515

16+
###2026.03.05.8
17+
- Improve folder status labels to show explicit state totals:
18+
- `X/N started` when any items are running,
19+
- `X/N paused` when none are running but one or more are paused/suspended,
20+
- `X/N stopped` when all items are stopped.
21+
- Apply the same status logic to both Docker and VM folder views.
22+
1623
###2026.03.05.7
1724
- Fix folder status display so fully stopped folders still show `0/N started` instead of appearing blank when the stopped badge is disabled.
1825
- Keep badge toggles functional while preserving readable status text in Docker and VM views.

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/scripts/docker.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ const createFolder = (folder, id, positionInMainOrder, liveOrderArray, container
221221
// Default variables
222222
let upToDate = true;
223223
let started = 0;
224+
let paused = 0;
225+
let stopped = 0;
224226
let autostart = 0;
225227
let autostartStarted = 0;
226228
let managed = 0;
@@ -928,7 +930,15 @@ const createFolder = (folder, id, positionInMainOrder, liveOrderArray, container
928930
}
929931

930932
upToDate = upToDate && !newFolder[container_name_in_folder].update;
931-
started += newFolder[container_name_in_folder].state ? 1 : 0;
933+
if (newFolder[container_name_in_folder].state) {
934+
if (newFolder[container_name_in_folder].pause) {
935+
paused += 1;
936+
} else {
937+
started += 1;
938+
}
939+
} else {
940+
stopped += 1;
941+
}
932942
const isDockerMan = ct.info.State.manager === 'dockerman';
933943
autostart += (isDockerMan && !(ct.info.State.Autostart === false)) ? 1 : 0;
934944
autostartStarted += (isDockerMan && !(ct.info.State.Autostart === false) && newFolder[container_name_in_folder].state) ? 1 : 0;
@@ -1011,28 +1021,35 @@ const createFolder = (folder, id, positionInMainOrder, liveOrderArray, container
10111021
$(`tr.folder-id-${id} > td.updatecolumn`).append($(`<a class="exec" onclick="updateFolder('${id}');"><span style="white-space:nowrap;"><i class="fa fa-cloud-download fa-fw"></i> ${$.i18n('apply-update')}</span></a>`));
10121022
if (FOLDER_VIEW_DEBUG_MODE) console.log(`[FV3_DEBUG] createFolder (id: ${id}): Set 'update ready' status in update column.`);
10131023
}
1014-
if (started) {
1024+
const total = Object.entries(folder.containers).length;
1025+
let folderStatusKind = 'stopped';
1026+
if (started > 0) {
1027+
folderStatusKind = 'running';
10151028
$(`tr.folder-id-${id} i#load-folder-${id}`).attr('class', 'fa fa-play started green-text folder-load-status');
1016-
$(`tr.folder-id-${id} span.folder-state`).text(`${started}/${Object.entries(folder.containers).length} ${$.i18n('started')}`);
1017-
if (FOLDER_VIEW_DEBUG_MODE) console.log(`[FV3_DEBUG] createFolder (id: ${id}): Set 'started' status. Count: ${started}/${Object.entries(folder.containers).length}.`);
1029+
$(`tr.folder-id-${id} span.folder-state`).text(`${started}/${total} ${$.i18n('started')}`);
1030+
} else if (paused > 0) {
1031+
folderStatusKind = 'paused';
1032+
$(`tr.folder-id-${id} i#load-folder-${id}`).attr('class', 'fa fa-pause paused orange-text folder-load-status');
1033+
$(`tr.folder-id-${id} span.folder-state`).text(`${paused}/${total} ${$.i18n('paused')}`);
1034+
} else {
1035+
folderStatusKind = 'stopped';
1036+
$(`tr.folder-id-${id} i#load-folder-${id}`).attr('class', 'fa fa-square stopped red-text folder-load-status');
1037+
$(`tr.folder-id-${id} span.folder-state`).text(`${stopped}/${total} ${$.i18n('stopped')}`);
10181038
}
10191039
const badgePrefs = folderTypePrefs?.badges || {};
10201040
const showRunningBadge = badgePrefs.running !== false;
10211041
const showStoppedBadge = badgePrefs.stopped === true;
10221042
const showUpdateBadge = badgePrefs.updates !== false;
1023-
const folderIsRunning = started > 0;
10241043

10251044
if (!showUpdateBadge && !folder.settings.update_column) {
10261045
$(`tr.folder-id-${id} > td.updatecolumn`).next().attr('colspan', 6).end().remove();
10271046
}
10281047

1029-
if (folderIsRunning && !showRunningBadge) {
1048+
if (folderStatusKind === 'running' && !showRunningBadge) {
10301049
$(`tr.folder-id-${id} i#load-folder-${id}`).hide();
10311050
}
1032-
if (!folderIsRunning && !showStoppedBadge) {
1033-
const total = Object.entries(folder.containers).length;
1051+
if (folderStatusKind === 'stopped' && !showStoppedBadge) {
10341052
$(`tr.folder-id-${id} i#load-folder-${id}`).hide();
1035-
$(`tr.folder-id-${id} span.folder-state`).text(`${started}/${total} ${$.i18n('started')}`);
10361053
}
10371054

10381055
if (!managerTypes.has('dockerman')) {
@@ -1057,7 +1074,7 @@ const createFolder = (folder, id, positionInMainOrder, liveOrderArray, container
10571074
else if (managed > 0 && managed === Object.values(folder.containers).length) { $(`tr.folder-id-${id}`).addClass('managed-full'); }
10581075
if (FOLDER_VIEW_DEBUG_MODE) console.log(`[FV3_DEBUG] createFolder (id: ${id}): Applied managed status class. Managed: ${managed}, Total: ${Object.values(folder.containers).length}.`);
10591076

1060-
folder.status = { upToDate, started, autostart, autostartStarted, managed, managerTypes: Array.from(managerTypes), expanded: false };
1077+
folder.status = { upToDate, started, paused, stopped, autostart, autostartStarted, managed, managerTypes: Array.from(managerTypes), expanded: false };
10611078
if (FOLDER_VIEW_DEBUG_MODE) console.log(`[FV3_DEBUG] createFolder (id: ${id}): Set final folder.status object:`, JSON.parse(JSON.stringify(folder.status)));
10621079
if (FOLDER_VIEW_DEBUG_MODE) console.log(`[FV3_DEBUG] createFolder (id: ${id}): Dispatching docker-post-folder-creation event.`);
10631080
folderEvents.dispatchEvent(new CustomEvent('docker-post-folder-creation', {detail: {

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/scripts/vm.js

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ const createFolder = (folder, id, position, order, vmInfo, foldersDone) => {
141141

142142
// default varibles
143143
let started = 0;
144+
let paused = 0;
145+
let stopped = 0;
144146
let autostart = 0;
145147
let autostartStarted = 0;
146148
let remBefore = 0;
@@ -312,7 +314,13 @@ const createFolder = (folder, id, position, order, vmInfo, foldersDone) => {
312314
}
313315

314316
// set the status of the folder
315-
started += ct.state!=="shutoff" ? 1 : 0;
317+
if (ct.state === "running") {
318+
started += 1;
319+
} else if (ct.state === "paused" || ct.state === "pmsuspended" || ct.state === "unknown") {
320+
paused += 1;
321+
} else {
322+
stopped += 1;
323+
}
316324
autostart += ct.autostart ? 1 : 0;
317325
autostartStarted += (ct.autostart && ct.state!=="shutoff") ? 1 : 0;
318326

@@ -352,21 +360,29 @@ const createFolder = (folder, id, position, order, vmInfo, foldersDone) => {
352360

353361
//set tehe status of a folder
354362

355-
if (started) {
363+
const total = Object.entries(folder.containers).length;
364+
let folderStatusKind = 'stopped';
365+
if (started > 0) {
366+
folderStatusKind = 'running';
356367
$(`tr.folder-id-${id} i#load-folder-${id}`).attr('class', 'fa fa-play started green-text folder-load-status');
357-
$(`tr.folder-id-${id} span.folder-state`).text(`${started}/${Object.entries(folder.containers).length} ${$.i18n('started')}`);
368+
$(`tr.folder-id-${id} span.folder-state`).text(`${started}/${total} ${$.i18n('started')}`);
369+
} else if (paused > 0) {
370+
folderStatusKind = 'paused';
371+
$(`tr.folder-id-${id} i#load-folder-${id}`).attr('class', 'fa fa-pause paused orange-text folder-load-status');
372+
$(`tr.folder-id-${id} span.folder-state`).text(`${paused}/${total} ${$.i18n('paused')}`);
373+
} else {
374+
folderStatusKind = 'stopped';
375+
$(`tr.folder-id-${id} i#load-folder-${id}`).attr('class', 'fa fa-square stopped red-text folder-load-status');
376+
$(`tr.folder-id-${id} span.folder-state`).text(`${stopped}/${total} ${$.i18n('stopped')}`);
358377
}
359378
const badgePrefs = folderTypePrefs?.badges || {};
360379
const showRunningBadge = badgePrefs.running !== false;
361380
const showStoppedBadge = badgePrefs.stopped === true;
362-
const folderIsRunning = started > 0;
363-
if (folderIsRunning && !showRunningBadge) {
381+
if (folderStatusKind === 'running' && !showRunningBadge) {
364382
$(`tr.folder-id-${id} i#load-folder-${id}`).hide();
365383
}
366-
if (!folderIsRunning && !showStoppedBadge) {
367-
const total = Object.entries(folder.containers).length;
384+
if (folderStatusKind === 'stopped' && !showStoppedBadge) {
368385
$(`tr.folder-id-${id} i#load-folder-${id}`).hide();
369-
$(`tr.folder-id-${id} span.folder-state`).text(`${started}/${total} ${$.i18n('started')}`);
370386
}
371387

372388

@@ -389,6 +405,8 @@ const createFolder = (folder, id, position, order, vmInfo, foldersDone) => {
389405
// set the status
390406
folder.status = {};
391407
folder.status.started = started;
408+
folder.status.paused = paused;
409+
folder.status.stopped = stopped;
392410
folder.status.autostart = autostart;
393411
folder.status.autostartStarted = autostartStarted;
394412
folder.status.expanded = false;

0 commit comments

Comments
 (0)