// Renderers for the connector namespace picker and connector catalog pages.
// Styled to match the reference connector extension UI.
import { CATEGORY } from "./categories.mjs";
import { buildSandboxUrl } from "./sandbox.mjs";
const CONNECT_ICON = '';
// Official Azure Connector Namespace mark — a gray viewfinder frame wrapping
// two interlocking blue-gradient chain links. Path + gradient data is lifted
// verbatim from the portal's ConnectorNamespaceIcon brand asset. idSuffix keeps
// the gradient element IDs unique when the mark renders more than once per page.
export function brandMark(size = 28, idSuffix = "m") {
const g0 = `cn-g0-${idSuffix}`;
const g1 = `cn-g1-${idSuffix}`;
return ``;
}
export function baseStyles() {
return ``;
}
// ---------------------------------------------------------------------------
// Setup / Namespace Picker
// ---------------------------------------------------------------------------
export function renderSetupHtml(subscriptions, notice = "", capabilityToken = "") {
const subOptions = subscriptions.map((s) =>
``
).join("");
return `
Select Connector Namespace${baseStyles()}
${brandMark(30, "setup")}Select a Connector Namespace
Choose which connector namespace to browse. This choice is saved for future sessions.
${notice ? `
${esc(notice)}
` : ""}
Select a subscription to see available connector namespaces.
`;
}
// ---------------------------------------------------------------------------
// Catalog
// ---------------------------------------------------------------------------
const CSS_HEX_COLOR = /^#[0-9a-fA-F]{6}$/;
function iconBackgroundStyle(brandColor) {
const color = String(brandColor || "").trim();
return CSS_HEX_COLOR.test(color) ? ` style="background:${color}22"` : "";
}
export function renderCatalogHtml(instanceId, catalog, { filter, category, source, config }, capabilityToken = "") {
const renderItem = (c) => {
// Items carry their home grid so hydrateState can move them into
// "My MCPs" when added and back to Microsoft/Partner on remove.
const home = c.category === CATEGORY.microsoft ? "microsoft" : "partner";
const icon = c.iconUri
? `
`
: `
${esc(c.displayName.charAt(0))}
`;
// Button state is hydrated client-side from /api/state on load.
const btn = ``;
const haystack = esc((c.displayName + " " + (c.description || "")).toLowerCase());
const sandboxUrl = esc(buildSandboxUrl(config, c.apiName));
return `
`;
};
// Server paints the first-run layout: My MCPs hidden+empty (filled by
// hydrateState), Microsoft expanded so there's something to browse, Partner
// collapsed. updateSections() flips to the steady layout on the first hydrate
// if anything is already added.
let sectionsHtml =
section("mine", "My MCPs", [], { collapsed: false, hidden: true }) +
section("microsoft", "Microsoft", microsoft, { collapsed: false, hidden: microsoft.length === 0 }) +
section("partner", "Partners", partner, { collapsed: true, hidden: partner.length === 0 });
if (!catalog.length) {
sectionsHtml = `