From 3ebd4ee5bbe2c157966d78268b135898b01c237d Mon Sep 17 00:00:00 2001 From: librelad Date: Wed, 19 Aug 2026 23:50:11 +0100 Subject: [PATCH] fix(webui): tell a deliberate singleton from an un-reviewed app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The instances line had two states where there are three. An app with a blocker cannot be instanced; an app whose flag is explicitly false was reviewed and deliberately kept to one — the resolver clients point at, the auth provider every router points at, the scanner the updater resolves by a fixed container name; an app with no flag has simply never been looked at. Collapsing the middle case into the last reported a decision as an oversight, and invited someone to "fix" it by flipping the flag. Those apps now read "Not offered" and point at the reason recorded above the flag in their config, rather than "not been opted in". Co-Authored-By: Claude Opus 5 --- .../components/apps/core/js/apps-grid.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/containers/libreportal/frontend/components/apps/core/js/apps-grid.js b/containers/libreportal/frontend/components/apps/core/js/apps-grid.js index 88c3cd0..d0d063a 100644 --- a/containers/libreportal/frontend/components/apps/core/js/apps-grid.js +++ b/containers/libreportal/frontend/components/apps/core/js/apps-grid.js @@ -378,11 +378,23 @@ Object.assign(AppsManager.prototype, { + `(${shown}${unprefixed.length > 4 ? `, +${unprefixed.length - 4} more` : ''}) ` + `— those names cannot be made unique per instance`); } - const short = bits.length ? 'Not available' : 'Not enabled'; + // Three states, not two. An app with a blocker cannot be instanced; an app + // with the flag explicitly false was reviewed and deliberately left off + // (a singleton by role — the resolver clients point at, the auth provider + // every router points at, the scanner the updater resolves by a fixed + // container name); an app with no flag at all has simply never been + // looked at. Collapsing the middle case into the last one reports a + // decision as an oversight. + const decided = typeCfg[`CFG_${U(type)}_MULTI_INSTANCE`] !== undefined; + const short = bits.length ? 'Not available' : (decided ? 'Not offered' : 'Not enabled'); const tip = bits.length ? `${typeTitleEarly} ${bits.join('; and ')}.` - : `${typeTitleEarly} has no technical blocker — it simply has not been opted in. ` - + `Set CFG_${U(type)}_MULTI_INSTANCE=true on a reviewed app to allow it.`; + : decided + ? `${typeTitleEarly} could run as multiple instances, but is deliberately kept to one — ` + + `it is infrastructure the rest of the box points at. See the note above ` + + `CFG_${U(type)}_MULTI_INSTANCE in its config for the specific reason.` + : `${typeTitleEarly} has no technical blocker — it simply has not been opted in. ` + + `Set CFG_${U(type)}_MULTI_INSTANCE=true on a reviewed app to allow it.`; return `
Instances