From 9fbf90ee91a1295e84c2fd8fb46d35ec4c1602a1 Mon Sep 17 00:00:00 2001 From: Stan Grams Date: Sat, 1 Aug 2026 11:12:33 +0200 Subject: [PATCH] feat(ui): explain operator workspace choices --- .../trx-frontend-http/assets/web/style.css | 33 ++++++++++++++++++- .../trx-frontend-http/assets/web/ui-core.js | 12 ++++--- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css index 05c7bb73..0332ef8d 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css @@ -2949,7 +2949,8 @@ button.is-active { font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; - overflow: hidden; + overflow: visible; + position: relative; } .operator-layout-picker::before { content: "Layout"; } .operator-layout-picker select { @@ -2967,6 +2968,36 @@ button.is-active { } .operator-layout-picker:focus-within { border-color: var(--accent-green); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-green) 20%, transparent); } .operator-layout-picker select:focus-visible { outline: 0; } +.operator-layout-description { + position: absolute; + top: calc(100% + 0.35rem); + left: 0; + z-index: 25; + width: max-content; + max-width: min(22rem, calc(100vw - 2rem)); + padding: 0.35rem 0.55rem; + border: 1px solid var(--border-light); + border-radius: var(--radius-sm); + background: var(--card-bg); + color: var(--text-muted); + box-shadow: 0 8px 24px color-mix(in srgb, #000 28%, transparent); + font-size: var(--fs-xs); + font-weight: 500; + letter-spacing: 0; + line-height: 1.35; + text-transform: none; + opacity: 0; + transform: translateY(-0.2rem); + visibility: hidden; + pointer-events: none; + transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), visibility var(--dur-fast); +} +.operator-layout-picker:hover .operator-layout-description, +.operator-layout-picker:focus-within .operator-layout-description { + opacity: 1; + transform: none; + visibility: visible; +} .advanced-radio-controls { margin-top: var(--space-3); border: 1px solid color-mix(in srgb, var(--border-light) 75%, transparent); diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/ui-core.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/ui-core.js index f29ebb73..1bfe06f9 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/ui-core.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/ui-core.js @@ -126,10 +126,10 @@ }; const layouts = { - compact: { label: "Compact", advanced: false, preferredTab: "main" }, - broadcast: { label: "Broadcast", advanced: false, preferredTab: "main", capability: "broadcast" }, - digital: { label: "Digital", advanced: false, preferredTab: "digital-modes", capability: "digital" }, - full: { label: "Full controls", advanced: true, preferredTab: "main" }, + compact: { label: "Compact", description: "Essential tuning and audio controls", advanced: false, preferredTab: "main" }, + broadcast: { label: "Broadcast", description: "WFM, RDS, stereo and interference monitoring", advanced: false, preferredTab: "main", capability: "broadcast" }, + digital: { label: "Digital", description: "Decoder status, messages and background decoding", advanced: false, preferredTab: "digital-modes", capability: "digital" }, + full: { label: "Full controls", description: "Every control supported by the selected rig", advanced: true, preferredTab: "main" }, }; const layoutCapabilities = { broadcast: false, digital: false }; @@ -166,6 +166,8 @@ localStorage.setItem("trxOperatorLayout", document.body.dataset.operatorLayout); const details = document.getElementById("advanced-radio-controls"); if (details) details.open = layout.advanced; + const description = document.getElementById("operator-layout-description"); + if (description) description.textContent = layout.description; if (options.navigate && typeof window.navigateToTab === "function") { window.navigateToTab(layout.preferredTab); } @@ -176,7 +178,7 @@ if (actions && !document.getElementById("operator-layout-select")) { const label = document.createElement("label"); label.className = "operator-layout-picker"; - label.innerHTML = 'Operator layout'; + label.innerHTML = 'Operator layout'; const select = label.querySelector("select"); const savedLayout = localStorage.getItem("trxOperatorLayout") || "compact"; actions.insertBefore(label, actions.firstChild);