fix: gate unfinished surfaces honestly (oracle round 2)
- Login.tsx: dev-login gated by VITE_ENABLE_DEV_LOGIN (defaults on, set to 'false' in production builds). SSO button probes /microsoft/login and shows 'NOT CONFIGURED' or 'NOT WIRED' state with disabled action instead of looking like a working primary login. - Hub.tsx: 'Queue'/'Selected work' renamed 'Available workflows' / 'Workflow detail' + footnote that a real work-item queue replaces it when the EA2 hub queue is wired. No more semantic overclaim. - Landing.tsx: Attendance Map chip gated by VITE_ENABLE_GEO_PREVIEW (default on) and labelled 'preview' so it can be hidden in prod builds. - flowCuration.ts: extend the dev-artefact filter to drop engineering names (EA2 *, SDX *, *runtime reference*, *demo*, *test*) so Pi and the hubs only ever expose buyer-appropriate flows. - All 29 unit tests + 26 dogfood QA assertions still green.
This commit is contained in:
@@ -21,6 +21,11 @@ const DEV_ARTEFACT_PATTERNS = [
|
||||
/\bsmoke[_\s]?test\b/i,
|
||||
/\bprobe\b/i,
|
||||
/\bfixture\b/i,
|
||||
/\bea2\b/i,
|
||||
/\bsdx\b/i,
|
||||
/\bruntime reference\b/i,
|
||||
/\bdemo\b/i,
|
||||
/\btest\b/i,
|
||||
];
|
||||
|
||||
const NON_BUSINESS_SOURCE_CONTEXTS = new Set([
|
||||
|
||||
+5
-4
@@ -163,11 +163,11 @@ export default function Hub({ hub }: { hub: HubKey }) {
|
||||
|
||||
<div className="hub-split">
|
||||
<section className="hub-queue">
|
||||
<div className="hub-section-label">{spec.title.split(" ")[0].toUpperCase()} QUEUE</div>
|
||||
<div className="hub-section-label">AVAILABLE WORKFLOWS</div>
|
||||
{flows === null && <div className="hub-empty">Loading…</div>}
|
||||
{flows !== null && visible.length === 0 && (
|
||||
<div className="hub-empty">
|
||||
Nothing in the queue yet. Open the <button className="link-inline" onClick={() => setScene("studio")}>Process Studio</button> to publish a process.
|
||||
No workflows published for this function yet. Open the <button className="link-inline" onClick={() => setScene("studio")}>Process Studio</button> to add one.
|
||||
</div>
|
||||
)}
|
||||
<ul className="hub-queue-list">
|
||||
@@ -183,11 +183,12 @@ export default function Hub({ hub }: { hub: HubKey }) {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="hub-queue-foot">A live work-item queue will replace this list once the EA2 hub queue endpoint is wired.</p>
|
||||
</section>
|
||||
|
||||
<section className="hub-selected">
|
||||
<div className="hub-section-label">SELECTED WORK</div>
|
||||
{!selected && <div className="hub-empty">Select a row on the left.</div>}
|
||||
<div className="hub-section-label">WORKFLOW DETAIL</div>
|
||||
{!selected && <div className="hub-empty">Select a workflow on the left.</div>}
|
||||
{selected && (
|
||||
<div className="hub-flow-card">
|
||||
<div className="hub-flow-title"><Branch size={11} /> {selected.display_name}</div>
|
||||
|
||||
@@ -79,7 +79,9 @@ export default function Landing() {
|
||||
<button className="hub-chip" onClick={() => setScene("hub-procurement")}>Procurement Hub</button>
|
||||
<button className="hub-chip" onClick={() => setScene("hub-hr")}>People Hub</button>
|
||||
<button className="hub-chip" onClick={() => setScene("hub-it")}>IT Hub</button>
|
||||
<button className="hub-chip" onClick={() => setScene("geo-attendance")}>Attendance Map</button>
|
||||
{(import.meta.env.VITE_ENABLE_GEO_PREVIEW ?? "true") !== "false" && (
|
||||
<button className="hub-chip" onClick={() => setScene("geo-attendance")}>Attendance Map · preview</button>
|
||||
)}
|
||||
<button className="hub-chip" onClick={() => setScene("agent")}>Command Assistant</button>
|
||||
<button className="hub-chip" onClick={() => setScene("chat")}>Team Chat</button>
|
||||
<button className="hub-chip" onClick={() => setScene("explainer")}>What is FlowMaster?</button>
|
||||
|
||||
+26
-8
@@ -9,16 +9,28 @@ export default function Login() {
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [rememberMe, setRememberMe] = useState(false);
|
||||
const [devLoginEnabled, setDevLoginEnabled] = useState(true);
|
||||
const buildAllowsDev = (import.meta.env.VITE_ENABLE_DEV_LOGIN ?? "true") !== "false";
|
||||
const [devLoginEnabled, setDevLoginEnabled] = useState(buildAllowsDev);
|
||||
const [ssoState, setSsoState] = useState<"unknown" | "ready" | "not-configured" | "not-wired">("unknown");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// dev-login is on by default. Only the endpoint can flip it OFF.
|
||||
api.devLoginConfig()
|
||||
.then((cfg) => { if (cfg.enabled === false) setDevLoginEnabled(false); })
|
||||
.catch(() => { /* endpoint absent → keep ON */ });
|
||||
}, []);
|
||||
if (!buildAllowsDev) {
|
||||
setDevLoginEnabled(false);
|
||||
} else {
|
||||
api.devLoginConfig()
|
||||
.then((cfg) => { if (cfg.enabled === false) setDevLoginEnabled(false); })
|
||||
.catch(() => { /* endpoint absent → keep state */ });
|
||||
}
|
||||
fetch("/api/v1/auth/microsoft/login", { method: "GET", redirect: "manual" })
|
||||
.then((r) => {
|
||||
if (r.status >= 300 && r.status < 400) setSsoState("ready");
|
||||
else if (r.status === 503) setSsoState("not-configured");
|
||||
else setSsoState("not-wired");
|
||||
})
|
||||
.catch(() => setSsoState("not-wired"));
|
||||
}, [buildAllowsDev]);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
@@ -142,14 +154,20 @@ export default function Login() {
|
||||
</div>
|
||||
|
||||
<div className="login-sso-actions">
|
||||
<button type="button" className="sso-btn" onClick={handleSSO} disabled={loading}>
|
||||
<button
|
||||
type="button"
|
||||
className="sso-btn"
|
||||
onClick={handleSSO}
|
||||
disabled={loading || ssoState === "not-configured" || ssoState === "not-wired"}
|
||||
title={ssoState === "not-configured" ? "Microsoft sign-in is not yet configured for this tenant" : ssoState === "not-wired" ? "Microsoft sign-in is not wired to this environment yet" : "Sign in with Microsoft"}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 21 21">
|
||||
<rect x="1" y="1" width="9" height="9" fill="#f25022"/>
|
||||
<rect x="11" y="1" width="9" height="9" fill="#7fba00"/>
|
||||
<rect x="1" y="11" width="9" height="9" fill="#00a4ef"/>
|
||||
<rect x="11" y="11" width="9" height="9" fill="#ffb900"/>
|
||||
</svg>
|
||||
CONTINUE WITH MICROSOFT
|
||||
{ssoState === "not-configured" ? "MICROSOFT SIGN-IN · NOT CONFIGURED" : ssoState === "not-wired" ? "MICROSOFT SIGN-IN · NOT WIRED" : "CONTINUE WITH MICROSOFT"}
|
||||
</button>
|
||||
|
||||
{devLoginEnabled && (
|
||||
|
||||
Reference in New Issue
Block a user