@protobase/ui 0.19.0 → 0.19.2

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 (53) hide show
  1. package/dist/app/app.d.ts +2 -2
  2. package/dist/app/app.js +14 -9
  3. package/dist/app/custom-section.js +1 -1
  4. package/dist/app/displays/custom-display.js +1 -1
  5. package/dist/app/displays/map-display.js +1 -1
  6. package/dist/app/displays/record-card.js +1 -1
  7. package/dist/app/favicon.svg +1 -0
  8. package/dist/app/pages/merge-ui.d.ts +1 -1
  9. package/dist/app/pages/merge-ui.js +16 -4
  10. package/dist/app/pages/project-ui.d.ts +30 -5
  11. package/dist/app/pages/project-ui.js +3 -3
  12. package/dist/app/pages/render-node.js +1 -1
  13. package/dist/app/project-logo.js +17 -0
  14. package/dist/app-shell/app-shell.d.ts +1 -1
  15. package/dist/app-shell/app-shell.js +3 -2
  16. package/dist/app-shell/index.d.ts +1 -0
  17. package/dist/app-shell/logo.d.ts +11 -0
  18. package/dist/app-shell/logo.js +30 -32
  19. package/dist/app-shell/sidebar.d.ts +2 -1
  20. package/dist/app-shell/sidebar.js +3 -3
  21. package/dist/app-shell/wordmark-path.js +4 -0
  22. package/dist/assistant-dock/widget-view.js +1 -1
  23. package/dist/auth/auth-gate.js +7 -1
  24. package/dist/auth/auth-layout.d.ts +10 -0
  25. package/dist/auth/auth-provider.js +10 -0
  26. package/dist/auth/code-form.d.ts +29 -0
  27. package/dist/auth/resend-code-button.d.ts +11 -0
  28. package/dist/index.d.ts +9 -2
  29. package/dist/index.js +12 -5
  30. package/dist/package.js +1 -1
  31. package/dist/plugins/before-sign-in.js +49 -0
  32. package/dist/plugins/plugin-gate.js +8 -8
  33. package/dist/plugins/plugin-source.js +32 -0
  34. package/dist/plugins/plugin-ui.js +5 -3
  35. package/dist/plugins/use-plugin-loads.js +3 -4
  36. package/dist/primitives/button.d.ts +11 -0
  37. package/dist/primitives/input.d.ts +11 -0
  38. package/dist/primitives/spinner.d.ts +5 -0
  39. package/dist/shell/assets/app-Rbouc_gR.js +66 -0
  40. package/dist/shell/assets/{index-CLXqLf4p.js → index-Crd6_WsY.js} +1 -1
  41. package/dist/shell/assets/index-DaFzUWmg.css +2 -0
  42. package/dist/shell/assets/maplibre-Gu5hHDDK.js +814 -0
  43. package/dist/shell/assets/{record-map-Bvls7qdn.js → record-map-DQ0oyZff.js} +1 -1
  44. package/dist/shell/assets/records-map-Dp97bL3p.js +1 -0
  45. package/dist/shell/assets/shared-protobase-ui-DvvdY2OO.js +1 -0
  46. package/dist/shell/index.html +5 -4
  47. package/dist/shell/protobase.shell.json +1 -1
  48. package/package.json +6 -5
  49. package/dist/shell/assets/app-BS7ufaBT.js +0 -66
  50. package/dist/shell/assets/index-BLnOMDD8.css +0 -2
  51. package/dist/shell/assets/maplibre-r-WEXdlV.js +0 -814
  52. package/dist/shell/assets/records-map-iNBfciYy.js +0 -1
  53. package/dist/shell/assets/shared-protobase-ui-9PLdWR62.js +0 -1
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import { LogoMark, ShellLogoProps } from "./app-shell/logo.js";
1
2
  import { FieldWidget, FieldWidgetEditorProps, FieldWidgetProps } from "./app/field-types/field-widget.js";
2
- import { ActionContext, ActionHandler, ProjectUi, definePlugin, defineUi } from "./app/pages/project-ui.js";
3
+ import { ActionContext, ActionHandler, BeforeSignInProps, ProjectUi, definePlugin, defineUi } from "./app/pages/project-ui.js";
3
4
  import { PluginInfo, usePlugin } from "./plugins/plugin-context.js";
4
5
  import { App, AppProps } from "./app/app.js";
5
6
  import "./app/index.js";
@@ -42,4 +43,10 @@ import { Step, StepList, StepState } from "./step-list/step-list.js";
42
43
  import { DiffView, DiffViewProps } from "./diff-view/diff-view.js";
