diff --git a/html/auth-guard.js b/html/auth-guard.js index a6fb029..e6030fc 100644 --- a/html/auth-guard.js +++ b/html/auth-guard.js @@ -165,86 +165,14 @@ // stale cache errs toward hiding the unfinished tooling rather than showing it. window.wpBimEnabled = function () { return !!(window.WP_FLAGS && window.WP_FLAGS.bim_enabled); }; - function isDarkBg(el) { - try { - var m = (getComputedStyle(el).backgroundColor || '').match(/(\d+),\s*(\d+),\s*(\d+)/); - if (!m) return true; - return (0.299 * +m[1] + 0.587 * +m[2] + 0.114 * +m[3]) < 140; - } catch (e) { return true; } - } - - // The user menu (name · Admin · Password · Sign out). Text colors adapt to the - // bar it sits in (light links on a dark bar, blue links on a light bar). - function buildUserMenu(user, dark) { - var wrap = document.createElement('div'); - wrap.id = 'wp-usermenu'; - var linkColor = dark ? '#ffffff' : '#0f62fe'; - // The menu wraps; each link inside does not. It used to be nowrap as a whole, - // which made it one unbreakable 412px run — at 390px that put "Sign out" at - // x382-432, half of it past the edge and untappable (F2). Wrapping the container - // costs nothing above 720px, where it has never needed to wrap. Interim: T2.2 - // replaces this markup with the drawer. - wrap.style.cssText = 'display:flex;align-items:center;gap:8px;margin-left:auto;padding-left:14px;' + - 'flex-wrap:wrap;min-width:0;' + - 'font:400 13px/1.2 "IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;' + - 'color:' + (dark ? '#c6c6c6' : '#525252') + ';'; - function sep() { var s = document.createElement('span'); s.textContent = '·'; s.style.color = dark ? '#6f6f6f' : '#a8a8a8'; return s; } - function link(text, onClick, href) { - var a = document.createElement('a'); a.textContent = text; a.href = href || '#'; - // nowrap per link, so "Language & time" wraps as a unit rather than mid-phrase. - a.style.cssText = 'color:' + linkColor + ';text-decoration:none;font-weight:600;white-space:nowrap;'; - if (onClick) a.addEventListener('click', function (e) { e.preventDefault(); onClick(); }); - return a; - } - var who = document.createElement('span'); - who.textContent = user.full_name || user.username; - who.style.color = dark ? '#ffffff' : '#161616'; - wrap.appendChild(who); - var onAdmin = /(^|\/)admin\.html$/.test(location.pathname); - if (window.wpIsAdmin() && !onAdmin) { wrap.appendChild(sep()); wrap.appendChild(link('Admin', null, 'admin.html')); } - // The directory is readable by everyone — it's how you find who is on your job — - // so it is offered to everyone, not just the people who can edit accounts. - if (!/(^|\/)users\.html$/.test(location.pathname)) { - wrap.appendChild(sep()); wrap.appendChild(link('Users', null, 'users.html')); - } - // Always offered; wp-format.js may still be parsing when the menu is built, so - // the check happens at click time rather than once, up front. - wrap.appendChild(sep()); - wrap.appendChild(link('Language & time', function () { - if (typeof window.wpPreferences === 'function') window.wpPreferences(); - })); - wrap.appendChild(sep()); wrap.appendChild(link('Password', function () { window.wpChangePassword(); })); - wrap.appendChild(sep()); wrap.appendChild(link('Sign out', function () { window.wpLogout(); })); - return wrap; - } - - function addLogoutPill(user) { - if (inIframe) return; // the parent page already shows it - if (document.getElementById('wp-usermenu') || document.getElementById('wp-logout-pill')) return; - - // Preferred: drop the menu INTO the top bar so it never floats over the - // header's own links (Help, etc.). Works with the dark UI-shell appbar and - // the older .header bars alike. - var host = document.querySelector('.wp-appbar') || document.querySelector('.header'); - if (host) { - var menu = buildUserMenu(user, isDarkBg(host)); - // The older .header bars already right-align their own toolbar (via flex:1 - // or a button's margin-left:auto). A second auto-margin would split the free - // space, so only the .wp-appbar (which may have no spacer, e.g. admin) keeps it. - if (!host.classList.contains('wp-appbar')) menu.style.marginLeft = '0'; - host.appendChild(menu); - return; - } - - // Fallback for any page with no header bar: a floating pill (as before). - var pill = document.createElement('div'); - pill.id = 'wp-logout-pill'; - pill.style.cssText = 'position:fixed;top:12px;right:12px;z-index:10001;' + - 'display:flex;align-items:center;background:#fff;border:1px solid #e0e0e0;' + - 'box-shadow:0 1px 4px rgba(0,0,0,.16);border-radius:16px;padding:5px 12px;'; - pill.appendChild(buildUserMenu(user, false)); - document.body.appendChild(pill); - } + // The flat user menu that used to sit in this bar is gone (T2.2). It duplicated + // Admin, Users and Sign out from the navigation drawer, and being one unbreakable + // 412px run with an inline white-space:nowrap, it was what clipped the bar at 390px + // and cut "Sign out" in half — F2. wp-sidenav.js now carries all of it, including + // the two items that were only here: Language & time, and Password. + // + // Nothing replaces it. Every signed-in page mounts the drawer, so there is no page + // left that would need a floating fallback pill. function proceed(user) { clearTimeout(safety); @@ -253,8 +181,6 @@ if (window.WP_USER) { window.wpFlags(); // start the feature-flag fetch; pages await it as needed try { document.dispatchEvent(new CustomEvent('wp-auth-ready', { detail: window.WP_USER })); } catch (e) {} - if (document.body) addLogoutPill(window.WP_USER); - else document.addEventListener('DOMContentLoaded', function () { addLogoutPill(window.WP_USER); }); } } diff --git a/html/field.html b/html/field.html index c7b8a9a..5561ec7 100644 --- a/html/field.html +++ b/html/field.html @@ -70,7 +70,9 @@ Field View
- Home +
diff --git a/html/wp-creation-index.html b/html/wp-creation-index.html index ba1d703..b63ebe9 100644 --- a/html/wp-creation-index.html +++ b/html/wp-creation-index.html @@ -20,8 +20,13 @@
Saving work package…
+
- + + Prime Controls +
|
diff --git a/html/wp-creation-styles.css b/html/wp-creation-styles.css index 6378e67..a53bb0d 100644 --- a/html/wp-creation-styles.css +++ b/html/wp-creation-styles.css @@ -54,14 +54,17 @@ z-index: 100; box-shadow: var(--shadow); } - .header-logo { - font-family: var(--mono); - font-size: 11px; - font-weight: 600; - letter-spacing: .15em; - color: var(--accent); - text-transform: uppercase; + /* The brand is the shared logo chip now, the same as every other page (T2.2). + .header-logo was this page's own mono wordmark - the one thing in the suite + that spelled "Prime Controls" out in monospace instead of showing the mark. + .wp-logo-chip comes from theme-light.css, which this page already loads. */ + .header-logo-chip { + display: inline-flex; + align-items: center; + text-decoration: none; + flex-shrink: 0; } + .header-logo-chip:hover { opacity: .92; } .header-sep { color: var(--border-strong); } .header-title { font-size: 13px; font-weight: 500; color: var(--text-muted); } @@ -553,7 +556,6 @@ .cstatus button { padding:6px 8px; } } @media (max-width: 480px) { - .header-logo { font-size:14px; } .workstep-row textarea { font-size:16px; } /* avoid iOS zoom */ input, select, textarea { font-size:16px; } /* avoid iOS zoom on focus */ } diff --git a/html/wp-sidenav.js b/html/wp-sidenav.js index 051bea8..db707c2 100644 --- a/html/wp-sidenav.js +++ b/html/wp-sidenav.js @@ -44,6 +44,14 @@ { href: 'admin.html', match: /(^|\/)admin\.html$/, icon: '⚡', label: 'Admin Console', sub: 'Settings & diagnostics', show: function () { return typeof window.wpIsAdmin === 'function' && window.wpIsAdmin(); } }, + // Account actions, inherited from the flat user menu that used to sit in the app + // bar (T2.2). Everything else that menu offered — Admin, Users, Sign out — the + // drawer already had; these two were its only unique contents, so they moved here + // rather than being lost with it. `action` items render as buttons, not links. + { section: 'Account' }, + { action: 'wpPreferences', icon: '⌚', label: 'Language & time', + sub: 'Dates, numbers and time zone' }, + { action: 'wpChangePassword', icon: '⚿', label: 'Password', sub: 'Change your password' }, ]; function esc(v) { @@ -110,11 +118,21 @@ LINKS.forEach(function (item) { if (item.section) { rows += '
' + esc(item.section) + '
'; return; } if (item.show && !item.show()) return; - rows += '' + + var inner = '' + '' + esc(item.label) + - (item.sub ? '' + esc(item.sub) + '' : '') + ''; + (item.sub ? '' + esc(item.sub) + '' : '') + ''; + // An action opens a dialog on the current page rather than going anywhere, so + // it is a button. Never a
with a click handler — CLAUDE.md, and the + // drawer is keyboard-navigable precisely because everything in it is focusable. + if (item.action) { + rows += ''; + return; + } + rows += '' + + inner + ''; }); var who = user ? (user.full_name || user.username || '') : ''; @@ -136,6 +154,17 @@ drawer.querySelector('#wp-sidenav-signout').addEventListener('click', function () { if (typeof window.wpLogout === 'function') window.wpLogout(); }); + // Close first, then act: these open a dialog, and leaving the drawer over it + // would put a scrim between the user and the thing they just asked for. The + // handler is looked up at click time because wp-format.js may still be parsing + // when the drawer is built — the flat menu had the same note. + Array.prototype.forEach.call(drawer.querySelectorAll('[data-action]'), function (el) { + el.addEventListener('click', function () { + var fn = window[el.getAttribute('data-action')]; + close(); + if (typeof fn === 'function') fn(); + }); + }); document.body.appendChild(scrim); document.body.appendChild(drawer); }