@protobase/ui 0.33.4 → 0.34.1

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.
Files changed (92) hide show
  1. package/dist/account/account-security-page.js +16 -6
  2. package/dist/account/connected-apps-section.js +93 -0
  3. package/dist/app/app.js +20 -7
  4. package/dist/app/charts/chart-view.js +1 -1
  5. package/dist/app/create/create-page.js +2 -2
  6. package/dist/app/create/create-route.js +1 -1
  7. package/dist/app/delete/use-delete-flow.js +1 -1
  8. package/dist/app/displays/board-display.js +1 -1
  9. package/dist/app/displays/calendar-display.js +1 -1
  10. package/dist/app/displays/map-display.js +1 -1
  11. package/dist/app/displays/record-card.js +1 -1
  12. package/dist/app/displays/timeline-display.js +1 -1
  13. package/dist/app/displays/use-board-column.js +1 -1
  14. package/dist/app/displays/use-map-records.js +1 -1
  15. package/dist/app/embedded-list/embedded-list.js +1 -1
  16. package/dist/app/embedded-list/use-embedded-rows.js +1 -1
  17. package/dist/app/export/export-dialog.js +1 -1
  18. package/dist/app/file-field.js +1 -1
  19. package/dist/app/gallery/gallery-section.js +1 -1
  20. package/dist/app/gallery/lightbox.js +1 -1
  21. package/dist/app/gallery/use-gallery-photos.js +1 -1
  22. package/dist/app/hand-order/hand-sorted-list.js +1 -1
  23. package/dist/app/hand-order/use-hand-order.js +1 -1
  24. package/dist/app/import/import-dialog.js +1 -1
  25. package/dist/app/incoming-card.js +1 -1
  26. package/dist/app/list-page.js +3 -3
  27. package/dist/app/map/map-section.js +1 -1
  28. package/dist/app/meta-gate.js +2 -2
  29. package/dist/app/pages/action-inputs/action-inputs-dialog.js +2 -2
  30. package/dist/app/pages/blocks/card-row.js +1 -1
  31. package/dist/app/pages/blocks/field.js +1 -1
  32. package/dist/app/pages/blocks/modal-form.js +1 -1
  33. package/dist/app/pages/blocks/record-card.js +1 -1
  34. package/dist/app/pages/blocks/record-cards.js +1 -1
  35. package/dist/app/pages/blocks/stat.js +1 -1
  36. package/dist/app/pages/composed-page.js +1 -1
  37. package/dist/app/pages/field-value.js +1 -1
  38. package/dist/app/pages/use-run-action.js +1 -1
  39. package/dist/app/record-chart/record-chart-section.js +1 -1
  40. package/dist/app/record-lines.js +1 -1
  41. package/dist/app/record-page.js +5 -5
  42. package/dist/app/record-row/record-row-body.js +1 -1
  43. package/dist/app/record-row/saved-record-row.js +1 -1
  44. package/dist/app/related-cards/related-card.js +1 -1
  45. package/dist/app/related-section.js +2 -2
  46. package/dist/app/saved/use-favorite.js +1 -1
  47. package/dist/app/search/navigation-hits.js +1 -1
  48. package/dist/app/search/use-global-search.js +1 -1
  49. package/dist/app/searches/save-search-button.js +1 -1
  50. package/dist/app/searches/saved-search-rows.js +1 -1
  51. package/dist/app/searches/saved-searches.js +1 -1
  52. package/dist/app/searches/search-controls.js +1 -1
  53. package/dist/app/searches/update-search-dialog.js +1 -1
  54. package/dist/app/searches/use-save-search.js +1 -1
  55. package/dist/app/searches/use-saved-searches.js +1 -1
  56. package/dist/app/source-notice.js +1 -1
  57. package/dist/app/use-app-address.js +1 -1
  58. package/dist/app/use-incoming-counts.js +1 -1
  59. package/dist/auth/auth-gate.js +1 -1
  60. package/dist/auth/auth-provider.js +4 -0
  61. package/dist/auth/sign-in-prompt.js +2 -2
  62. package/dist/connect/client-name.js +9 -0
  63. package/dist/connect/client-publisher.js +13 -0
  64. package/dist/connect/connect-page.js +236 -0
  65. package/dist/connect/interaction-guard.js +77 -0
  66. package/dist/connect/redirect-target.js +36 -0
  67. package/dist/connect/signed-request.js +14 -0
  68. package/dist/connect/use-connect-address.js +11 -0
  69. package/dist/data/use-live-updates.js +1 -1
  70. package/dist/forms/public-form-page.js +2 -2
  71. package/dist/index.js +3 -3
  72. package/dist/live/use-filter-config.js +1 -1
  73. package/dist/live/use-reference-search.js +1 -1
  74. package/dist/package.js +1 -1
  75. package/dist/plugins/plugin-gate.js +1 -1
  76. package/dist/shell/assets/app-Bh3A_oyl.js +70 -0
  77. package/dist/shell/assets/{index-BAYZFH-l.js → index-B7S1UwQw.js} +2 -2
  78. package/dist/shell/assets/index-BX850JXd.css +2 -0
  79. package/dist/shell/assets/{records-map-D2XP8QkT.js → records-map-DH1o1e94.js} +2 -2
  80. package/dist/shell/assets/shared-protobase-ui-yYsrs03Z.js +2 -0
  81. package/dist/shell/index.html +4 -4
  82. package/dist/shell/protobase.shell.json +1 -1
  83. package/dist/shell/protobase.sw.js +2 -2
  84. package/dist/shell-source-maps/assets/app-Bh3A_oyl.js.map +1 -0
  85. package/dist/shell-source-maps/assets/{index-BAYZFH-l.js.map → index-B7S1UwQw.js.map} +1 -1
  86. package/dist/shell-source-maps/assets/{records-map-D2XP8QkT.js.map → records-map-DH1o1e94.js.map} +1 -1
  87. package/dist/shell-source-maps/assets/{shared-protobase-ui-C5AR2k3j.js.map → shared-protobase-ui-yYsrs03Z.js.map} +1 -1
  88. package/package.json +4 -4
  89. package/dist/shell/assets/app-B9bnfmK5.js +0 -70
  90. package/dist/shell/assets/index-BrgzNBVN.css +0 -2
  91. package/dist/shell/assets/shared-protobase-ui-C5AR2k3j.js +0 -2
  92. package/dist/shell-source-maps/assets/app-B9bnfmK5.js.map +0 -1