43
44
  import { DiffLine, diffStats, parseDiff } from "./diff-view/diff.js";
44
45
  import { CompactTable, CompactTableProps } from "./compact-table/compact-table.js";
45
- export { ActionCard, type ActionCardProps, type ActionContext, type ActionHandler, ApiProvider, type ApiProviderProps, App, AppLink, type AppProps, AssistantDock, type AssistantDockProps, type BackendData, type BackendRefresh, type CardAction, type CardTone, ChatMessage, ChatThread, type ChatThreadProps, CompactTable, type CompactTableProps, Composer, type ComposerProps, type CurrentAddress, type DiffLine, DiffView, type DiffViewProps, FieldList, type FieldWidget, type FieldWidgetEditorProps, type FieldWidgetProps, type LayoutRecord, type ListAddress, type ListChange, type ListDisplay, type ListDisplayRow, type MetaData, OtpInput, type OtpInputProps, PartView, type PluginInfo, type ProjectUi, type RecordCardProps, RecordLink, ResponsiveDialog, type ResponsiveDialogProps, SidePanel, type SidePanelProps, SignInPrompt, type SignInPromptProps, type Step, StepList, type StepState, definePlugin, defineUi, diffStats, isConflict, mergeUi, parseDiff, pluginApi, protobaseVersion, uiFromModule, useApiToken, useAppAddress, useAssistant, useAssistantClient, useBackendData, useClient, useFacets, useHistogram, useLayoutRecord, useList, useListDisplay, useMeta, usePlugin, useRecord, useResourceClient, useSeries, useUpdateRecord };
46
+ import { AuthLayout, AuthLayoutProps } from "./auth/auth-layout.js";
47
+ import { CodeForm, CodeFormProps } from "./auth/code-form.js";
48
+ import { ResendCodeButton, ResendCodeButtonProps } from "./auth/resend-code-button.js";
49
+ import { Button, ButtonProps, buttonClass } from "./primitives/button.js";
50
+ import { Input, InputProps } from "./primitives/input.js";
51
+ import { Spinner } from "./primitives/spinner.js";
52
+ export { ActionCard, type ActionCardProps, type ActionContext, type ActionHandler, ApiProvider, type ApiProviderProps, App, AppLink, type AppProps, AssistantDock, type AssistantDockProps, AuthLayout, type AuthLayoutProps, type BackendData, type BackendRefresh, type BeforeSignInProps, Button, type ButtonProps, type CardAction, type CardTone, ChatMessage, ChatThread, type ChatThreadProps, CodeForm, type CodeFormProps, CompactTable, type CompactTableProps, Composer, type ComposerProps, type CurrentAddress, type DiffLine, DiffView, type DiffViewProps, FieldList, type FieldWidget, type FieldWidgetEditorProps, type FieldWidgetProps, Input, type InputProps, type LayoutRecord, type ListAddress, type ListChange, type ListDisplay, type ListDisplayRow, LogoMark, type MetaData, OtpInput, type OtpInputProps, PartView, type PluginInfo, type ProjectUi, type RecordCardProps, RecordLink, ResendCodeButton, type ResendCodeButtonProps, ResponsiveDialog, type ResponsiveDialogProps, type ShellLogoProps, SidePanel, type SidePanelProps, SignInPrompt, type SignInPromptProps, Spinner, type Step, StepList, type StepState, buttonClass, definePlugin, defineUi, diffStats, isConflict, mergeUi, parseDiff, pluginApi, protobaseVersion, uiFromModule, useApiToken, useAppAddress, useAssistant, useAssistantClient, useBackendData, useClient, useFacets, useHistogram, useLayoutRecord, useList, useListDisplay, useMeta, usePlugin, useRecord, useResourceClient, useSeries, useUpdateRecord };
package/dist/index.js CHANGED
@@ -1,5 +1,16 @@
1
+ import { LogoMark } from "./app-shell/logo.js";
2
+ import { Input } from "./primitives/input.js";
3
+ import { Spinner } from "./primitives/spinner.js";
4
+ import { Button, buttonClass } from "./primitives/button.js";
1
5
  import { OtpInput } from "./primitives/otp-input.js";
2
6
  import { ApiProvider, useClient, useResourceClient } from "./data/api-provider.js";
7
+ import { AuthLayout } from "./auth/auth-layout.js";
8
+ import { ResendCodeButton } from "./auth/resend-code-button.js";
9
+ import { CodeForm } from "./auth/code-form.js";
10
+ import { uiFromModule } from "./app/pages/ui-from-module.js";
11
+ import { mergeUi } from "./app/pages/merge-ui.js";
12
+ import { usePlugin } from "./plugins/plugin-context.js";
13
+ import { pluginApi, protobaseVersion } from "./plugins/plugin-api.js";
3
14
  import { useApiToken } from "./auth/use-api-token.js";
