@protobase/ui 0.52.0 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,12 @@
1
1
  import { text } from "../messages.js";
2
2
  import { useAuth } from "../../auth/auth-provider.js";
3
+ import { useAdminMeta } from "../../app/meta-gate.js";
3
4
  import { AccountLoading } from "./account-loading.js";
4
5
  import { useAccountData } from "./use-account-data.js";
5
6
  import { ConnectedAppsSection } from "../connected-apps-section.js";
7
+ import { McpAddressSection } from "../mcp-address-section.js";
6
8
  import { useCallback } from "react";
7
- import { jsx } from "react/jsx-runtime";
9
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
10
  //#region src/account/blocks/connected-apps-block.tsx
9
11
  const Apps = () => {
10
12
  const { account } = useAuth().session;
@@ -15,7 +17,17 @@ const Apps = () => {
15
17
  onDisconnect: (clientId) => account.disconnectApp(clientId).then(reload)
16
18
  });
17
19
  };
18
- /** The `ConnectedApps` block: the apps the signed-in person allowed to act as them, hidden when the app has no MCP. */
19
- const ConnectedAppsBlock = () => useAuth().mcp ? /* @__PURE__ */ jsx(Apps, {}) : null;
20
+ const Mcp = ({ url }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(McpAddressSection, {
21
+ url,
22
+ appName: useAdminMeta().appName
23
+ }), /* @__PURE__ */ jsx(Apps, {})] });
24
+ /**
25
+ * The `ConnectedApps` block: the address of the app's MCP endpoint and the apps the signed-in person allowed to act as
26
+ * them, hidden when the app has no MCP.
27
+ */
28
+ const ConnectedAppsBlock = () => {
29
+ const { mcp } = useAuth();
30
+ return mcp ? /* @__PURE__ */ jsx(Mcp, { url: mcp.url }) : null;
31
+ };
20
32
  //#endregion
21
33
  export { ConnectedAppsBlock };