@@ -4,6 +4,7 @@ import { PageHeader } from "../app-shell/page-header.js";
4
4
  import { authMessage, providerMessage } from "../auth/auth-messages.js";
5
5
  import { readProviderError, withoutSignInLink } from "../auth/provider-link.js";
6
6
  import { useAuth } from "../auth/auth-provider.js";
7
+ import { ConnectedAppsSection } from "./connected-apps-section.js";
7
8
  import { PasskeysSection } from "./passkeys-section.js";
8
9
  import { SignInProvidersSection } from "./sign-in-providers-section.js";
9
10
  import { TwoFactorSection } from "./two-factor-section.js";
@@ -16,9 +17,12 @@ const takeLinkError = () => {
16
17
  if (code) window.history.replaceState(window.history.state, "", withoutSignInLink(window.location.href));
17
18
  return code;
18
19
  };
19
- /** The signed-in person's passkeys, two-factor authentication and connected accounts, within what the sign-in policy allows. */
20
+ /**
21
+ * The signed-in person's passkeys, two-factor authentication and connected accounts, within what the sign-in policy
22
+ * allows, and with MCP on the apps they allowed to act as them.
23
+ */
20
24
  const AccountSecurityPage = ({ email }) => {
21
- const { session, signInProviders, socialProviders, linkProvider } = useAuth();
25
+ const { session, signInProviders, socialProviders, linkProvider, mcp } = useAuth();
22
26
  const linkable = signInProviders.filter((provider) => socialProviders.includes(provider.id));
23
27
  const { account } = session;
24
28
  const [loaded, setLoaded] = useState();
@@ -28,13 +32,15 @@ const AccountSecurityPage = ({ email }) => {
28
32
  Promise.all([
29
33
  account.signInMethods(),
30
34
  account.passkeys(),
31
- account.linkedProviders()
32
- ]).then(([methods, passkeys, linked]) => setLoaded({
35
+ account.linkedProviders(),
36
+ mcp ? account.connectedApps() : []
37
+ ]).then(([methods, passkeys, linked, apps]) => setLoaded({
33
38
  methods,
34
39
  passkeys,
35
- linked
40
+ linked,
41
+ apps
36
42
  }), (failure) => setError(failure instanceof AuthError ? authMessage(failure) : text("couldNotReadMethods")));
37
- }, [account]);
43
+ }, [account, mcp]);
38
44
  useEffect(reload, [reload]);
39
45
  const thenReload = (change) => change.then((result) => (reload(), result));
