fix(ui): name the missing provider key on a key-gated layer row (#575)

Supersedes #296 by @Matthew-Selvam, ported onto the current component layout with fixes from review.

Verified before merge: format, package boundaries, unit suite, build, and the browser tracking suite; a browser harness for the change where one applies; adversarial review applied.

Co-authored-by: Matthew-Selvam <[email protected]>
This commit is contained in:
Bilawal SidhuandMatthew-Selvam authored and GitHub committed 2026-09-14 21:26:09 -05:00
1 parent 7fa0cfbb26
commit 6fa25c349a
8 files changed
+206 -3

No files matched your search

+32 -1
View File
@@ -1,4 +1,5 @@
import { GUIDANCE_STATUSES } from '../loadingFeedback.js';
import { keySetupRequirement } from '../keySetupCore.mjs';
const FEED_STATE_LABELS = Object.freeze({
nominal: 'ON',
loading: 'LOADING',
@@ -8,6 +9,26 @@ const FEED_STATE_LABELS = Object.freeze({
unavailable: 'UNAVAILABLE',
});
/**
* Guidance for a control a missing provider key is holding back.
*
* The key registry already owns what each key is called and which environment
* variables enable it, so a layer only declares WHICH key it needs
* (`requiresKeyId`) and reports `stats.keyRequired` while that key is absent.
* Naming the variable turns an unexplained dead control into a next step.
*
* An unnamed or unknown key returns '' rather than guessing: guidance naming
* the wrong variable sends the operator to the wrong provider.
*
* @param {object} [layer] Row from the layer manager's getAll().
* @returns {string} Guidance text, or '' when no key guidance applies.
*/
export function layerKeyRequirementTooltip(layer = {}) {
if (layer?.stats?.keyRequired !== true) return '';
const requiresKeyId = String(layer.requiresKeyId || '').trim();
return requiresKeyId ? keySetupRequirement(requiresKeyId) : '';
}
/**
* Normalize heterogeneous layer stats into one honest control-chip state.
* @param {object|null} stats Layer getStats() result.
@@ -511,7 +532,17 @@ export class LayerPanel {
: layer.enabled
? FEED_STATE_LABELS[feedState]
: 'OFF';
button.setAttribute('aria-label', `${layer.name}: ${button.textContent}`);
const keyGuidance = layerKeyRequirementTooltip(layer);
// Name the missing key on the control itself: a row reading KEY REQUIRED
// without saying WHICH key leaves a dead control and no next step. Empty
// when the layer needs no key, or already has one.
button.title = keyGuidance;
button.setAttribute(
'aria-label',
keyGuidance
? `${layer.name}: ${button.textContent}. ${keyGuidance}`
: `${layer.name}: ${button.textContent}`,
);
}
_formatCount(n) {