Files
Project-SDE-WP-Suite/html/users.html
n.siegfried 560f0cb3cc BL-024 - the last 21 native dialogs, onto the shared kit
S1 counted 79 native dialogs app-wide and its tasks removed 58; the audit
found the rest on surfaces no S1 task named: admin.js (6), users.js (10), the
launcher's inline script (5). All 21 now go through wp-dialog.js - the T7.9
kit extracted as a self-injecting shared component: markup and styles land on
first use, styles are theme tokens only with its own wp-dlg-* class names (the
consoles' existing .modal styles are untouched), 44px targets on coarse
pointers, and the whole file is guarded so the creator's inline copy - which
owns the same-id markup in its HTML - still wins on its own page. The kit's
toast comes along (S10 role rules), since none of the three pages had one.

Conversion follows the T7.9 precedent: confirms -> wpConfirmDialog with named
ok-labels, the password prompt -> wpPromptDialog whose validate() finally
enforces min-12 AT the input (it was label-text-only before, server-enforced),
API failures with detail -> wpAlertDialog, small info/validation messages ->
the announced toast.

New probe console_dialogs_check (17): counts pinned at 0, kit guarded and
loaded by all three pages, and the users console driven live with natives
poisoned - reset a password end to end (short refused inline, good one accepted
by the server and announced), cancel a delete and prove nothing died.

Items: BL-024 (closed), S1 completed to zero app-wide, C1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 18:24:09 -07:00

115 lines
5.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>User Directory — Work Package Suite</title>
<script src="auth-guard.js"></script>
<!-- Date/number formatting. Must parse BEFORE the app scripts: they format
timestamps during their own boot. -->
<script src="wp-format.js"></script>
<!-- Addressable state (S3). Parses before the app scripts, which read the URL
during their own boot. -->
<script src="wp-url.js"></script>
<link rel="icon" href="favicon.ico" sizes="any">
<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#161616">
<link rel="stylesheet" href="theme-light.css">
<link rel="stylesheet" href="wp-chrome.css">
<link rel="stylesheet" href="console.css">
<link rel="stylesheet" href="wp-sidenav.css">
<style>
/* Page-specific only — everything structural is in console.css.
The directory is one wide table, so the column exceptions live here: email is
the one cell long enough to stretch a row, and the two role dropdowns need
room for "Assistant Project Manager" without pushing Actions off screen. */
#users-table table td:nth-child(3){ max-width:230px; overflow:hidden; text-overflow:ellipsis; }
#users-banner:not(:empty), #scope-banner:not(:empty){ margin-bottom:var(--s3); }
/* The create form is a lot of fields; give the password one room to breathe and
let the project picker take a full row of its own. */
#nu-password{ flex:1 1 200px; }
#nu-projects{ margin-top:var(--s2); }
#nu-projects .pickrow{ padding:var(--s1) var(--s1); }
/* A manager with one project doesn't need a scrolling picker; a manager with
thirty does, and it must not push the Create button below the fold. */
#nu-project-list{ max-height:200px; overflow:auto; border:1px solid var(--border); }
.whoami-chip{ font-size:12px; color:var(--muted); }
.whoami-chip strong{ color:var(--text); }
</style>
</head>
<body>
<!-- SHARED DARK APP BAR -->
<header class="wp-appbar">
<a href="index.html" class="wp-appbar-brand" title="Back to site">
<span class="wp-logo-chip"><img src="prime-controls-logo.jpg" alt="Prime Controls"></span>
<span class="wp-appbar-title">Work Package Suite <span class="wp-appbar-sub">| User Directory</span></span>
</a>
</header>
<div class="wrap" id="users-main" style="display:none">
<div class="row" style="justify-content:space-between; margin-bottom:var(--s5)">
<div>
<h1>User Directory</h1>
<div class="sub" style="margin:0" id="dir-sub">The people on your projects — who they are, and how to reach them.</div>
</div>
<div class="row"><a class="home" href="index.html">← Site</a></div>
</div>
<!-- WHAT YOU MAY DO HERE (rendered from GET /api/auth/user-scope) -->
<div id="scope-banner"></div>
<!-- THE DIRECTORY -->
<div class="card">
<h2>People</h2>
<div class="sub" id="people-sub"></div>
<div class="toolbar">
<button onclick="loadUsers()">Refresh</button>
<input id="user-search" placeholder="Search name / username / email / job function…" oninput="renderUsers()">
<select id="user-filter" onchange="renderUsers()">
<option value="">Everyone</option>
<option value="active">Active only</option>
<option value="disabled">Disabled only</option>
<option value="mine">Accounts I manage</option>
</select>
</div>
<div id="users-banner"></div>
<div id="users-table"><div class="note">Loading…</div></div>
</div>
<!-- ADD A USER (managers only; hidden otherwise) -->
<div class="card" id="create-card" style="display:none">
<h2>Add a user</h2>
<div class="sub" id="create-sub"></div>
<div class="urow">
<input id="nu-username" placeholder="Username *" autocomplete="off">
<input id="nu-fullname" placeholder="Full name" autocomplete="off">
<input id="nu-email" placeholder="Email" autocomplete="off">
<select id="nu-role" title="Permissions — what this account may do"></select>
<select id="nu-project-role" title="Job function on the project"></select>
<input id="nu-password" type="password" placeholder="Password (min 12)" autocomplete="new-password">
</div>
<div id="nu-projects">
<div class="note" id="nu-projects-label" style="margin-bottom:var(--s1)"></div>
<div id="nu-project-list"></div>
</div>
<div class="row" style="margin-top:var(--s3)">
<button class="primary" onclick="createUser()">Create user</button>
<span id="users-create-msg" class="note" style="margin:0"></span>
</div>
</div>
</div>
<script src="console-util.js"></script>
<script src="wp-dialog.js"></script>
<script src="users.js"></script>
<!-- The app bar's project switcher reads ProjectData; without this the bar on this
page could never show a project and always read "Select a project" (F1). Must
parse before wp-chrome.js, which reads it as it mounts. -->
<script src="project-data.js"></script>
<script src="wp-chrome.js"></script>
<script src="wp-sidenav.js"></script>
</body>
</html>