4
15
  import { useRecord } from "./data/use-record.js";
5
16
  import { ChatMessage } from "./chat/chat-message.js";
@@ -25,12 +36,8 @@ import { SignInPrompt } from "./auth/sign-in-prompt.js";
25
36
  import { useListDisplay } from "./app/displays/display-context.js";
26
37
  import { useFacets, useHistogram, useSeries } from "./data/use-aggregates.js";
27
38
  import { useLayoutRecord } from "./app/pages/record-scope.js";
28
- import { uiFromModule } from "./app/pages/ui-from-module.js";
29
- import { mergeUi } from "./app/pages/merge-ui.js";
30
- import { usePlugin } from "./plugins/plugin-context.js";
31
- import { pluginApi, protobaseVersion } from "./plugins/plugin-api.js";
32
39
  import { useList } from "./data/use-list.js";
33
40
  import { isConflict, useUpdateRecord } from "./data/use-update-record.js";
34
41
  import { App } from "./app/app.js";
35
42
  import { RecordLink } from "./app/displays/record-link.js";
36
- export { ActionCard, ApiProvider, App, AppLink, AssistantDock, ChatMessage, ChatThread, CompactTable, Composer, DiffView, FieldList, OtpInput, PartView, RecordLink, ResponsiveDialog, SidePanel, SignInPrompt, StepList, definePlugin, defineUi, diffStats, isConflict, mergeUi, parseDiff, pluginApi, protobaseVersion, uiFromModule, useApiToken, useAppAddress, useAssistant, useAssistantClient, useBackendData, useClient, useFacets, useHistogram, useLayoutRecord, useList, useListDisplay, useMeta, usePlugin, useRecord, useResourceClient, useSeries, useUpdateRecord };
43
+ export { ActionCard, ApiProvider, App, AppLink, AssistantDock, AuthLayout, Button, ChatMessage, ChatThread, CodeForm, CompactTable, Composer, DiffView, FieldList, Input, LogoMark, OtpInput, PartView, RecordLink, ResendCodeButton, ResponsiveDialog, SidePanel, SignInPrompt, Spinner, StepList, buttonClass, definePlugin, defineUi, diffStats, isConflict, mergeUi, parseDiff, pluginApi, protobaseVersion, uiFromModule, useApiToken, useAppAddress, useAssistant, useAssistantClient, useBackendData, useClient, useFacets, useHistogram, useLayoutRecord, useList, useListDisplay, useMeta, usePlugin, useRecord, useResourceClient, useSeries, useUpdateRecord };
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.19.0";
2
+ var version = "0.19.2";
3
3
  var protobase = { "pluginApi": 1 };
4
4
  //#endregion
5
5
  export { protobase, version };
@@ -0,0 +1,49 @@
1
+ import { Spinner } from "../primitives/spinner.js";
2
+ import { useAuth } from "../auth/auth-provider.js";
3
+ import { useRouter } from "../app/router.js";
4
+ import { CustomBoundary } from "../app/pages/custom-boundary.js";
5
+ import { mergePlugins } from "./merge-plugins.js";
6
+ import { usePluginSource } from "./plugin-source.js";
7
+ import { usePluginLoads } from "./use-plugin-loads.js";
8
+ import { useCallback, useMemo } from "react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ //#region src/plugins/before-sign-in.tsx
11
+ /**
12
+ * Loads the plugins the setup status names to everyone, from the app's plugin source, and draws their `beforeSignIn`
13
+ * components around `children` for someone signed out or a visitor, once they have loaded, or failed, or after a wait
14
+ * (see `usePluginLoads`). Signed in, it draws `children` alone, and the plugins stay loaded for the app to merge with
15
+ * the others `/meta` names. A `beforeSignIn` that throws leaves `children` as they are without it.
16
+ */
17
+ const BeforeSignIn = ({ children }) => {
18
+ const { state, beforeSignIn, adoptSession } = useAuth();
19
+ const { path, params, navigate } = useRouter();
20
+ const { loads, settled } = usePluginLoads(beforeSignIn, usePluginSource());
21
+ const Around = useMemo(() => mergePlugins(void 0, loads).ui.beforeSignIn, [loads]);
22
+ const removeParams = useCallback((names) => {
23
+ const kept = new URLSearchParams(params);
24
+ for (const name of names) kept.delete(name);
25
+ navigate(kept.size > 0 ? `${path}?${kept}` : path, { replace: true });
26
+ }, [
27
+ path,
28
+ params,
29
+ navigate
30
+ ]);
31
+ if (state.kind !== "signed-out" && state.kind !== "visitor") return children;
32
+ if (!settled) return /* @__PURE__ */ jsxs("div", {
33
+ className: "flex h-full min-h-48 items-center justify-center gap-2 text-[13px] text-muted-foreground",
34
+ children: [/* @__PURE__ */ jsx(Spinner, {}), " Loading"]
35
+ });
36
+ if (!Around) return children;
37
+ return /* @__PURE__ */ jsx(CustomBoundary, {
38
+ name: "beforeSignIn",
39
+ fallback: children,
40
+ children: /* @__PURE__ */ jsx(Around, {
41
+ signedIn: adoptSession,
42
+ params,
43
+ removeParams,
44
+ children
45
+ })
46
+ });
47
+ };
48
+ //#endregion
49
+ export { BeforeSignIn };
@@ -1,9 +1,9 @@
1
1
  import { Spinner } from "../primitives/spinner.js";