@@ -0,0 +1,14 @@
1
+ //#region src/account/connector-dialog.ts
2
+ /**
3
+ * The address of Claude's dialog that adds a custom connector, filled in with the MCP endpoint's `url` and, when the
4
+ * app has one, its name; the person sees both there and confirms.
5
+ */
6
+ const connectorDialogUrl = (url, appName) => {
7
+ const dialog = new URL("https://claude.ai/customize/connectors");
8
+ dialog.searchParams.set("modal", "add-custom-connector");
9
+ if (appName) dialog.searchParams.set("connectorName", appName);
10
+ dialog.searchParams.set("connectorUrl", url);
11
+ return dialog.href;
12
+ };
13
+ //#endregion
14
+ export { connectorDialogUrl };
@@ -0,0 +1,45 @@
1
+ import { text } from "./messages.js";
2
+ import { buttonClass } from "../primitives/button.js";
3
+ import { AccountSection } from "./account-section.js";
4
+ import { connectorDialogUrl } from "./connector-dialog.js";
5
+ import { useState } from "react";
6
+ import { Check, Copy, ExternalLink } from "lucide-react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/account/mcp-address-section.tsx
9
+ /** The address of the app's MCP endpoint, to copy into an AI client or add to Claude, with how connecting goes. */
10
+ const McpAddressSection = ({ url, appName }) => {
11
+ const [copied, setCopied] = useState(false);
12
+ return /* @__PURE__ */ jsx(AccountSection, {
13
+ title: text("mcpAddress"),
14
+ description: text("mcpAddressDescription"),
15
+ children: /* @__PURE__ */ jsxs("div", {
16
+ className: "flex flex-wrap items-center gap-2",
17
+ children: [/* @__PURE__ */ jsxs("div", {
18
+ className: "flex min-w-0 flex-1 items-center gap-2 rounded-md border bg-surface py-1.5 pl-3 pr-1.5",
19
+ children: [/* @__PURE__ */ jsx("code", {
20
+ className: "min-w-0 flex-1 break-all font-mono text-xs",
21
+ children: url
22
+ }), /* @__PURE__ */ jsx("button", {
23
+ type: "button",
24
+ "aria-label": copied ? text("copied") : text("copyMcpAddress"),
25
+ onClick: () => {
26
+ navigator.clipboard.writeText(url).then(() => {
27
+ setCopied(true);
28
+ setTimeout(() => setCopied(false), 2e3);
29
+ });
30
+ },
31
+ className: "inline-flex size-8 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-muted pointer-coarse:size-11",
32
+ children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-4 text-success" }) : /* @__PURE__ */ jsx(Copy, { className: "size-4" })
33
+ })]
34
+ }), /* @__PURE__ */ jsxs("a", {
35
+ href: connectorDialogUrl(url, appName),
36
+ target: "_blank",
37
+ rel: "noreferrer",
38
+ className: buttonClass(),
39
+ children: [/* @__PURE__ */ jsx(ExternalLink, { className: "size-3.5" }), text("addToClaude")]
40
+ })]
41
+ })
42
+ });
43
+ };
44
+ //#endregion
45
+ export { McpAddressSection };
@@ -149,7 +149,11 @@ const text = defineMessages({
149
149
  couldNotReadStaffSignIns: "Could not read the staff sign-ins",
150
150
  couldNotReadPolicy: "Could not read the sign-in policy",
151
151
  policySaved: "Saved. It applies to every sign-in from now on.",
152
- policySubtitle: "How people sign in to this app. Signed-in people keep their session, and are asked for what is newly required within 15 minutes."
152
+ policySubtitle: "How people sign in to this app. Signed-in people keep their session, and are asked for what is newly required within 15 minutes.",
153
+ mcpAddress: "MCP address",
154
+ mcpAddressDescription: "Add this address to an AI assistant or code editor that speaks MCP, as a custom connector or remote MCP server. It opens this app in your browser, where you sign in and allow it; it then works with your access.",
155
+ copyMcpAddress: "Copy the MCP address",
156
+ addToClaude: "Add to Claude"
153
157
  },
154
158
  nl: {
155
159
  account: "Account",
@@ -299,7 +303,11 @@ const text = defineMessages({
299
303
  couldNotReadStaffSignIns: "Kon de inlogs van medewerkers niet lezen",
300
304
  couldNotReadPolicy: "Kon het inlogbeleid niet lezen",
301
305
  policySaved: "Bewaard. Het geldt vanaf nu voor elke inlog.",
302
- policySubtitle: "Hoe mensen inloggen bij deze app. Wie is ingelogd, houdt de sessie en krijgt binnen 15 minuten de vraag naar wat nieuw verplicht is."
306
+ policySubtitle: "Hoe mensen inloggen bij deze app. Wie is ingelogd, houdt de sessie en krijgt binnen 15 minuten de vraag naar wat nieuw verplicht is.",
307
+ mcpAddress: "MCP-adres",
308
+ mcpAddressDescription: "Voeg dit adres toe aan een AI-assistent of code-editor die MCP spreekt, als aangepaste connector of externe MCP-server. Die opent deze app in je browser, waar je inlogt en hem toestaat; daarna werkt hij met jouw toegang.",
309
+ copyMcpAddress: "Het MCP-adres kopiëren",
310
+ addToClaude: "Toevoegen aan Claude"
303
311
  }
304
312
  });
305
313
  //#endregion
@@ -25,7 +25,7 @@ const AuthProvider = ({ session: given, origin, nativeBridge, children }) => {
25
25
  const [signInFirst, setSignInFirst] = useState("password");
26
26
  const [passwordReset, setPasswordReset] = useState(false);
27
27
  const [changeEmail, setChangeEmail] = useState(false);
28
- const [mcp, setMcp] = useState(false);
28
+ const [mcp, setMcp] = useState();
29
29
  const [canSignUp, setCanSignUp] = useState(false);
30
30
  const [passkeyDomains, setPasskeyDomains] = useState([]);
31
31
  const [socialProviders, setSocialProviders] = useState([]);
@@ -110,7 +110,7 @@ const AuthProvider = ({ session: given, origin, nativeBridge, children }) => {
110
110
  setSignInFirst(status.signInFirst ?? "password");
111
111
  setPasswordReset(status.passwordReset && !nativeBridge);
112
112
  setChangeEmail(Boolean(status.changeEmail));
113
- setMcp(Boolean(status.mcp));
113
+ setMcp(status.mcp);
114
114
  setCanSignUp(Boolean(status.signUp));
115
115
  setPasskeyDomains(status.passkeyDomains ?? []);
116
116
  setSocialProviders(status.socialProviders);
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.52.0";
2
+ var version = "0.53.0";
3
3
  var protobase = { "pluginApi": 1 };
4
4
  //#endregion
5
5
  export { protobase, version };