40
46
  return /* @__PURE__ */ jsxs("div", {
@@ -68,6 +74,10 @@ const AccountSecurityPage = ({ email }) => {
68
74
  linked: loaded.linked,
69
75
  onConnect: linkProvider,
70
76
  error: linkError && providerMessage(linkError, linkable.length === 1 ? linkable[0].name : text("theProvider"))
77
+ }),
78
+ mcp && /* @__PURE__ */ jsx(ConnectedAppsSection, {
79
+ apps: loaded.apps,
80
+ onDisconnect: (clientId) => thenReload(account.disconnectApp(clientId))
71
81
  })
72
82
  ] }) : error ? /* @__PURE__ */ jsx("p", {
73
83
  role: "alert",
@@ -0,0 +1,93 @@
1
+ import { authMessage } from "../auth/auth-messages.js";
2
+ import { clientName } from "../connect/client-name.js";
3
+ import { clientPublisher } from "../connect/client-publisher.js";
4
+ import { formatDate } from "../format/date.js";
5
+ import { Button } from "../primitives/button.js";
6
+ import { Dialog } from "../primitives/dialog.js";
7
+ import { AccountSection, SectionError } from "./account-section.js";
8
+ import { useState } from "react";
9
+ import { Bot } from "lucide-react";
10
+ import { AuthError } from "@protobase/client";
11
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
12
+ //#region src/account/connected-apps-section.tsx
13
+ const nameOf = (app) => clientName(app.name) ?? "An unnamed app";
14
+ const accessOf = (app) => app.access.map(({ role, organization }) => `as ${role || "no role"}${organization ? ` in ${organization}` : ""}`).join(", ");
15
+ /** The apps, such as MCP clients, the person allowed to act as them, each of which they can disconnect. */
16
+ const ConnectedAppsSection = ({ apps, onDisconnect }) => {
17
+ const [busy, setBusy] = useState(false);
18
+ const [error, setError] = useState();
19
+ const [disconnecting, setDisconnecting] = useState();
20
+ const disconnect = async (app) => {
21
+ setBusy(true);
22
+ setError(void 0);
23
+ try {
24
+ await onDisconnect(app.clientId);
25
+ setDisconnecting(void 0);
26
+ } catch (failure) {
27
+ if (!(failure instanceof AuthError)) throw failure;
28
+ setError(authMessage(failure));
29
+ }
30
+ setBusy(false);
31
+ };
32
+ return /* @__PURE__ */ jsxs(AccountSection, {
33
+ title: "Connected apps",
34
+ description: "AI assistants and other apps you allowed to act as you here. Disconnecting one stops it within 15 minutes; it has to ask you again to come back.",
35
+ children: [
36
+ /* @__PURE__ */ jsx(SectionError, { message: disconnecting ? void 0 : error }),
37
+ apps.length === 0 ? /* @__PURE__ */ jsx("p", {
38
+ className: "text-muted-foreground",
39
+ children: "No apps are connected. Add this app's MCP address to an AI assistant to connect one."
40
+ }) : /* @__PURE__ */ jsx("ul", {
41
+ className: "divide-y rounded-md border",
42
+ children: apps.map((app) => {
43
+ const publisher = clientPublisher(app.clientId);
44
+ return /* @__PURE__ */ jsxs("li", {
45
+ className: "flex flex-wrap items-center gap-3 px-3 py-2.5",
46
+ children: [
47
+ /* @__PURE__ */ jsx(Bot, { className: "size-4 shrink-0 text-muted-foreground" }),
48
+ /* @__PURE__ */ jsxs("span", {
49
+ className: "min-w-0 flex-1",
50
+ children: [/* @__PURE__ */ jsx("bdi", {
51
+ className: "block truncate font-medium",
52
+ children: nameOf(app)
53
+ }), /* @__PURE__ */ jsxs("span", {
54
+ className: "block text-xs text-muted-foreground",
55
+ children: [
56
+ publisher && `Published by ${publisher} · `,
57
+ "Allowed ",
58
+ formatDate(Date.parse(app.allowedAt)),
59
+ " · ",
60
+ accessOf(app)
61
+ ]
62
+ })]
63
+ }),
64
+ /* @__PURE__ */ jsx(Button, {
65
+ size: "sm",
66
+ variant: "ghost",
67
+ onClick: () => setDisconnecting(app),
68
+ children: "Disconnect"
69
+ })
70
+ ]
71
+ }, app.clientId);
72
+ })
73
+ }),
74
+ disconnecting && /* @__PURE__ */ jsx(Dialog, {
75
+ title: `Disconnect ${nameOf(disconnecting)}?`,
76
+ description: "It can no longer read or change anything as you. What it already started may keep working for up to 15 minutes.",
77
+ onClose: () => setDisconnecting(void 0),
78
+ actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Button, {
79
+ onClick: () => setDisconnecting(void 0),
80
+ children: "Cancel"
81
+ }), /* @__PURE__ */ jsx(Button, {
82
+ variant: "danger",
83
+ loading: busy,
84
+ onClick: () => void disconnect(disconnecting),
85
+ children: "Disconnect"
86
+ })] }),
87
+ children: error && /* @__PURE__ */ jsx(SectionError, { message: error })
88
+ })
89
+ ]
90
+ });
91
+ };
92
+ //#endregion
93
+ export { ConnectedAppsSection };
package/dist/app/app.js CHANGED
@@ -3,12 +3,16 @@ import { accountMenuItems } from "../account/account-pages.js";
3
3
  import { AppShell } from "../app-shell/app-shell.js";
4
4
  import { AuthProvider, useAuth } from "../auth/auth-provider.js";
5
5
  import { AccountSecurityPage } from "../account/account-security-page.js";
6
- import { SignInPolicyPage } from "../account/sign-in-policy-page.js";
7
- import { ApiProvider } from "../data/api-provider.js";
8
6
  import { text } from "./messages.js";
9
7
  import { Router, useRouter } from "./router.js";
10
- import { slotted } from "../locale/slotted.js";
11
8
  import { useSignInAddress } from "../auth/use-sign-in-address.js";
9
+ import { SignInPrompt } from "../auth/sign-in-prompt.js";
10
+ import { ApiProvider } from "../data/api-provider.js";
11
+ import { sourceStatusOf } from "../data/with-sources.js";
12
+ import { MetaGate, Notice, useAdminMeta } from "./meta-gate.js";
13
+ import { ConnectPage } from "../connect/connect-page.js";
14
+ import { SignInPolicyPage } from "../account/sign-in-policy-page.js";
15
+ import { slotted } from "../locale/slotted.js";
12
16
  import { managesOrganization, organizationMenuItems, organizationPageTitle } from "../organizations/organization-paths.js";
13
17
  import { startErrorReporting } from "./error-reporting.js";
14
18
  import { CustomBoundary } from "./pages/custom-boundary.js";
@@ -16,13 +20,11 @@ import { PluginSourceProvider } from "../plugins/plugin-source.js";
16
20
  import { AuthGate } from "../auth/auth-gate.js";
17
21
  import { isAdmin, userToShell } from "../auth/user-to-shell.js";