2
- import { ProjectUiContext } from "../app/pages/project-ui.js";
3
- import { useAdminMeta } from "../app/meta-gate.js";
4
- import { browserLoader } from "./load-plugin.js";
5
2
  import { mergePlugins } from "./merge-plugins.js";
3
+ import { usePluginSource } from "./plugin-source.js";
6
4
  import { usePluginLoads } from "./use-plugin-loads.js";
5
+ import { ProjectUiContext } from "../app/pages/project-ui.js";
6
+ import { useAdminMeta } from "../app/meta-gate.js";
7
7
  import { createContext, useContext, useMemo } from "react";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/plugins/plugin-gate.tsx
@@ -11,13 +11,13 @@ const PluginsOffContext = createContext([]);
11
11
  /** The plugins `/meta` names that the app did not load, and why. */
12
12
  const usePluginsOff = () => useContext(PluginsOffContext);
13
13
  /**
14
- * Loads the plugins `/meta` names and provides the project's UI config with theirs merged in. It draws its children
15
- * once they have loaded, or failed, or after a wait (see `usePluginLoads`); a plugin that fails is left out, and its
16
- * components draw what any missing component draws.
14
+ * Loads the plugins `/meta` names, from the app's plugin source, and provides the project's UI config with theirs
15
+ * merged in. It draws its children once they have loaded, or failed, or after a wait (see `usePluginLoads`); a plugin
16
+ * that fails is left out, and its components draw what any missing component draws.
17
17
  */
