PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.9.5
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.9.5
4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 All 203 releases
betterdocs / react-src / admin / mcp / components / McpHeader.js

McpHeader.js in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.9.5, at react-src/admin/mcp/components/McpHeader.js

86 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React, { useEffect, useState } from "react";
2 import { createPortal } from "react-dom";
3 import { __ } from "@wordpress/i18n";
4
5 import DarkModeToggle from "../../components/DarkModeToggle";
6 import { IconMcp } from "./Icons";
7
8 /**
9 * The MCP screen's own header row, portalled into the admin shell's header the
10 * way the Analytics route does it (`analytics/components/Chrome.js`).
11 *
12 * The page needs the title, the status badge and the master switch on one row
13 * (ADR-062), and the switch reads state this component's parent owns — so the
14 * row cannot be built out of the shell's `betterdocs_admin_header_title` /
15 * `_action_icons` filters, which are registered in `Routes.js`, outside this
16 * tree. `Header.js` therefore skips its default row for `betterdocs-mcp` and
17 * this row takes its place, carrying the dark-mode switcher across with it:
18 * that switcher is the only global control on the screen, and dropping the
19 * shell row without re-rendering it is what U12b refused to do.
20 *
21 * @since 4.9.0
22 */
23 const HOST_SELECTOR = ".betterdocs-dashboard-header > .betterdocs-dashboard-container";
24
25 export default function McpHeader({ status, enabled, saving, onToggle }) {
26 const [host, setHost] = useState(null);
27
28 useEffect(() => {
29 const target = document.querySelector(HOST_SELECTOR);
30 if (!target) {
31 return undefined;
32 }
33 const node = document.createElement("div");
34 // `bd-mcp-header-host` also carries the `--bda-*` alias block, because
35 // this row renders outside `.bd-mcp-wrapper` and the badge inside it is
36 // a `bda-badge` — which Pro's admin-wide `analytics.css` redefines in
37 // terms of variables it only declares on its own root (U12b).
38 node.className = "bd-mcp-header-host";
39 target.appendChild(node);
40 setHost(node);
41 return () => {
42 node.remove();
43 };
44 }, []);
45
46 if (!host) {
47 return null;
48 }
49
50 return createPortal(
51 <div className="betterdocs-row bd-mcp-header">
52 <div className="betterdocs-col betterdocs-header-left betterdocs-col-xs-6 bd-mcp-header__left">
53 <span className="bd-mcp-header__tile">
54 <IconMcp size={20} />
55 </span>
56 <h2 className="betterdocs-dashboard-header-title bd-mcp-header__title">
57 {__("MCP", "betterdocs")}
58 </h2>
59 <span className={`bda-badge ${status.tone}`}>{status.label}</span>
60 </div>
61 <div className="betterdocs-col betterdocs-header-right betterdocs-col-xs-6 betterdocs-d-flex betterdocs-justify-end bd-mcp-header__right">
62 {saving && <span className="bd-mcp-muted">{__("Saving…", "betterdocs")}</span>}
63 <label className="bd-mcp-switch" htmlFor="betterdocs-enable-mcp">
64 <span className="bd-mcp-switch__label">{__("Enable MCP access", "betterdocs")}</span>
65 <input
66 id="betterdocs-enable-mcp"
67 type="checkbox"
68 checked={enabled}
69 onChange={onToggle}
70 disabled={saving}
71 />
72 <span className="bd-mcp-switch__track" aria-hidden="true">
73 <span className="bd-mcp-switch__thumb" />
74 </span>
75 </label>
76 <ul className="betterdocs-dashboard-header-action-list betterdocs-text-align-right">
77 <li>
78 <DarkModeToggle />
79 </li>
80 </ul>
81 </div>
82 </div>,
83 host,
84 );
85 }
86