18
22
  import { AuthLocale } from "../auth/auth-locale.js";
19
- import { sourceStatusOf } from "../data/with-sources.js";
20
23
  import { useLiveUpdates } from "../data/use-live-updates.js";
21
24
  import { useOpenedRecord } from "../data/use-record.js";
22
25
  import { humanize } from "../live/naming.js";
23
26
  import { ToastProvider } from "../toasts/toast-provider.js";
24
27
  import { recordTitle } from "../live/model-helpers.js";
25
- import { MetaGate, Notice, useAdminMeta } from "./meta-gate.js";
26
28
  import { useAppAddress } from "./use-app-address.js";
27
29
  import { documentTitle, titleParts, useDocumentTitle } from "./document-title.js";
28
30
  import { ProjectUiContext, useProjectUi } from "./pages/project-ui.js";
@@ -56,6 +58,7 @@ import { useNavRecent } from "./use-nav-recent.js";
56
58
  import { useCallback, useEffect, useState } from "react";
57
59
  import { viewOfList } from "@protobase/schema/internal";
58
60
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
61
+ import { connectRoute } from "@protobase/schema";
59
62
  //#region src/app/app.tsx
60
63
  const placeOf = (address) => {
61
64
  if (address?.kind === "page") return address.page;
@@ -63,6 +66,10 @@ const placeOf = (address) => {
63
66
  return address?.resource;
64
67
  };
65
68
  const recordOf = (address) => address?.kind === "record" ? address : void 0;
69
+ const connectPrompt = {
70
+ title: "Sign in to connect an app",
71
+ description: "An app asks to act as you here. Sign in, then choose whether to allow it."
72
+ };
66
73
  const Routes = ({ workspace, sidebarMode, assistant, runtime }) => {
67
74
  const meta = useAdminMeta();
68
75
  const { state, session, signOut, stopStaffSession, organizations: organizationSettings } = useAuth();
@@ -141,7 +148,7 @@ const Routes = ({ workspace, sidebarMode, assistant, runtime }) => {
141
148
  const current = organizations.current;
142
149
  const outsideOrganizations = Boolean(organizationSettings) && current !== void 0 && !current.organization;
143
150
  const organizationPage = organizationSettings && user ? organizationPageTitle(path) : void 0;
144
- const accountPage = !user ? void 0 : path === "/-/account" ? text("signInSecurity") : path === "/-/sign-in-policy" ? text("signInPolicy") : organizationPage;
151
+ const accountPage = path === connectRoute ? "Connect an app" : !user ? void 0 : path === "/-/account" ? text("signInSecurity") : path === "/-/sign-in-policy" ? text("signInPolicy") : organizationPage;
145
152
  const resourceLabel = view?.names?.plural ?? (resource && humanize(resource));
146
153
  const breadcrumb = accountPage ? [accountPage] : breadcrumbFor({
147
154
  basePath,
@@ -162,7 +169,13 @@ const Routes = ({ workspace, sidebarMode, assistant, runtime }) => {
162
169
  recordTitle: title,
163
170
  recordLoading: titleLoading
164
171
  }), meta.appName));
165
- const content = user && path === "/-/account" ? /* @__PURE__ */ jsx(AccountSecurityPage, { email: user.email }) : user && path === "/-/sign-in-policy" ? admin ? /* @__PURE__ */ jsx(SignInPolicyPage, {}) : /* @__PURE__ */ jsx(Notice, {
172
+ const content = path === connectRoute ? user ? /* @__PURE__ */ jsx(ConnectPage, {
173
+ email: user.email,
174
+ appName: meta.appName ?? "this app"
175
+ }) : /* @__PURE__ */ jsx(SignInPrompt, {
176
+ as: "page",
177
+ prompt: connectPrompt
178
+ }) : user && path === "/-/account" ? /* @__PURE__ */ jsx(AccountSecurityPage, { email: user.email }) : user && path === "/-/sign-in-policy" ? admin ? /* @__PURE__ */ jsx(SignInPolicyPage, {}) : /* @__PURE__ */ jsx(Notice, {
166
179
  title: text("adminsOnly"),
167
180
  children: text("onlyAdminPolicy")
168
181
  }) : organizationPage && path === "/-/organization" ? /* @__PURE__ */ jsx(OrganizationPage, {
@@ -1,7 +1,7 @@
1
1
  import { Skeleton } from "../../primitives/skeleton.js";
2
2
  import { viewerZone } from "../../format/zone.js";
3
- import { labelFieldOf } from "../../live/model-helpers.js";
4
3
  import { useAdminMeta } from "../meta-gate.js";
4
+ import { labelFieldOf } from "../../live/model-helpers.js";
5
5
  import { useAggregate } from "../../data/use-aggregates.js";
6
6
  import { text } from "./messages.js";
7
7
  import { periodPoints, valueSlices } from "./chart-groups.js";
@@ -1,8 +1,8 @@
1
- import { useClient } from "../../data/api-provider.js";
2
1
  import { text } from "../messages.js";
2
+ import { useClient } from "../../data/api-provider.js";
3
+ import { Notice, useAdminMeta, usePermissions } from "../meta-gate.js";
3
4
  import { humanize } from "../../live/naming.js";
4
5
  import { recordKey } from "../../live/model-helpers.js";
5
- import { Notice, useAdminMeta, usePermissions } from "../meta-gate.js";
6
6
  import { useAppAddress } from "../use-app-address.js";
7
7
  import { text as text$1 } from "./messages.js";
8
8
  import { createBody, createSections, hasDatabaseDefault, initialDraft, isChosen, isRequired } from "./create-values.js";
@@ -1,5 +1,5 @@
1
- import { humanize } from "../../live/naming.js";
2
1
  import { Notice, useAdminMeta } from "../meta-gate.js";
2
+ import { humanize } from "../../live/naming.js";
3
3
  import { text } from "./messages.js";
4
4
  import { ComposedPage } from "../pages/composed-page.js";
5
5
  import { CreatePage } from "./create-page.js";
@@ -1,7 +1,7 @@
1
1
  import { useClient } from "../../data/api-provider.js";
2
+ import { useAdminMeta } from "../meta-gate.js";
2
3
  import { humanize } from "../../live/naming.js";
3
4
  import { useToast } from "../../toasts/toast-provider.js";
4
- import { useAdminMeta } from "../meta-gate.js";
5
5
  import { useAppAddress } from "../use-app-address.js";
6
6
  import { text } from "./messages.js";
7
7
  import { blockedDelete } from "./blocked-delete.js";
@@ -1,8 +1,8 @@
1
+ import { usePermissions } from "../meta-gate.js";
1
2
  import { slotted } from "../../locale/slotted.js";
2
3
  import { Problem } from "../pages/problem.js";
3
4
  import { text } from "./messages.js";
4
5
  import { boardCard, boardColumns, boardRank } from "./board-columns.js";
5
- import { usePermissions } from "../meta-gate.js";
6
6
  import { useProjectUi } from "../pages/project-ui.js";
7
7
  import { can } from "../permissions.js";
8
8
  import { RecordCard } from "./record-card.js";
@@ -2,8 +2,8 @@ import { cn } from "../../lib/cn.js";
2
2
  import { Skeleton } from "../../primitives/skeleton.js";
3
3
  import { dayIn, viewerZone } from "../../format/zone.js";
4
4
  import { formatDate, formatWeekday } from "../../format/date.js";
5
- import { text } from "./messages.js";
6
5
  import { usePermissions } from "../meta-gate.js";
6
+ import { text } from "./messages.js";
7
7
  import { AppLink } from "../use-app-address.js";
8
8
  import { ErrorBanner } from "../error-banner.js";
9
9
  import { can, rowAllows } from "../permissions.js";
@@ -1,11 +1,11 @@
1
1
  import { formatTag } from "../../locale/active-locale.js";
2
2
  import { cn } from "../../lib/cn.js";
3
3
  import { Button } from "../../primitives/button.js";
4
+ import { useAdminMeta } from "../meta-gate.js";
4
5
  import { Problem } from "../pages/problem.js";
5
6
  import { humanize } from "../../live/naming.js";
6
7
  import { text } from "./messages.js";
7
8
  import { mapCards } from "./list-displays.js";
8
- import { useAdminMeta } from "../meta-gate.js";
9
9
  import { ErrorBanner } from "../error-banner.js";
10
10
  import { useDebounced } from "../../lib/use-debounced.js";
11
11
  import { RecordCard } from "./record-card.js";
@@ -1,4 +1,5 @@
1
1
  import { Badge } from "../../primitives/badge.js";
2
+ import { namedIcon } from "../named-icon.js";
2
3
  import { CustomBoundary } from "../pages/custom-boundary.js";
3
4
  import { humanize } from "../../live/naming.js";
4
5
  import { markdownExcerpt } from "../../markdown/markdown-excerpt.js";
@@ -14,7 +15,6 @@ import { WidgetPart } from "../field-types/widget-part.js";
14
15
  import { Markdown } from "../../markdown/markdown.js";
15
16
  import { ValueBadge } from "../value-badge.js";
16
17
  import { useSeedRecord } from "../record-preview.js";
17
- import { namedIcon } from "../named-icon.js";
18
18
  import { FavoriteButton } from "../saved/favorite-button.js";
19
19
  import { CardDots, CardDotsRoom } from "../related-dots/card-dots.js";
20
20
  import { cardDotsLines } from "../related-dots/card-dots-lines.js";
@@ -1,9 +1,9 @@
1
1
  import { Skeleton } from "../../primitives/skeleton.js";
2
2
  import { dayIn, viewerZone } from "../../format/zone.js";
3
3
  import { formatDate } from "../../format/date.js";
4
+ import { usePermissions } from "../meta-gate.js";
4
5
  import { humanize } from "../../live/naming.js";
5
6
  import { text } from "./messages.js";
6
- import { usePermissions } from "../meta-gate.js";
7
7
  import { ErrorBanner } from "../error-banner.js";
8
8
  import { can, rowAllows } from "../permissions.js";
9
9
  import { addDays, inStartOrder, recordDays } from "./calendar-range.js";
@@ -1,5 +1,5 @@
1
- import { columnFilter } from "./board-columns.js";
2
1
  import { useAdminMeta } from "../meta-gate.js";
2
+ import { columnFilter } from "./board-columns.js";
3
3
  import { useLiveRows } from "../../live/use-live-rows.js";
4
4
  import { useDisplayRows } from "./use-display-rows.js";
5
5
  //#region src/app/displays/use-board-column.ts
@@ -1,8 +1,8 @@
1
1
  import { keys } from "../../data/query-keys.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
+ import { useAdminMeta } from "../meta-gate.js";
3
4
  import { listPhotos, withPhotos } from "../../live/row-photos.js";
4
5
  import { displayRow } from "./list-displays.js";
5
- import { useAdminMeta } from "../meta-gate.js";
6
6
  import { listLabels, withLabels } from "../../live/relation-labels.js";
7
7
  import { areaFilter, requestZoom } from "../map/map-area.js";
8
8
  import { keepPreviousData, useQuery } from "@tanstack/react-query";
@@ -1,10 +1,10 @@
1
1
  import { useIsDesktop, useIsXs } from "../../lib/use-media-query.js";
2
2
  import { Skeleton } from "../../primitives/skeleton.js";
3
+ import { useAdminMeta, usePermissions } from "../meta-gate.js";
3
4
  import { humanize } from "../../live/naming.js";
4
5
  import { listColumnNames } from "../../live/columns-from-model.js";
5
6
  import { displayRow, loadedFields, shownDisplay } from "../displays/list-displays.js";
6
7
  import { defaultOrderBy, parseSort, sortToOrderBy } from "../list-order.js";
7
- import { useAdminMeta, usePermissions } from "../meta-gate.js";
8
8
  import { AppLink, useAppAddress } from "../use-app-address.js";
9
9
  import { ErrorBanner } from "../error-banner.js";
10
10
  import { useProjectUi } from "../pages/project-ui.js";
@@ -1,8 +1,8 @@
1
1
  import { keys } from "../../data/query-keys.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
+ import { useAdminMeta } from "../meta-gate.js";
3
4
  import { recordId } from "../../live/model-helpers.js";
4
5
  import { listPhotos, withPhotos } from "../../live/row-photos.js";
5
- import { useAdminMeta } from "../meta-gate.js";
6
6
  import { listLabels, withLabels } from "../../live/relation-labels.js";
7
7
  import { keepPreviousData, useQuery } from "@tanstack/react-query";
8
8
  //#region src/app/embedded-list/use-embedded-rows.ts
@@ -1,8 +1,8 @@
1
1
  import { Segmented } from "../../primitives/segmented.js";
2
2
  import { formatApproxRows, formatInt } from "../../format/number.js";
3
3
  import { Button } from "../../primitives/button.js";
4
- import { Checkbox } from "../../primitives/checkbox.js";
5
4
  import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
5
+ import { Checkbox } from "../../primitives/checkbox.js";
6
6
  import { text } from "./messages.js";
7
7
  import { exportLimit } from "./export-options.js";
8
8
  import { useState } from "react";
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../lib/cn.js";
2
2
  import { Button } from "../primitives/button.js";
3
- import { useClient } from "../data/api-provider.js";
4
3
  import { text } from "./messages.js";
4
+ import { useClient } from "../data/api-provider.js";
5
5
  import { humanize } from "../live/naming.js";
6
6
  import { acceptOf, fileShown, formatSize, isPreviewable, shownImage } from "../live/file-values.js";
7
7
  import { ErrorBanner } from "./error-banner.js";
@@ -1,9 +1,9 @@
1
1
  import { cn } from "../../lib/cn.js";
2
2
  import { Skeleton } from "../../primitives/skeleton.js";
3
+ import { useAdminMeta, usePermissions } from "../meta-gate.js";
3
4
  import { humanize } from "../../live/naming.js";
4
5
  import { Section } from "../../record-view/section.js";
5
6
  import { shownImage } from "../../live/file-values.js";
6
- import { useAdminMeta, usePermissions } from "../meta-gate.js";
7
7
  import { ErrorBanner } from "../error-banner.js";
8
8
  import { FileImage } from "../../live/file-image.js";
9
9
  import { galleryTiles } from "./gallery-layout.js";
@@ -1,9 +1,9 @@
1
1
  import { cn } from "../../lib/cn.js";
2
2
  import { useIsDesktop } from "../../lib/use-media-query.js";
3
3
  import { useFocusTrap } from "../../lib/use-focus-trap.js";
4
+ import { Sheet } from "../../primitives/sheet.js";
4
5
  import { shownImage } from "../../live/file-values.js";
5
6
  import { FileImage } from "../../live/file-image.js";
6
- import { Sheet } from "../../primitives/sheet.js";
7
7
  import { keyStep, steppedPhoto, swipeStep, togglesDetails } from "./gallery-layout.js";
8
8
  import { readDetailsOpen, writeDetailsOpen } from "./details-open-storage.js";
9
9
  import { text } from "./messages.js";
@@ -2,8 +2,8 @@ import { keys } from "../../data/query-keys.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
3
  import { useAdminMeta } from "../meta-gate.js";
4
4
  import { galleryItems } from "./gallery-items.js";
5
- import { useQuery } from "@tanstack/react-query";
6
5
  import { createWhere, printFilter } from "@protobase/schema";
6
+ import { useQuery } from "@tanstack/react-query";
7
7
  //#region src/app/gallery/use-gallery-photos.ts
8
8
  const where$1 = createWhere();
9
9
  /**
@@ -1,9 +1,9 @@
1
1
  import { Skeleton } from "../../primitives/skeleton.js";
2
+ import { useAdminMeta } from "../meta-gate.js";
2
3
  import { slotted } from "../../locale/slotted.js";
3
4
  import { Problem } from "../pages/problem.js";
4
5
  import { recordKey, recordTitle } from "../../live/model-helpers.js";
5
6
  import { loadedFields } from "../displays/list-displays.js";
6
- import { useAdminMeta } from "../meta-gate.js";
7
7
  import { useAppAddress } from "../use-app-address.js";
8
8
  import { ErrorBanner } from "../error-banner.js";
9
9
  import { useProjectUi } from "../pages/project-ui.js";
@@ -1,10 +1,10 @@
1
1
  import { keys } from "../../data/query-keys.js";
2
2
  import { useClient } from "../../data/api-provider.js";
3
+ import { useAdminMeta } from "../meta-gate.js";
3
4
  import { useToast } from "../../toasts/toast-provider.js";
4
5
  import { recordId, recordKey, recordTitle } from "../../live/model-helpers.js";
5
6
  import { refusalReason } from "../displays/board-columns.js";
6
7
  import { displayRow } from "../displays/list-displays.js";
7
- import { useAdminMeta } from "../meta-gate.js";
8
8
  import { useRefreshResource } from "../pages/use-layout-data.js";
9
9
  import { listLabels, withLabels } from "../../live/relation-labels.js";
10
10
  import { text } from "./messages.js";
@@ -1,8 +1,8 @@
1
1
  import { formatTag } from "../../locale/active-locale.js";
2
2
  import { Button } from "../../primitives/button.js";
3
+ import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
3
4
  import { humanize } from "../../live/naming.js";
4
5
  import { ErrorBanner } from "../error-banner.js";
5
- import { ResponsiveDialog } from "../../primitives/responsive-dialog.js";
6
6
  import { text } from "./messages.js";
7
7
  import { unmappedRequired } from "./mapping.js";
8
8
  import { ImportCheckStep, ImportChecking } from "./import-check-step.js";
@@ -1,7 +1,7 @@
1
1
  import { Skeleton } from "../primitives/skeleton.js";
2
2
  import { formatInt } from "../format/number.js";
3
- import { SidebarCard } from "../record-view/record-sidebar.js";
4
3
  import { useAdminMeta } from "./meta-gate.js";
4
+ import { SidebarCard } from "../record-view/record-sidebar.js";
5
5
  import { AppLink } from "./use-app-address.js";
6
6
  import { text } from "./record-messages.js";
7
7
  import { incomingAddress, incomingRelations } from "./incoming-relations.js";
@@ -3,7 +3,10 @@ import { usePageScroll } from "../app-shell/page-scroll.js";
3
3
  import { PageHeader } from "../app-shell/page-header.js";
4
4
  import { useAuth } from "../auth/auth-provider.js";
5
5
  import { Button, buttonClass } from "../primitives/button.js";
6
+ import { Sheet } from "../primitives/sheet.js";
6
7
  import { text } from "./messages.js";
8
+ import { SignInPrompt } from "../auth/sign-in-prompt.js";
9
+ import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
7
10
  import { humanize } from "../live/naming.js";
8
11
  import { recordKey, recordTitleField } from "../live/model-helpers.js";
9
12
  import { columnsFromModel, listColumnNames } from "../live/columns-from-model.js";
@@ -11,11 +14,9 @@ import { boardRank } from "./displays/board-columns.js";
11
14
  import { displayRow, listDisplayChoices, loadedFields, shownListDisplay } from "./displays/list-displays.js";
12
15
  import { parseSort, sortToOrderBy } from "./list-order.js";
13
16
  import { listedResource } from "./current-address.js";
14
- import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
15
17
  import { AppLink, useAppAddress } from "./use-app-address.js";
16
18
  import { ErrorBanner } from "./error-banner.js";
17
19
  import { useProjectUi } from "./pages/project-ui.js";
18
- import { Sheet } from "../primitives/sheet.js";
19
20
  import { can, rowAllows } from "./permissions.js";
20
21
  import { pinnedStorageKey } from "../data-grid/pinned-storage.js";
21
22
  import { DataGrid } from "../data-grid/data-grid.js";
@@ -29,7 +30,6 @@ import { stateToText, textToState } from "../live/filter-string.js";
29
30
  import { widgetFields } from "../live/view-fields.js";
30
31
  import { facetNames, filterChips } from "./searches/saved-search.js";
31
32
  import { useSeedRecord } from "./record-preview.js";
32
- import { SignInPrompt } from "../auth/sign-in-prompt.js";
33
33
  import { relatedColumnLoads } from "./related-dots/dot-card.js";
34
34
  import { dragsRank, listHandOrder } from "./hand-order/hand-order.js";
35
35
  import { useDisplayRows } from "./displays/use-display-rows.js";
@@ -1,6 +1,6 @@
1
+ import { useAdminMeta } from "../meta-gate.js";
1
2
  import { Section } from "../../record-view/section.js";
2
3
  import { SidebarCard } from "../../record-view/record-sidebar.js";
3
- import { useAdminMeta } from "../meta-gate.js";
4
4
  import { recordPosition } from "./record-position.js";
5
5
  import { Suspense, lazy } from "react";
6
6
  import { jsx } from "react/jsx-runtime";
@@ -1,11 +1,11 @@
1
1
  import { Spinner } from "../primitives/spinner.js";
2
2
  import { ClientProvider, useClient, useSourceClients } from "../data/api-provider.js";
3
- import { AppLocale } from "../locale/app-locale.js";
4
- import { withSources } from "../data/with-sources.js";
5
3
  import { MetaContext } from "../data/meta-context.js";
6
4
  import { allowEverything } from "../data/meta-data.js";
7
5
  import { useMeta } from "../data/use-meta.js";
8
6
  import { useSourceMetas } from "../data/use-source-metas.js";
7
+ import { withSources } from "../data/with-sources.js";
8
+ import { AppLocale } from "../locale/app-locale.js";
9
9
  import { text } from "./meta-gate-messages.js";
10
10
  import { useContext, useMemo } from "react";
11
11
  import { isApiError, routedClient } from "@protobase/client";
@@ -1,12 +1,12 @@
1
1
  import { Button } from "../../../primitives/button.js";
2
+ import { ResponsiveDialog } from "../../../primitives/responsive-dialog.js";
3
+ import { useAdminMeta } from "../../meta-gate.js";
2
4
  import { text } from "../messages.js";
3
5
  import { Field } from "../../../record-view/field.js";
4
- import { useAdminMeta } from "../../meta-gate.js";
5
6
  import { isChosen } from "../../create/create-values.js";
6
7
  import { ErrorBanner } from "../../error-banner.js";
7
8
  import { useProjectUi } from "../project-ui.js";
8
9
  import { FieldEditor } from "../../field-editor.js";
9
- import { ResponsiveDialog } from "../../../primitives/responsive-dialog.js";
10
10
  import { answeredValues, inputField, inputHints, refusedAnswers, startingAnswers } from "./input-answers.js";
11
11
  import { inputErrors } from "./input-errors.js";
12
12
  import { useId, useState } from "react";
@@ -1,6 +1,6 @@
1
1
  import { Skeleton } from "../../../primitives/skeleton.js";
2
- import { text } from "../messages.js";
3
2
  import { useAdminMeta } from "../../meta-gate.js";
3
+ import { text } from "../messages.js";
4
4
  import { ErrorBanner } from "../../error-banner.js";
5
5
  import { RecordScope } from "../record-scope.js";
6
6
  import { scopeOf, useListPage } from "../use-layout-data.js";
@@ -1,6 +1,6 @@
1
1
  import { Skeleton } from "../../../primitives/skeleton.js";
2
- import { humanize } from "../../../live/naming.js";
3
2
  import { useAdminMeta } from "../../meta-gate.js";
3
+ import { humanize } from "../../../live/naming.js";
4
4
  import { useLayoutRecord } from "../record-scope.js";
5
5
  import { propsOf } from "./block-props.js";
6
6
  import { FieldValue } from "../field-value.js";
@@ -1,11 +1,11 @@
1
1
  import { Button } from "../../../primitives/button.js";
2
2
  import { Dialog } from "../../../primitives/dialog.js";
3
3
  import { useClient } from "../../../data/api-provider.js";
4
+ import { useAdminMeta, usePermissions } from "../../meta-gate.js";
4
5
  import { text } from "../messages.js";
5
6
  import { humanize } from "../../../live/naming.js";
6
7
  import { useToast } from "../../../toasts/toast-provider.js";
7
8
  import { Field } from "../../../record-view/field.js";
8
- import { useAdminMeta, usePermissions } from "../../meta-gate.js";
9
9
  import { differs, toDraft, toPatchValue } from "../../../live/field-values.js";
10
10
  import { createBody, isChosen } from "../../create/create-values.js";
11
11
  import { ErrorBanner } from "../../error-banner.js";
@@ -1,6 +1,6 @@
1
1
  import { Skeleton } from "../../../primitives/skeleton.js";
2
- import { text } from "../messages.js";
3
2
  import { useAdminMeta } from "../../meta-gate.js";
3
+ import { text } from "../messages.js";
4
4
  import { ErrorBanner } from "../../error-banner.js";
5
5
  import { RecordScope } from "../record-scope.js";
6
6
  import { useFirstRecord } from "../use-layout-data.js";
@@ -1,6 +1,6 @@
1
+ import { useAdminMeta } from "../../meta-gate.js";
1
2
  import { SectionContent } from "../../../record-view/section.js";
2
3
  import { listColumnNames } from "../../../live/columns-from-model.js";
3
- import { useAdminMeta } from "../../meta-gate.js";
4
4
  import { propsOf } from "./block-props.js";
5
5
  import { RelatedCards } from "../../related-cards/related-cards.js";
6
6
  import { jsx } from "react/jsx-runtime";
@@ -1,7 +1,7 @@
1
1
  import { formatTag } from "../../../locale/active-locale.js";
2
2
  import { Skeleton } from "../../../primitives/skeleton.js";
3
- import { text } from "../messages.js";
4
3
  import { useAdminMeta } from "../../meta-gate.js";
4
+ import { text } from "../messages.js";
5
5
  import { AppLink } from "../../use-app-address.js";
6
6
  import { useLayoutRecord } from "../record-scope.js";
7
7
  import { useCount } from "../use-layout-data.js";
@@ -1,6 +1,6 @@
1
+ import { Notice, useAdminMeta } from "../meta-gate.js";
1
2
  import { slotted } from "../../locale/slotted.js";
2
3
  import { text } from "./messages.js";
3
- import { Notice, useAdminMeta } from "../meta-gate.js";
4
4
  import { RenderNode } from "./render-node.js";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/app/pages/composed-page.tsx