18
- const PluginGate = ({ ui, loader = browserLoader, children }) => {
18
+ const PluginGate = ({ ui, children }) => {
19
19
  const { plugins = [] } = useAdminMeta();
20
- const { loads, settled } = usePluginLoads(plugins, loader);
20
+ const { loads, settled } = usePluginLoads(plugins, usePluginSource());
21
21
  const merged = useMemo(() => mergePlugins(ui, loads), [ui, loads]);
22
22
  if (!settled) return /* @__PURE__ */ jsxs("div", {
23
23
  className: "flex h-full min-h-48 items-center justify-center gap-2 text-[13px] text-muted-foreground",
@@ -0,0 +1,32 @@
1
+ import { browserLoader, loadPlugin } from "./load-plugin.js";
2
+ import { createContext, useContext, useMemo } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/plugins/plugin-source.tsx
5
+ /** A source that loads with `loader` and keeps each plugin's load, so one named before and after sign-in loads once. */
6
+ const createPluginSource = (loader) => {
7
+ const loads = /* @__PURE__ */ new Map();
8
+ return { load: (ref) => {
9
+ const key = JSON.stringify(ref);
10
+ const known = loads.get(key);
11
+ if (known) return known;
12
+ const load = loadPlugin(ref, loader, window.location.href);
13
+ loads.set(key, load);
14
+ return load;
15
+ } };
16
+ };
17
+ const PluginSourceContext = createContext(null);
18
+ /** The app's plugin source, loading with `loader`: the page's `fetch` and `import()` by default. */
19
+ const PluginSourceProvider = ({ loader = browserLoader, children }) => {
20
+ const source = useMemo(() => createPluginSource(loader), [loader]);
21
+ return /* @__PURE__ */ jsx(PluginSourceContext.Provider, {
22
+ value: source,
23
+ children
24
+ });
25
+ };
26
+ const usePluginSource = () => {
27
+ const source = useContext(PluginSourceContext);
28
+ if (!source) throw new Error("usePluginSource must be used inside PluginSourceProvider");
29
+ return source;
30
+ };
31
+ //#endregion
32
+ export { PluginSourceProvider, createPluginSource, usePluginSource };
@@ -19,8 +19,8 @@ const fieldWithin = (plugin, name, widget) => ({
19
19
  });
20
20
  /**
21
21
  * A plugin's UI config from its module, read as a `protobase.ui.tsx` module and merged with the configs it extends,
22
- * named after the plugin: its components, field types and shell slots draw inside the plugin. Throws `UiConflictError`
23
- * when the configs it merges define a name twice.
22
+ * named after the plugin: its components, field types, shell slots and `beforeSignIn` draw inside the plugin. Throws
23
+ * `UiConflictError` when the configs it merges define a name twice.
24
24
  */
25
25
  const pluginUi = (plugin, module) => {
26
26
  const ui = mergeUi({
@@ -33,12 +33,14 @@ const pluginUi = (plugin, module) => {
33
33
  ...ui.shell.actions && { actions: within(plugin, ui.shell.actions, "shell.actions") },
34
34
  ...ui.shell.rightPanel && { rightPanel: within(plugin, ui.shell.rightPanel, "shell.rightPanel") }
35
35
  };
36
+ const beforeSignIn = ui.beforeSignIn && within(plugin, ui.beforeSignIn, "beforeSignIn");
36
37
  return {
37
38
  name: plugin.name,
38
39
  components,
39
40
  ...ui.actions && { actions: ui.actions },
40
41
  ...fields && { fields },
41
- ...shell && { shell }
42
+ ...shell && { shell },
43
+ ...beforeSignIn && { beforeSignIn }
42
44
  };
43
45
  };
44
46
  //#endregion
@@ -1,4 +1,3 @@
1
- import { loadPlugin } from "./load-plugin.js";
2
1
  import { useEffect, useState } from "react";
3
2
  //#region src/plugins/use-plugin-loads.ts
4
3
  /** How long the app waits for its plugins before it draws without the ones still loading, which arrive later. */
@@ -8,7 +7,7 @@ const none = [];
8
7
  * The plugins `refs` names, in their order, as they load. `settled` once every one has loaded or failed, or after
9
8
  * `pluginWaitMs`, so a slow plugin delays the app only that long. Without plugins it is settled at once.
10
9
  */
11
- const usePluginLoads = (refs, loader) => {
10
+ const usePluginLoads = (refs, source) => {
12
11
  const key = JSON.stringify(refs);
13
12
  const [state, setState] = useState({
14
13
  key: "[]",
@@ -34,7 +33,7 @@ const usePluginLoads = (refs, loader) => {
34
33
  publish();
35
34
  }, pluginWaitMs);
36
35
  refs.forEach((ref, index) => {
37
- loadPlugin(ref, loader, window.location.href).then((load) => {
36
+ source.load(ref).then((load) => {
38
37
  results[index] = load;
39
38
  publish();
40
39
  });
@@ -43,7 +42,7 @@ const usePluginLoads = (refs, loader) => {
43
42
  active = false;
44
43
  clearTimeout(timer);
45
44
  };
46
- }, [key, loader]);
45
+ }, [key, source]);
47
46
  if (refs.length === 0) return {
48
47
  loads: none,
49
48
  settled: true
@@ -0,0 +1,11 @@
1
+ import { ButtonHTMLAttributes } from "react";
2
+ //#region src/primitives/button.d.ts
3
+ export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
4
+ variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
5
+ size?: 'sm' | 'md';
6
+ loading?: boolean;
7
+ };
8
+ /** A button's classes, for a link that looks like one. */
9
+ export declare const buttonClass: ({ variant, size }?: Pick<ButtonProps, "variant" | "size">) => string;
10
+ export declare const Button: ({ variant, size, loading, className, children, disabled, ...rest }: ButtonProps) => import("react").JSX.Element;
11
+ //#endregion
@@ -0,0 +1,11 @@
1
+ import { InputHTMLAttributes, ReactNode, Ref } from "react";
2
+ //#region src/primitives/input.d.ts
3
+ export type InputProps = InputHTMLAttributes<HTMLInputElement> & {
4
+ ref?: Ref<HTMLInputElement>;
5
+ leading?: ReactNode;
6
+ trailing?: ReactNode;
7
+ invalid?: boolean;
8
+ wrapperClassName?: string;
9
+ };
10
+ export declare const Input: ({ leading, trailing, invalid, className, wrapperClassName, ...rest }: InputProps) => import("react").JSX.Element;
11
+ //#endregion
@@ -0,0 +1,5 @@
1
+ //#region src/primitives/spinner.d.ts
2
+ export declare const Spinner: ({ className }: {
3
+ className?: string;
4
+ }) => import("react").JSX.Element;
5
+ //#endregion