@flanksource/clicky-ui 0.3.58 → 0.3.59

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 (89) hide show
  1. package/dist/clicky.cjs +3 -1
  2. package/dist/clicky.d.ts +1 -0
  3. package/dist/clicky.d.ts.map +1 -1
  4. package/dist/clicky.js +3 -1
  5. package/dist/data/Clicky.cjs +22 -270
  6. package/dist/data/Clicky.cjs.map +1 -1
  7. package/dist/data/Clicky.d.ts +3 -29
  8. package/dist/data/Clicky.d.ts.map +1 -1
  9. package/dist/data/Clicky.js +10 -259
  10. package/dist/data/Clicky.js.map +1 -1
  11. package/dist/data/clicky-download.cjs +251 -0
  12. package/dist/data/clicky-download.cjs.map +1 -0
  13. package/dist/data/clicky-download.d.ts +55 -0
  14. package/dist/data/clicky-download.d.ts.map +1 -0
  15. package/dist/data/clicky-download.js +244 -0
  16. package/dist/data/clicky-download.js.map +1 -0
  17. package/dist/data/traces/index.d.ts +2 -0
  18. package/dist/data/traces/index.d.ts.map +1 -1
  19. package/dist/data/traces/otel/OtelTraceDetail.cjs +102 -78
  20. package/dist/data/traces/otel/OtelTraceDetail.cjs.map +1 -1
  21. package/dist/data/traces/otel/OtelTraceDetail.d.ts +6 -2
  22. package/dist/data/traces/otel/OtelTraceDetail.d.ts.map +1 -1
  23. package/dist/data/traces/otel/OtelTraceDetail.js +102 -78
  24. package/dist/data/traces/otel/OtelTraceDetail.js.map +1 -1
  25. package/dist/data/traces/otel/OtelTraceTable.cjs +43 -7
  26. package/dist/data/traces/otel/OtelTraceTable.cjs.map +1 -1
  27. package/dist/data/traces/otel/OtelTraceTable.d.ts +14 -3
  28. package/dist/data/traces/otel/OtelTraceTable.d.ts.map +1 -1
  29. package/dist/data/traces/otel/OtelTraceTable.js +44 -8
  30. package/dist/data/traces/otel/OtelTraceTable.js.map +1 -1
  31. package/dist/data/traces/otel/profile-listing.cjs +61 -0
  32. package/dist/data/traces/otel/profile-listing.cjs.map +1 -0
  33. package/dist/data/traces/otel/profile-listing.d.ts +23 -0
  34. package/dist/data/traces/otel/profile-listing.d.ts.map +1 -0
  35. package/dist/data/traces/otel/profile-listing.js +60 -0
  36. package/dist/data/traces/otel/profile-listing.js.map +1 -0
  37. package/dist/data/traces/otel/profile-spans.cjs +22 -0
  38. package/dist/data/traces/otel/profile-spans.cjs.map +1 -0
  39. package/dist/data/traces/otel/profile-spans.d.ts +4 -0
  40. package/dist/data/traces/otel/profile-spans.d.ts.map +1 -0
  41. package/dist/data/traces/otel/profile-spans.js +22 -0
  42. package/dist/data/traces/otel/profile-spans.js.map +1 -0
  43. package/dist/data/traces/otel/span-traces.cjs +7 -1
  44. package/dist/data/traces/otel/span-traces.cjs.map +1 -1
  45. package/dist/data/traces/otel/span-traces.d.ts +2 -0
  46. package/dist/data/traces/otel/span-traces.d.ts.map +1 -1
  47. package/dist/data/traces/otel/span-traces.js +7 -2
  48. package/dist/data/traces/otel/span-traces.js.map +1 -1
  49. package/dist/data/useClickyTableMenu.cjs +33 -0
  50. package/dist/data/useClickyTableMenu.cjs.map +1 -0
  51. package/dist/data/useClickyTableMenu.d.ts +17 -0
  52. package/dist/data/useClickyTableMenu.d.ts.map +1 -0
  53. package/dist/data/useClickyTableMenu.js +33 -0
  54. package/dist/data/useClickyTableMenu.js.map +1 -0
  55. package/dist/data/version-info.cjs +3 -3
  56. package/dist/data/version-info.js +3 -3
  57. package/dist/data.cjs +7 -2
  58. package/dist/data.js +5 -3
  59. package/dist/index.cjs +14 -3
  60. package/dist/index.js +9 -4
  61. package/dist/rpc/EntityExplorerApp.cjs +49 -12
  62. package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
  63. package/dist/rpc/EntityExplorerApp.d.ts +10 -1
  64. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
  65. package/dist/rpc/EntityExplorerApp.js +51 -14
  66. package/dist/rpc/EntityExplorerApp.js.map +1 -1
  67. package/dist/rpc/EntitySurface.cjs +38 -0
  68. package/dist/rpc/EntitySurface.cjs.map +1 -0
  69. package/dist/rpc/EntitySurface.d.ts +17 -0
  70. package/dist/rpc/EntitySurface.d.ts.map +1 -0
  71. package/dist/rpc/EntitySurface.js +38 -0
  72. package/dist/rpc/EntitySurface.js.map +1 -0
  73. package/dist/rpc/ExplorerNav.cjs +48 -0
  74. package/dist/rpc/ExplorerNav.cjs.map +1 -0
  75. package/dist/rpc/ExplorerNav.d.ts +12 -0
  76. package/dist/rpc/ExplorerNav.d.ts.map +1 -0
  77. package/dist/rpc/ExplorerNav.js +48 -0
  78. package/dist/rpc/ExplorerNav.js.map +1 -0
  79. package/dist/rpc/explorer-nav-context.cjs +5 -0
  80. package/dist/rpc/explorer-nav-context.cjs.map +1 -0
  81. package/dist/rpc/explorer-nav-context.d.ts +11 -0
  82. package/dist/rpc/explorer-nav-context.d.ts.map +1 -0
  83. package/dist/rpc/explorer-nav-context.js +6 -0
  84. package/dist/rpc/explorer-nav-context.js.map +1 -0
  85. package/dist/rpc.cjs +4 -0
  86. package/dist/rpc.d.ts +2 -0
  87. package/dist/rpc.d.ts.map +1 -1
  88. package/dist/rpc.js +3 -1
  89. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"EntityExplorerApp.cjs","names":["useRouter","useOperations","useMemo","getClickySurfaces","buildCommandHref","surfaceNavSection","withBasePath","_jsx","AppShell","ThemeSwitcher","makeSurfaceDefinition","OperationCatalog","OperationEntityPage","OperationCommandPage","trimTrailingSlash","ARG_QUERY_PREFIX"],"sources":["../../src/rpc/EntityExplorerApp.tsx"],"sourcesContent":["import { useEffect, useMemo, type ReactNode } from \"react\";\nimport { ThemeSwitcher } from \"../components/theme-switcher\";\nimport type { PreExtension, PostExtension } from \"../components/json-schema-form-types\";\nimport type { ClickyCommandRuntime } from \"../data/Clicky\";\nimport { AppShell, type AppShellNavSection } from \"../layout/AppShell\";\nimport { getClickySurfaces, makeSurfaceDefinition } from \"./clickyMetadata\";\nimport {\n ARG_QUERY_PREFIX,\n AUTORUN_QUERY_PARAM,\n buildCommandHref,\n trimTrailingSlash,\n withBasePath,\n} from \"./commandHref\";\nimport { useRouter } from \"./router\";\nimport { OperationCatalog } from \"./OperationCatalog\";\nimport type { ResultRenderer } from \"./OperationResultView\";\nimport { OperationCommandPage } from \"./OperationCommandPage\";\nimport {\n OperationEntityPage,\n type EntityDetailBodyRenderer,\n type EntityDetailHeaderRenderer,\n} from \"./OperationEntityPage\";\nimport type { FormActionsRenderer } from \"./SchemaActionForm\";\nimport { surfaceNavSection } from \"./surfaceNav\";\nimport type { ClickySurface } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\nimport { useOperations } from \"./useOperations\";\n\nexport type SurfaceActionLabels = Record<string, Record<string, string>>;\n\nexport type EntityExplorerAppProps = {\n client: OperationsApiClient;\n basePath?: string;\n showApiExplorer?: boolean;\n /** Right-aligned top-bar cluster forwarded to AppShell's actions slot. */\n actions?: ReactNode;\n /**\n * Custom JsonSchemaForm field extensions applied to every create/edit form the\n * explorer renders — e.g. a SecretKeySelector widget keyed on an\n * `x-clicky-component` schema hint. `pre` transforms a resolved control; `post`\n * can replace the rendered value node with a custom component.\n */\n formExtensions?: { pre?: PreExtension[]; post?: PostExtension[] };\n /**\n * Optional extra footer actions added to every create/edit form (e.g. a\n * connection \"Test\" split-button). The renderer receives the live form value\n * and the action it submits to, so it can scope itself to a given entity.\n */\n formActions?: FormActionsRenderer;\n /** Per-surface labels keyed by x-clicky verb/actionName. */\n surfaceActionLabels?: SurfaceActionLabels;\n /**\n * @deprecated Superseded by per-surface icons emitted by the backend\n * (x-clicky-icon → ClickySurface.icon). AppShell section labels are plain\n * strings, so this group-header icon map is no longer rendered. Kept for\n * source-compatibility only.\n */\n surfaceIcons?: Record<string, ReactNode>;\n /**\n * Optional host override for the result surface. Called where an entity's\n * result table renders, with the current surface key, the raw response, and\n * the default OperationResultView element. Return `defaultView` to keep the\n * standard table, or a custom node (e.g. a LogsTable for trace/log profiles\n * flagged via x-clicky-render). Filtering/sorting policy is the host's choice.\n */\n resultRenderer?: ResultRenderer;\n /** Host override for a loaded entity's body; heading and actions remain. */\n entityDetailBodyRenderer?: EntityDetailBodyRenderer;\n /** Host override for a loaded entity's \"{title}: {id}\" heading. */\n entityDetailHeaderRenderer?: EntityDetailHeaderRenderer;\n};\n\n// SIDEBAR_COLLAPSED_KEY persists the AppShell rail collapsed flag across reloads.\nconst SIDEBAR_COLLAPSED_KEY = \"clicky-ui:sidebar:collapsed\";\n\nexport function EntityExplorerApp({\n client,\n basePath = \"\",\n showApiExplorer = true,\n actions,\n formExtensions,\n formActions,\n surfaceActionLabels,\n resultRenderer,\n entityDetailBodyRenderer,\n entityDetailHeaderRenderer,\n}: EntityExplorerAppProps) {\n const formPre = formExtensions?.pre;\n const formPost = formExtensions?.post;\n const { pathname, renderLink, navigate } = useRouter();\n const { spec } = useOperations(client);\n const surfaces = useMemo(() => getClickySurfaces(spec), [spec]);\n const surfaceGroups = useMemo(() => groupSurfacesByParent(surfaces), [surfaces]);\n const defaultSurface = useMemo(\n () => surfaces.find((surface) => !surface.admin) ?? surfaces[0],\n [surfaces],\n );\n const relativePath = useMemo(() => stripBasePath(pathname, basePath), [basePath, pathname]);\n const route = useMemo(() => parseExplorerRoute(relativePath), [relativePath]);\n const resolvedRoute = useMemo(() => resolveRouteSurface(route, surfaces), [route, surfaces]);\n const commandRuntime = useMemo<ClickyCommandRuntime>(\n () => ({\n client,\n hrefForCommand: (resolved) => buildCommandHref(basePath, resolved),\n onNavigate: (resolved) => {\n const href = buildCommandHref(basePath, resolved);\n if (!href) return;\n navigate(href);\n },\n }),\n [basePath, client, navigate],\n );\n const { initialValues: commandInitialValues } = useMemo(\n () =>\n resolvedRoute.kind === \"command\"\n ? readCommandQueryParams()\n : { initialValues: {}, autoRun: false },\n [resolvedRoute.kind, pathname],\n );\n const explorerDefinition = useMemo(\n () => ({\n key: \"explorer\",\n title: \"API Explorer\",\n description: \"Every operation exposed by the current OpenAPI spec.\",\n }),\n [],\n );\n const navSections = useMemo<AppShellNavSection[]>(() => {\n const sections: AppShellNavSection[] = surfaceGroups.map((group) =>\n surfaceNavSection(group.label, group.surfaces, {\n isActive: (surface) => isSurfaceRouteActive(resolvedRoute, surface.key),\n hrefFor: (surface) => withBasePath(basePath, `/${surface.key}`),\n }),\n );\n if (showApiExplorer) {\n sections.push({\n items: [\n {\n key: explorerDefinition.key,\n label: explorerDefinition.title,\n active: resolvedRoute.kind === \"explorer\" || resolvedRoute.kind === \"command\",\n to: withBasePath(basePath, \"/explorer\"),\n },\n ],\n });\n }\n return sections;\n }, [surfaceGroups, basePath, resolvedRoute, showApiExplorer, explorerDefinition]);\n\n useEffect(() => {\n if (defaultSurface == null || relativePath !== \"/\") return;\n navigate(withBasePath(basePath, `/${defaultSurface.key}`), { replace: true });\n }, [basePath, defaultSurface, relativePath, navigate]);\n\n const content = (\n <AppShell\n brand={\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-semibold\">\n {spec?.info.title ?? \"Clicky Explorer\"}\n </div>\n <div className=\"truncate text-xs text-sidebar-foreground/60\">\n Metadata-driven entity explorer\n </div>\n </div>\n }\n navSections={navSections}\n sidebarFooter={<ThemeSwitcher />}\n {...(actions ? { actions } : {})}\n // The page header belongs to the host, not to OperationCatalog — the\n // catalog renders only its results. OperationEntityPage still titles\n // itself, so this covers the collection route only.\n //\n // It rides in the top bar rather than a bodyHeader row: next to the rail\n // that bar is otherwise empty, and the row it replaces cost the result\n // table ~72px of the viewport it needs to keep its sticky head and\n // pagination footer on screen without the page itself scrolling.\n {...(resolvedRoute.kind === \"surface\" && resolvedRoute.surface\n ? {\n nav: (\n <div className=\"flex min-w-0 flex-1 items-baseline gap-density-2\">\n <h1 className=\"min-w-0 truncate text-base font-semibold tracking-tight\">\n {resolvedRoute.surface.title}\n </h1>\n <p className=\"hidden min-w-0 truncate text-sm text-muted-foreground lg:block\">\n {makeSurfaceDefinition(resolvedRoute.surface).description}\n </p>\n </div>\n ),\n }\n : {})}\n collapsedStorageKey={SIDEBAR_COLLAPSED_KEY}\n // Results are wide tables, not prose — let them use the whole workspace\n // instead of the centred reading column.\n contentWidth=\"full\"\n contentClassName=\"p-6\"\n >\n {resolvedRoute.kind === \"surface\" ? (\n resolvedRoute.surface ? (\n <OperationCatalog\n // Filter state is seeded from the URL when the catalog mounts and\n // written back to it, so one instance spanning two surfaces would\n // carry the first surface's filters onto the second's URL. Keying\n // on the surface makes each one start from its own query string.\n key={resolvedRoute.surface.key}\n definition={makeSurfaceDefinition(resolvedRoute.surface)}\n entities={[resolvedRoute.surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={resolvedRoute.surface.key}\n commandRuntime={commandRuntime}\n {...(formPre ? { formPre } : {})}\n {...(formPost ? { formPost } : {})}\n {...(formActions ? { formActions } : {})}\n {...(surfaceActionLabels?.[resolvedRoute.surface.key]\n ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] }\n : {})}\n {...(resultRenderer ? { resultRenderer } : {})}\n />\n ) : (\n <UnknownSurface surfaceKey={resolvedRoute.surfaceKey} />\n )\n ) : resolvedRoute.kind === \"entity\" ? (\n resolvedRoute.surface ? (\n <OperationEntityPage\n definition={makeSurfaceDefinition(resolvedRoute.surface)}\n entities={[resolvedRoute.surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={resolvedRoute.surface.key}\n backHref={withBasePath(basePath, `/${resolvedRoute.surface.key}`)}\n backLabel={`Back to ${resolvedRoute.surface.title}`}\n commandRuntime={commandRuntime}\n {...(formPre ? { formPre } : {})}\n {...(formPost ? { formPost } : {})}\n {...(formActions ? { formActions } : {})}\n {...(surfaceActionLabels?.[resolvedRoute.surface.key]\n ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] }\n : {})}\n {...(entityDetailBodyRenderer ? { entityDetailBodyRenderer } : {})}\n {...(entityDetailHeaderRenderer ? { entityDetailHeaderRenderer } : {})}\n {...(resolvedRoute.id ? { id: resolvedRoute.id } : {})}\n />\n ) : (\n <UnknownSurface surfaceKey={resolvedRoute.surfaceKey} />\n )\n ) : resolvedRoute.kind === \"command\" ? (\n <OperationCommandPage\n client={client}\n backHref={withBasePath(basePath, \"/explorer\")}\n backLabel=\"Back to API Explorer\"\n renderLink={renderLink}\n commandRuntime={commandRuntime}\n initialValues={commandInitialValues}\n autoRun={true}\n {...(resolvedRoute.operationId ? { operationId: resolvedRoute.operationId } : {})}\n />\n ) : resolvedRoute.kind === \"explorer\" ? (\n <OperationCatalog\n definition={explorerDefinition}\n entities={[]}\n allOperations\n client={client}\n renderLink={renderLink}\n commandRuntime={commandRuntime}\n />\n ) : defaultSurface == null ? (\n <div className=\"text-sm text-muted-foreground\">Loading surfaces…</div>\n ) : (\n <div className=\"text-sm text-muted-foreground\">Redirecting…</div>\n )}\n </AppShell>\n );\n\n return content;\n}\n\ntype ExplorerRoute =\n | { kind: \"root\" }\n | { kind: \"explorer\" }\n | { kind: \"command\"; operationId?: string }\n | { kind: \"surface\"; surfaceKey: string; surface?: ClickySurface }\n | {\n kind: \"entity\";\n surfaceKey: string;\n surface?: ClickySurface;\n id?: string;\n };\n\nfunction parseExplorerRoute(pathname: string): ExplorerRoute {\n const normalized = trimTrailingSlash(pathname) || \"/\";\n if (normalized === \"/\") {\n return { kind: \"root\" };\n }\n\n const segments = normalized.replace(/^\\/+/, \"\").split(\"/\");\n if (segments[0] === \"explorer\") {\n return { kind: \"explorer\" };\n }\n if (segments[0] === \"commands\") {\n return segments[1] ? { kind: \"command\", operationId: segments[1] } : { kind: \"command\" };\n }\n const surfaceKey = segments[0] ?? \"\";\n if (segments[1]) {\n return {\n kind: \"entity\",\n surfaceKey,\n id: decodeURIComponent(segments[1]),\n };\n }\n return { kind: \"surface\", surfaceKey };\n}\n\nfunction resolveRouteSurface(route: ExplorerRoute, surfaces: ClickySurface[]): ExplorerRoute {\n if (route.kind !== \"surface\" && route.kind !== \"entity\") {\n return route;\n }\n const surface = surfaces.find((item) => item.key === route.surfaceKey);\n return surface ? { ...route, surface } : route;\n}\n\nfunction isSurfaceRouteActive(route: ExplorerRoute, surfaceKey: string) {\n return (\n (route.kind === \"surface\" && route.surfaceKey === surfaceKey) ||\n (route.kind === \"entity\" && route.surfaceKey === surfaceKey)\n );\n}\n\nfunction stripBasePath(pathname: string, basePath: string) {\n const base = trimTrailingSlash(basePath);\n if (!base || base === \"/\") {\n return trimTrailingSlash(pathname) || \"/\";\n }\n if (pathname === base) {\n return \"/\";\n }\n if (pathname.startsWith(`${base}/`)) {\n return trimTrailingSlash(pathname.slice(base.length)) || \"/\";\n }\n return trimTrailingSlash(pathname) || \"/\";\n}\n\nfunction UnknownSurface({ surfaceKey }: { surfaceKey: string }) {\n return (\n <div className=\"p-6 text-sm text-muted-foreground\">\n Unknown surface: <code>{surfaceKey}</code>\n </div>\n );\n}\n\nconst LEGACY_AUTORUN_QUERY_PARAM = \"__autoRun\";\n\ntype SurfaceGroup = {\n parent: string; // the slug; \"\" for surfaces that declared no parent\n label: string; // display name in the sidebar\n surfaces: ClickySurface[];\n};\n\n// groupSurfacesByParent buckets surfaces by their ClickySurface.parent slug,\n// preserving the order surfaces appeared in the spec. Surfaces with no parent\n// fall into a trailing \"\" bucket labelled \"Other\".\nfunction groupSurfacesByParent(surfaces: ClickySurface[]): SurfaceGroup[] {\n const order: string[] = [];\n const buckets = new Map<string, ClickySurface[]>();\n for (const surface of surfaces) {\n const parent = surface.parent ?? \"\";\n if (!buckets.has(parent)) {\n buckets.set(parent, []);\n order.push(parent);\n }\n buckets.get(parent)!.push(surface);\n }\n return order.map((parent) => ({\n parent,\n label: parent === \"\" ? \"Other\" : titleCase(parent),\n surfaces: buckets.get(parent)!,\n }));\n}\n\nfunction titleCase(value: string): string {\n if (!value) return value;\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction readCommandQueryParams(): { initialValues: Record<string, string>; autoRun: boolean } {\n if (typeof window === \"undefined\") {\n return { initialValues: {}, autoRun: false };\n }\n const search = new URLSearchParams(window.location.search);\n const initialValues: Record<string, string> = {};\n let autoRun = false;\n const positional: string[] = [];\n\n for (const [key, value] of search.entries()) {\n if (key === AUTORUN_QUERY_PARAM || key === LEGACY_AUTORUN_QUERY_PARAM) {\n autoRun = value === \"1\" || value === \"true\";\n continue;\n }\n if (key.startsWith(ARG_QUERY_PREFIX)) {\n const index = Number.parseInt(key.slice(ARG_QUERY_PREFIX.length), 10);\n if (Number.isFinite(index) && index >= 0) {\n positional[index] = value;\n }\n continue;\n }\n initialValues[key] = value;\n }\n\n const packedArgs = positional.filter((value) => value !== undefined).join(\" \");\n if (packedArgs !== \"\") {\n initialValues.args = packedArgs;\n }\n\n return { initialValues, autoRun };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EntityExplorerApp.cjs","names":["useRouter","useOperations","useMemo","getClickySurfaces","buildCommandHref","surfaceNavSection","withBasePath","useState","useCallback","AppShell","ThemeSwitcher","_Fragment","makeSurfaceDefinition","OperationCatalog","OperationEntityPage","OperationCommandPage","ExplorerNavContext","trimTrailingSlash","ARG_QUERY_PREFIX"],"sources":["../../src/rpc/EntityExplorerApp.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { ExplorerNavContext, type ExplorerNavSlot } from \"./explorer-nav-context\";\nimport { ThemeSwitcher } from \"../components/theme-switcher\";\nimport type { PreExtension, PostExtension } from \"../components/json-schema-form-types\";\nimport type { ClickyCommandRuntime } from \"../data/Clicky\";\nimport { AppShell, type AppShellNavSection } from \"../layout/AppShell\";\nimport { getClickySurfaces, makeSurfaceDefinition } from \"./clickyMetadata\";\nimport {\n ARG_QUERY_PREFIX,\n AUTORUN_QUERY_PARAM,\n buildCommandHref,\n trimTrailingSlash,\n withBasePath,\n} from \"./commandHref\";\nimport { useRouter } from \"./router\";\nimport { OperationCatalog } from \"./OperationCatalog\";\nimport type { ResultRenderer } from \"./OperationResultView\";\nimport { OperationCommandPage } from \"./OperationCommandPage\";\nimport {\n OperationEntityPage,\n type EntityDetailBodyRenderer,\n type EntityDetailHeaderRenderer,\n} from \"./OperationEntityPage\";\nimport type { FormActionsRenderer } from \"./SchemaActionForm\";\nimport { surfaceNavSection } from \"./surfaceNav\";\nimport type { ClickySurface } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\nimport { useOperations } from \"./useOperations\";\n\nexport type SurfaceActionLabels = Record<string, Record<string, string>>;\n\nexport type EntityExplorerAppProps = {\n client: OperationsApiClient;\n basePath?: string;\n showApiExplorer?: boolean;\n /** Right-aligned top-bar cluster forwarded to AppShell's actions slot. */\n actions?: ReactNode;\n /**\n * Custom JsonSchemaForm field extensions applied to every create/edit form the\n * explorer renders — e.g. a SecretKeySelector widget keyed on an\n * `x-clicky-component` schema hint. `pre` transforms a resolved control; `post`\n * can replace the rendered value node with a custom component.\n */\n formExtensions?: { pre?: PreExtension[]; post?: PostExtension[] };\n /**\n * Optional extra footer actions added to every create/edit form (e.g. a\n * connection \"Test\" split-button). The renderer receives the live form value\n * and the action it submits to, so it can scope itself to a given entity.\n */\n formActions?: FormActionsRenderer;\n /** Per-surface labels keyed by x-clicky verb/actionName. */\n surfaceActionLabels?: SurfaceActionLabels;\n /**\n * @deprecated Superseded by per-surface icons emitted by the backend\n * (x-clicky-icon → ClickySurface.icon). AppShell section labels are plain\n * strings, so this group-header icon map is no longer rendered. Kept for\n * source-compatibility only.\n */\n surfaceIcons?: Record<string, ReactNode>;\n /**\n * Optional host override for the result surface. Called where an entity's\n * result table renders, with the current surface key, the raw response, and\n * the default OperationResultView element. Return `defaultView` to keep the\n * standard table, or a custom node (e.g. a LogsTable for trace/log profiles\n * flagged via x-clicky-render). Filtering/sorting policy is the host's choice.\n */\n resultRenderer?: ResultRenderer;\n /** Host override for a loaded entity's body; heading and actions remain. */\n entityDetailBodyRenderer?: EntityDetailBodyRenderer;\n /** Host override for a loaded entity's \"{title}: {id}\" heading. */\n entityDetailHeaderRenderer?: EntityDetailHeaderRenderer;\n /** Compact host controls (e.g. an edit icon) shown right after a surface's title or breadcrumb in the top bar. */\n surfaceTitleActions?: (surfaceKey: string) => ReactNode;\n /**\n * Per-surface paging presentation, forwarded to OperationCatalog's\n * `paginationMode`. Return undefined to keep automatic selection (a cursor\n * walk whenever the list declares a cursor); return \"paged\" for a surface\n * whose readers need prev/next offset controls.\n */\n surfacePaginationMode?: (surfaceKey: string) => \"paged\" | \"infinite\" | undefined;\n};\n\n// SIDEBAR_COLLAPSED_KEY persists the AppShell rail collapsed flag across reloads.\nconst SIDEBAR_COLLAPSED_KEY = \"clicky-ui:sidebar:collapsed\";\n\nexport function EntityExplorerApp({\n client,\n basePath = \"\",\n showApiExplorer = true,\n actions,\n formExtensions,\n formActions,\n surfaceActionLabels,\n resultRenderer,\n entityDetailBodyRenderer,\n entityDetailHeaderRenderer,\n surfaceTitleActions,\n surfacePaginationMode,\n}: EntityExplorerAppProps) {\n const formPre = formExtensions?.pre;\n const formPost = formExtensions?.post;\n const { pathname, renderLink, navigate } = useRouter();\n const { spec } = useOperations(client);\n const surfaces = useMemo(() => getClickySurfaces(spec), [spec]);\n const surfaceGroups = useMemo(() => groupSurfacesByParent(surfaces), [surfaces]);\n const defaultSurface = useMemo(\n () => surfaces.find((surface) => !surface.admin) ?? surfaces[0],\n [surfaces],\n );\n const relativePath = useMemo(() => stripBasePath(pathname, basePath), [basePath, pathname]);\n const route = useMemo(() => parseExplorerRoute(relativePath), [relativePath]);\n const resolvedRoute = useMemo(() => resolveRouteSurface(route, surfaces), [route, surfaces]);\n const commandRuntime = useMemo<ClickyCommandRuntime>(\n () => ({\n client,\n hrefForCommand: (resolved) => buildCommandHref(basePath, resolved),\n onNavigate: (resolved) => {\n const href = buildCommandHref(basePath, resolved);\n if (!href) return;\n navigate(href);\n },\n }),\n [basePath, client, navigate],\n );\n const { initialValues: commandInitialValues } = useMemo(\n () =>\n resolvedRoute.kind === \"command\"\n ? readCommandQueryParams()\n : { initialValues: {}, autoRun: false },\n [resolvedRoute.kind, pathname],\n );\n const explorerDefinition = useMemo(\n () => ({\n key: \"explorer\",\n title: \"API Explorer\",\n description: \"Every operation exposed by the current OpenAPI spec.\",\n }),\n [],\n );\n const navSections = useMemo<AppShellNavSection[]>(() => {\n const sections: AppShellNavSection[] = surfaceGroups.map((group) =>\n surfaceNavSection(group.label, group.surfaces, {\n isActive: (surface) => isSurfaceRouteActive(resolvedRoute, surface.key),\n hrefFor: (surface) => withBasePath(basePath, `/${surface.key}`),\n }),\n );\n if (showApiExplorer) {\n sections.push({\n items: [\n {\n key: explorerDefinition.key,\n label: explorerDefinition.title,\n active: resolvedRoute.kind === \"explorer\" || resolvedRoute.kind === \"command\",\n to: withBasePath(basePath, \"/explorer\"),\n },\n ],\n });\n }\n return sections;\n }, [surfaceGroups, basePath, resolvedRoute, showApiExplorer, explorerDefinition]);\n\n const [navContainer, setNavContainer] = useState<HTMLElement | null>(null);\n const [navClaims, setNavClaims] = useState(0);\n const claimNav = useCallback(() => {\n setNavClaims((count) => count + 1);\n return () => setNavClaims((count) => count - 1);\n }, []);\n const surface = resolvedRoute.kind === \"surface\" ? resolvedRoute.surface : undefined;\n const titleActions = surface ? surfaceTitleActions?.(surface.key) : undefined;\n const paginationMode = surface ? surfacePaginationMode?.(surface.key) : undefined;\n // The container only exists while a surface is resolved, so a portal\n // mounted before the spec loads renders nothing rather than a bare crumb.\n const navSlot = useMemo<ExplorerNavSlot>(\n () => ({\n container: surface ? navContainer : null,\n title: surface?.title ?? \"\",\n titleActions,\n claim: claimNav,\n }),\n [claimNav, navContainer, surface, titleActions],\n );\n\n useEffect(() => {\n if (defaultSurface == null || relativePath !== \"/\") return;\n navigate(withBasePath(basePath, `/${defaultSurface.key}`), { replace: true });\n }, [basePath, defaultSurface, relativePath, navigate]);\n\n const content = (\n <AppShell\n brand={\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-semibold\">\n {spec?.info.title ?? \"Clicky Explorer\"}\n </div>\n <div className=\"truncate text-xs text-sidebar-foreground/60\">\n Metadata-driven entity explorer\n </div>\n </div>\n }\n navSections={navSections}\n sidebarFooter={<ThemeSwitcher />}\n {...(actions ? { actions } : {})}\n // The page header belongs to the host, not to OperationCatalog — the\n // catalog renders only its results. OperationEntityPage still titles\n // itself, so this covers the collection route only.\n //\n // It rides in the top bar rather than a bodyHeader row: next to the rail\n // that bar is otherwise empty, and the row it replaces cost the result\n // table ~72px of the viewport it needs to keep its sticky head and\n // pagination footer on screen without the page itself scrolling.\n {...(resolvedRoute.kind === \"surface\" && resolvedRoute.surface\n ? {\n nav: (\n <>\n {navClaims === 0 && (\n <div className=\"flex min-w-0 flex-1 items-baseline gap-density-2\">\n <h1 className=\"min-w-0 truncate text-base font-semibold tracking-tight\">\n {resolvedRoute.surface.title}\n </h1>\n {titleActions ? (\n <div className=\"flex shrink-0 items-center self-center\">{titleActions}</div>\n ) : null}\n <p className=\"hidden min-w-0 truncate text-sm text-muted-foreground lg:block\">\n {makeSurfaceDefinition(resolvedRoute.surface).description}\n </p>\n </div>\n )}\n <div ref={setNavContainer} data-slot=\"explorer-nav\" className=\"contents\" />\n </>\n ),\n }\n : {})}\n collapsedStorageKey={SIDEBAR_COLLAPSED_KEY}\n // Results are wide tables, not prose — let them use the whole workspace\n // instead of the centred reading column.\n contentWidth=\"full\"\n contentClassName=\"p-6\"\n >\n {resolvedRoute.kind === \"surface\" ? (\n resolvedRoute.surface ? (\n <OperationCatalog\n // Filter state is seeded from the URL when the catalog mounts and\n // written back to it, so one instance spanning two surfaces would\n // carry the first surface's filters onto the second's URL. Keying\n // on the surface makes each one start from its own query string.\n key={resolvedRoute.surface.key}\n definition={makeSurfaceDefinition(resolvedRoute.surface)}\n entities={[resolvedRoute.surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={resolvedRoute.surface.key}\n commandRuntime={commandRuntime}\n {...(formPre ? { formPre } : {})}\n {...(formPost ? { formPost } : {})}\n {...(formActions ? { formActions } : {})}\n {...(surfaceActionLabels?.[resolvedRoute.surface.key]\n ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] }\n : {})}\n {...(resultRenderer ? { resultRenderer } : {})}\n {...(paginationMode ? { paginationMode } : {})}\n />\n ) : (\n <UnknownSurface surfaceKey={resolvedRoute.surfaceKey} />\n )\n ) : resolvedRoute.kind === \"entity\" ? (\n resolvedRoute.surface ? (\n <OperationEntityPage\n definition={makeSurfaceDefinition(resolvedRoute.surface)}\n entities={[resolvedRoute.surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={resolvedRoute.surface.key}\n backHref={withBasePath(basePath, `/${resolvedRoute.surface.key}`)}\n backLabel={`Back to ${resolvedRoute.surface.title}`}\n commandRuntime={commandRuntime}\n {...(formPre ? { formPre } : {})}\n {...(formPost ? { formPost } : {})}\n {...(formActions ? { formActions } : {})}\n {...(surfaceActionLabels?.[resolvedRoute.surface.key]\n ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] }\n : {})}\n {...(entityDetailBodyRenderer ? { entityDetailBodyRenderer } : {})}\n {...(entityDetailHeaderRenderer ? { entityDetailHeaderRenderer } : {})}\n {...(resolvedRoute.id ? { id: resolvedRoute.id } : {})}\n />\n ) : (\n <UnknownSurface surfaceKey={resolvedRoute.surfaceKey} />\n )\n ) : resolvedRoute.kind === \"command\" ? (\n <OperationCommandPage\n client={client}\n backHref={withBasePath(basePath, \"/explorer\")}\n backLabel=\"Back to API Explorer\"\n renderLink={renderLink}\n commandRuntime={commandRuntime}\n initialValues={commandInitialValues}\n autoRun={true}\n {...(resolvedRoute.operationId ? { operationId: resolvedRoute.operationId } : {})}\n />\n ) : resolvedRoute.kind === \"explorer\" ? (\n <OperationCatalog\n definition={explorerDefinition}\n entities={[]}\n allOperations\n client={client}\n renderLink={renderLink}\n commandRuntime={commandRuntime}\n />\n ) : defaultSurface == null ? (\n <div className=\"text-sm text-muted-foreground\">Loading surfaces…</div>\n ) : (\n <div className=\"text-sm text-muted-foreground\">Redirecting…</div>\n )}\n </AppShell>\n );\n\n return <ExplorerNavContext.Provider value={navSlot}>{content}</ExplorerNavContext.Provider>;\n}\n\ntype ExplorerRoute =\n | { kind: \"root\" }\n | { kind: \"explorer\" }\n | { kind: \"command\"; operationId?: string }\n | { kind: \"surface\"; surfaceKey: string; surface?: ClickySurface }\n | {\n kind: \"entity\";\n surfaceKey: string;\n surface?: ClickySurface;\n id?: string;\n };\n\nfunction parseExplorerRoute(pathname: string): ExplorerRoute {\n const normalized = trimTrailingSlash(pathname) || \"/\";\n if (normalized === \"/\") {\n return { kind: \"root\" };\n }\n\n const segments = normalized.replace(/^\\/+/, \"\").split(\"/\");\n if (segments[0] === \"explorer\") {\n return { kind: \"explorer\" };\n }\n if (segments[0] === \"commands\") {\n return segments[1] ? { kind: \"command\", operationId: segments[1] } : { kind: \"command\" };\n }\n const surfaceKey = segments[0] ?? \"\";\n if (segments[1]) {\n return {\n kind: \"entity\",\n surfaceKey,\n id: decodeURIComponent(segments[1]),\n };\n }\n return { kind: \"surface\", surfaceKey };\n}\n\nfunction resolveRouteSurface(route: ExplorerRoute, surfaces: ClickySurface[]): ExplorerRoute {\n if (route.kind !== \"surface\" && route.kind !== \"entity\") {\n return route;\n }\n const surface = surfaces.find((item) => item.key === route.surfaceKey);\n return surface ? { ...route, surface } : route;\n}\n\nfunction isSurfaceRouteActive(route: ExplorerRoute, surfaceKey: string) {\n return (\n (route.kind === \"surface\" && route.surfaceKey === surfaceKey) ||\n (route.kind === \"entity\" && route.surfaceKey === surfaceKey)\n );\n}\n\nfunction stripBasePath(pathname: string, basePath: string) {\n const base = trimTrailingSlash(basePath);\n if (!base || base === \"/\") {\n return trimTrailingSlash(pathname) || \"/\";\n }\n if (pathname === base) {\n return \"/\";\n }\n if (pathname.startsWith(`${base}/`)) {\n return trimTrailingSlash(pathname.slice(base.length)) || \"/\";\n }\n return trimTrailingSlash(pathname) || \"/\";\n}\n\nfunction UnknownSurface({ surfaceKey }: { surfaceKey: string }) {\n return (\n <div className=\"p-6 text-sm text-muted-foreground\">\n Unknown surface: <code>{surfaceKey}</code>\n </div>\n );\n}\n\nconst LEGACY_AUTORUN_QUERY_PARAM = \"__autoRun\";\n\ntype SurfaceGroup = {\n parent: string; // the slug; \"\" for surfaces that declared no parent\n label: string; // display name in the sidebar\n surfaces: ClickySurface[];\n};\n\n// groupSurfacesByParent buckets surfaces by their ClickySurface.parent slug,\n// preserving the order surfaces appeared in the spec. Surfaces with no parent\n// fall into a trailing \"\" bucket labelled \"Other\".\nfunction groupSurfacesByParent(surfaces: ClickySurface[]): SurfaceGroup[] {\n const order: string[] = [];\n const buckets = new Map<string, ClickySurface[]>();\n for (const surface of surfaces) {\n const parent = surface.parent ?? \"\";\n if (!buckets.has(parent)) {\n buckets.set(parent, []);\n order.push(parent);\n }\n buckets.get(parent)!.push(surface);\n }\n return order.map((parent) => ({\n parent,\n label: parent === \"\" ? \"Other\" : titleCase(parent),\n surfaces: buckets.get(parent)!,\n }));\n}\n\nfunction titleCase(value: string): string {\n if (!value) return value;\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction readCommandQueryParams(): { initialValues: Record<string, string>; autoRun: boolean } {\n if (typeof window === \"undefined\") {\n return { initialValues: {}, autoRun: false };\n }\n const search = new URLSearchParams(window.location.search);\n const initialValues: Record<string, string> = {};\n let autoRun = false;\n const positional: string[] = [];\n\n for (const [key, value] of search.entries()) {\n if (key === AUTORUN_QUERY_PARAM || key === LEGACY_AUTORUN_QUERY_PARAM) {\n autoRun = value === \"1\" || value === \"true\";\n continue;\n }\n if (key.startsWith(ARG_QUERY_PREFIX)) {\n const index = Number.parseInt(key.slice(ARG_QUERY_PREFIX.length), 10);\n if (Number.isFinite(index) && index >= 0) {\n positional[index] = value;\n }\n continue;\n }\n initialValues[key] = value;\n }\n\n const packedArgs = positional.filter((value) => value !== undefined).join(\" \");\n if (packedArgs !== \"\") {\n initialValues.args = packedArgs;\n }\n\n return { initialValues, autoRun };\n}\n"],"mappings":"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"}
@@ -48,6 +48,15 @@ export type EntityExplorerAppProps = {
48
48
  entityDetailBodyRenderer?: EntityDetailBodyRenderer;
49
49
  /** Host override for a loaded entity's "{title}: {id}" heading. */
50
50
  entityDetailHeaderRenderer?: EntityDetailHeaderRenderer;
51
+ /** Compact host controls (e.g. an edit icon) shown right after a surface's title or breadcrumb in the top bar. */
52
+ surfaceTitleActions?: (surfaceKey: string) => ReactNode;
53
+ /**
54
+ * Per-surface paging presentation, forwarded to OperationCatalog's
55
+ * `paginationMode`. Return undefined to keep automatic selection (a cursor
56
+ * walk whenever the list declares a cursor); return "paged" for a surface
57
+ * whose readers need prev/next offset controls.
58
+ */
59
+ surfacePaginationMode?: (surfaceKey: string) => "paged" | "infinite" | undefined;
51
60
  };
52
- export declare function EntityExplorerApp({ client, basePath, showApiExplorer, actions, formExtensions, formActions, surfaceActionLabels, resultRenderer, entityDetailBodyRenderer, entityDetailHeaderRenderer, }: EntityExplorerAppProps): import("react").JSX.Element;
61
+ export declare function EntityExplorerApp({ client, basePath, showApiExplorer, actions, formExtensions, formActions, surfaceActionLabels, resultRenderer, entityDetailBodyRenderer, entityDetailHeaderRenderer, surfaceTitleActions, surfacePaginationMode, }: EntityExplorerAppProps): import("react").JSX.Element;
53
62
  //# sourceMappingURL=EntityExplorerApp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityExplorerApp.d.ts","sourceRoot":"","sources":["../../src/rpc/EntityExplorerApp.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAaxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAChC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzE,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;;OAKG;IACH,cAAc,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;IAClE;;;;OAIG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,4DAA4D;IAC5D,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,mEAAmE;IACnE,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;CACzD,CAAC;AAKF,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,QAAa,EACb,eAAsB,EACtB,OAAO,EACP,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,wBAAwB,EACxB,0BAA0B,GAC3B,EAAE,sBAAsB,+BA6LxB"}
1
+ {"version":3,"file":"EntityExplorerApp.d.ts","sourceRoot":"","sources":["../../src/rpc/EntityExplorerApp.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGlF,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAaxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAChC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzE,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;;OAKG;IACH,cAAc,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;IAClE;;;;OAIG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,4DAA4D;IAC5D,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,4EAA4E;IAC5E,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,mEAAmE;IACnE,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD,kHAAkH;IAClH,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,SAAS,CAAC;IACxD;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;CAClF,CAAC;AAKF,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,QAAa,EACb,eAAsB,EACtB,OAAO,EACP,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,GACtB,EAAE,sBAAsB,+BA2NxB"}
@@ -4,15 +4,16 @@ import { AppShell } from "../layout/AppShell.js";
4
4
  import { useOperations } from "./useOperations.js";
5
5
  import { getClickySurfaces, makeSurfaceDefinition } from "./clickyMetadata.js";
6
6
  import { OperationCatalog } from "./OperationCatalog.js";
7
+ import { ExplorerNavContext } from "./explorer-nav-context.js";
7
8
  import { ARG_QUERY_PREFIX, buildCommandHref, trimTrailingSlash, withBasePath } from "./commandHref.js";
8
9
  import { OperationCommandPage } from "./OperationCommandPage.js";
9
10
  import { OperationEntityPage } from "./OperationEntityPage.js";
10
11
  import { surfaceNavSection } from "./surfaceNav.js";
11
- import { useEffect, useMemo } from "react";
12
- import { jsx, jsxs } from "react/jsx-runtime";
12
+ import { useCallback, useEffect, useMemo, useState } from "react";
13
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
14
  // src/rpc/EntityExplorerApp.tsx
14
15
  var SIDEBAR_COLLAPSED_KEY = "clicky-ui:sidebar:collapsed";
15
- function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, actions, formExtensions, formActions, surfaceActionLabels, resultRenderer, entityDetailBodyRenderer, entityDetailHeaderRenderer }) {
16
+ function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, actions, formExtensions, formActions, surfaceActionLabels, resultRenderer, entityDetailBodyRenderer, entityDetailHeaderRenderer, surfaceTitleActions, surfacePaginationMode }) {
16
17
  const formPre = formExtensions?.pre;
17
18
  const formPost = formExtensions?.post;
18
19
  const { pathname, renderLink, navigate } = useRouter();
@@ -64,6 +65,26 @@ function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, acti
64
65
  showApiExplorer,
65
66
  explorerDefinition
66
67
  ]);
68
+ const [navContainer, setNavContainer] = useState(null);
69
+ const [navClaims, setNavClaims] = useState(0);
70
+ const claimNav = useCallback(() => {
71
+ setNavClaims((count) => count + 1);
72
+ return () => setNavClaims((count) => count - 1);
73
+ }, []);
74
+ const surface = resolvedRoute.kind === "surface" ? resolvedRoute.surface : void 0;
75
+ const titleActions = surface ? surfaceTitleActions?.(surface.key) : void 0;
76
+ const paginationMode = surface ? surfacePaginationMode?.(surface.key) : void 0;
77
+ const navSlot = useMemo(() => ({
78
+ container: surface ? navContainer : null,
79
+ title: surface?.title ?? "",
80
+ titleActions,
81
+ claim: claimNav
82
+ }), [
83
+ claimNav,
84
+ navContainer,
85
+ surface,
86
+ titleActions
87
+ ]);
67
88
  useEffect(() => {
68
89
  if (defaultSurface == null || relativePath !== "/") return;
69
90
  navigate(withBasePath(basePath, `/${defaultSurface.key}`), { replace: true });
@@ -73,7 +94,7 @@ function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, acti
73
94
  relativePath,
74
95
  navigate
75
96
  ]);
76
- return /* @__PURE__ */ jsx(AppShell, {
97
+ const content = /* @__PURE__ */ jsx(AppShell, {
77
98
  brand: /* @__PURE__ */ jsxs("div", {
78
99
  className: "min-w-0",
79
100
  children: [/* @__PURE__ */ jsx("div", {
@@ -87,16 +108,27 @@ function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, acti
87
108
  navSections,
88
109
  sidebarFooter: /* @__PURE__ */ jsx(ThemeSwitcher, {}),
89
110
  ...actions ? { actions } : {},
90
- ...resolvedRoute.kind === "surface" && resolvedRoute.surface ? { nav: /* @__PURE__ */ jsxs("div", {
111
+ ...resolvedRoute.kind === "surface" && resolvedRoute.surface ? { nav: /* @__PURE__ */ jsxs(Fragment$1, { children: [navClaims === 0 && /* @__PURE__ */ jsxs("div", {
91
112
  className: "flex min-w-0 flex-1 items-baseline gap-density-2",
92
- children: [/* @__PURE__ */ jsx("h1", {
93
- className: "min-w-0 truncate text-base font-semibold tracking-tight",
94
- children: resolvedRoute.surface.title
95
- }), /* @__PURE__ */ jsx("p", {
96
- className: "hidden min-w-0 truncate text-sm text-muted-foreground lg:block",
97
- children: makeSurfaceDefinition(resolvedRoute.surface).description
98
- })]
99
- }) } : {},
113
+ children: [
114
+ /* @__PURE__ */ jsx("h1", {
115
+ className: "min-w-0 truncate text-base font-semibold tracking-tight",
116
+ children: resolvedRoute.surface.title
117
+ }),
118
+ titleActions ? /* @__PURE__ */ jsx("div", {
119
+ className: "flex shrink-0 items-center self-center",
120
+ children: titleActions
121
+ }) : null,
122
+ /* @__PURE__ */ jsx("p", {
123
+ className: "hidden min-w-0 truncate text-sm text-muted-foreground lg:block",
124
+ children: makeSurfaceDefinition(resolvedRoute.surface).description
125
+ })
126
+ ]
127
+ }), /* @__PURE__ */ jsx("div", {
128
+ ref: setNavContainer,
129
+ "data-slot": "explorer-nav",
130
+ className: "contents"
131
+ })] }) } : {},
100
132
  collapsedStorageKey: SIDEBAR_COLLAPSED_KEY,
101
133
  contentWidth: "full",
102
134
  contentClassName: "p-6",
@@ -111,7 +143,8 @@ function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, acti
111
143
  ...formPost ? { formPost } : {},
112
144
  ...formActions ? { formActions } : {},
113
145
  ...surfaceActionLabels?.[resolvedRoute.surface.key] ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] } : {},
114
- ...resultRenderer ? { resultRenderer } : {}
146
+ ...resultRenderer ? { resultRenderer } : {},
147
+ ...paginationMode ? { paginationMode } : {}
115
148
  }, resolvedRoute.surface.key) : /* @__PURE__ */ jsx(UnknownSurface, { surfaceKey: resolvedRoute.surfaceKey }) : resolvedRoute.kind === "entity" ? resolvedRoute.surface ? /* @__PURE__ */ jsx(OperationEntityPage, {
116
149
  definition: makeSurfaceDefinition(resolvedRoute.surface),
117
150
  entities: [resolvedRoute.surface.entity],
@@ -152,6 +185,10 @@ function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, acti
152
185
  children: "Redirecting…"
153
186
  })
154
187
  });
188
+ return /* @__PURE__ */ jsx(ExplorerNavContext.Provider, {
189
+ value: navSlot,
190
+ children: content
191
+ });
155
192
  }
156
193
  function parseExplorerRoute(pathname) {
157
194
  const normalized = trimTrailingSlash(pathname) || "/";
@@ -1 +1 @@
1
- {"version":3,"file":"EntityExplorerApp.js","names":["_jsx"],"sources":["../../src/rpc/EntityExplorerApp.tsx"],"sourcesContent":["import { useEffect, useMemo, type ReactNode } from \"react\";\nimport { ThemeSwitcher } from \"../components/theme-switcher\";\nimport type { PreExtension, PostExtension } from \"../components/json-schema-form-types\";\nimport type { ClickyCommandRuntime } from \"../data/Clicky\";\nimport { AppShell, type AppShellNavSection } from \"../layout/AppShell\";\nimport { getClickySurfaces, makeSurfaceDefinition } from \"./clickyMetadata\";\nimport {\n ARG_QUERY_PREFIX,\n AUTORUN_QUERY_PARAM,\n buildCommandHref,\n trimTrailingSlash,\n withBasePath,\n} from \"./commandHref\";\nimport { useRouter } from \"./router\";\nimport { OperationCatalog } from \"./OperationCatalog\";\nimport type { ResultRenderer } from \"./OperationResultView\";\nimport { OperationCommandPage } from \"./OperationCommandPage\";\nimport {\n OperationEntityPage,\n type EntityDetailBodyRenderer,\n type EntityDetailHeaderRenderer,\n} from \"./OperationEntityPage\";\nimport type { FormActionsRenderer } from \"./SchemaActionForm\";\nimport { surfaceNavSection } from \"./surfaceNav\";\nimport type { ClickySurface } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\nimport { useOperations } from \"./useOperations\";\n\nexport type SurfaceActionLabels = Record<string, Record<string, string>>;\n\nexport type EntityExplorerAppProps = {\n client: OperationsApiClient;\n basePath?: string;\n showApiExplorer?: boolean;\n /** Right-aligned top-bar cluster forwarded to AppShell's actions slot. */\n actions?: ReactNode;\n /**\n * Custom JsonSchemaForm field extensions applied to every create/edit form the\n * explorer renders — e.g. a SecretKeySelector widget keyed on an\n * `x-clicky-component` schema hint. `pre` transforms a resolved control; `post`\n * can replace the rendered value node with a custom component.\n */\n formExtensions?: { pre?: PreExtension[]; post?: PostExtension[] };\n /**\n * Optional extra footer actions added to every create/edit form (e.g. a\n * connection \"Test\" split-button). The renderer receives the live form value\n * and the action it submits to, so it can scope itself to a given entity.\n */\n formActions?: FormActionsRenderer;\n /** Per-surface labels keyed by x-clicky verb/actionName. */\n surfaceActionLabels?: SurfaceActionLabels;\n /**\n * @deprecated Superseded by per-surface icons emitted by the backend\n * (x-clicky-icon → ClickySurface.icon). AppShell section labels are plain\n * strings, so this group-header icon map is no longer rendered. Kept for\n * source-compatibility only.\n */\n surfaceIcons?: Record<string, ReactNode>;\n /**\n * Optional host override for the result surface. Called where an entity's\n * result table renders, with the current surface key, the raw response, and\n * the default OperationResultView element. Return `defaultView` to keep the\n * standard table, or a custom node (e.g. a LogsTable for trace/log profiles\n * flagged via x-clicky-render). Filtering/sorting policy is the host's choice.\n */\n resultRenderer?: ResultRenderer;\n /** Host override for a loaded entity's body; heading and actions remain. */\n entityDetailBodyRenderer?: EntityDetailBodyRenderer;\n /** Host override for a loaded entity's \"{title}: {id}\" heading. */\n entityDetailHeaderRenderer?: EntityDetailHeaderRenderer;\n};\n\n// SIDEBAR_COLLAPSED_KEY persists the AppShell rail collapsed flag across reloads.\nconst SIDEBAR_COLLAPSED_KEY = \"clicky-ui:sidebar:collapsed\";\n\nexport function EntityExplorerApp({\n client,\n basePath = \"\",\n showApiExplorer = true,\n actions,\n formExtensions,\n formActions,\n surfaceActionLabels,\n resultRenderer,\n entityDetailBodyRenderer,\n entityDetailHeaderRenderer,\n}: EntityExplorerAppProps) {\n const formPre = formExtensions?.pre;\n const formPost = formExtensions?.post;\n const { pathname, renderLink, navigate } = useRouter();\n const { spec } = useOperations(client);\n const surfaces = useMemo(() => getClickySurfaces(spec), [spec]);\n const surfaceGroups = useMemo(() => groupSurfacesByParent(surfaces), [surfaces]);\n const defaultSurface = useMemo(\n () => surfaces.find((surface) => !surface.admin) ?? surfaces[0],\n [surfaces],\n );\n const relativePath = useMemo(() => stripBasePath(pathname, basePath), [basePath, pathname]);\n const route = useMemo(() => parseExplorerRoute(relativePath), [relativePath]);\n const resolvedRoute = useMemo(() => resolveRouteSurface(route, surfaces), [route, surfaces]);\n const commandRuntime = useMemo<ClickyCommandRuntime>(\n () => ({\n client,\n hrefForCommand: (resolved) => buildCommandHref(basePath, resolved),\n onNavigate: (resolved) => {\n const href = buildCommandHref(basePath, resolved);\n if (!href) return;\n navigate(href);\n },\n }),\n [basePath, client, navigate],\n );\n const { initialValues: commandInitialValues } = useMemo(\n () =>\n resolvedRoute.kind === \"command\"\n ? readCommandQueryParams()\n : { initialValues: {}, autoRun: false },\n [resolvedRoute.kind, pathname],\n );\n const explorerDefinition = useMemo(\n () => ({\n key: \"explorer\",\n title: \"API Explorer\",\n description: \"Every operation exposed by the current OpenAPI spec.\",\n }),\n [],\n );\n const navSections = useMemo<AppShellNavSection[]>(() => {\n const sections: AppShellNavSection[] = surfaceGroups.map((group) =>\n surfaceNavSection(group.label, group.surfaces, {\n isActive: (surface) => isSurfaceRouteActive(resolvedRoute, surface.key),\n hrefFor: (surface) => withBasePath(basePath, `/${surface.key}`),\n }),\n );\n if (showApiExplorer) {\n sections.push({\n items: [\n {\n key: explorerDefinition.key,\n label: explorerDefinition.title,\n active: resolvedRoute.kind === \"explorer\" || resolvedRoute.kind === \"command\",\n to: withBasePath(basePath, \"/explorer\"),\n },\n ],\n });\n }\n return sections;\n }, [surfaceGroups, basePath, resolvedRoute, showApiExplorer, explorerDefinition]);\n\n useEffect(() => {\n if (defaultSurface == null || relativePath !== \"/\") return;\n navigate(withBasePath(basePath, `/${defaultSurface.key}`), { replace: true });\n }, [basePath, defaultSurface, relativePath, navigate]);\n\n const content = (\n <AppShell\n brand={\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-semibold\">\n {spec?.info.title ?? \"Clicky Explorer\"}\n </div>\n <div className=\"truncate text-xs text-sidebar-foreground/60\">\n Metadata-driven entity explorer\n </div>\n </div>\n }\n navSections={navSections}\n sidebarFooter={<ThemeSwitcher />}\n {...(actions ? { actions } : {})}\n // The page header belongs to the host, not to OperationCatalog — the\n // catalog renders only its results. OperationEntityPage still titles\n // itself, so this covers the collection route only.\n //\n // It rides in the top bar rather than a bodyHeader row: next to the rail\n // that bar is otherwise empty, and the row it replaces cost the result\n // table ~72px of the viewport it needs to keep its sticky head and\n // pagination footer on screen without the page itself scrolling.\n {...(resolvedRoute.kind === \"surface\" && resolvedRoute.surface\n ? {\n nav: (\n <div className=\"flex min-w-0 flex-1 items-baseline gap-density-2\">\n <h1 className=\"min-w-0 truncate text-base font-semibold tracking-tight\">\n {resolvedRoute.surface.title}\n </h1>\n <p className=\"hidden min-w-0 truncate text-sm text-muted-foreground lg:block\">\n {makeSurfaceDefinition(resolvedRoute.surface).description}\n </p>\n </div>\n ),\n }\n : {})}\n collapsedStorageKey={SIDEBAR_COLLAPSED_KEY}\n // Results are wide tables, not prose — let them use the whole workspace\n // instead of the centred reading column.\n contentWidth=\"full\"\n contentClassName=\"p-6\"\n >\n {resolvedRoute.kind === \"surface\" ? (\n resolvedRoute.surface ? (\n <OperationCatalog\n // Filter state is seeded from the URL when the catalog mounts and\n // written back to it, so one instance spanning two surfaces would\n // carry the first surface's filters onto the second's URL. Keying\n // on the surface makes each one start from its own query string.\n key={resolvedRoute.surface.key}\n definition={makeSurfaceDefinition(resolvedRoute.surface)}\n entities={[resolvedRoute.surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={resolvedRoute.surface.key}\n commandRuntime={commandRuntime}\n {...(formPre ? { formPre } : {})}\n {...(formPost ? { formPost } : {})}\n {...(formActions ? { formActions } : {})}\n {...(surfaceActionLabels?.[resolvedRoute.surface.key]\n ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] }\n : {})}\n {...(resultRenderer ? { resultRenderer } : {})}\n />\n ) : (\n <UnknownSurface surfaceKey={resolvedRoute.surfaceKey} />\n )\n ) : resolvedRoute.kind === \"entity\" ? (\n resolvedRoute.surface ? (\n <OperationEntityPage\n definition={makeSurfaceDefinition(resolvedRoute.surface)}\n entities={[resolvedRoute.surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={resolvedRoute.surface.key}\n backHref={withBasePath(basePath, `/${resolvedRoute.surface.key}`)}\n backLabel={`Back to ${resolvedRoute.surface.title}`}\n commandRuntime={commandRuntime}\n {...(formPre ? { formPre } : {})}\n {...(formPost ? { formPost } : {})}\n {...(formActions ? { formActions } : {})}\n {...(surfaceActionLabels?.[resolvedRoute.surface.key]\n ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] }\n : {})}\n {...(entityDetailBodyRenderer ? { entityDetailBodyRenderer } : {})}\n {...(entityDetailHeaderRenderer ? { entityDetailHeaderRenderer } : {})}\n {...(resolvedRoute.id ? { id: resolvedRoute.id } : {})}\n />\n ) : (\n <UnknownSurface surfaceKey={resolvedRoute.surfaceKey} />\n )\n ) : resolvedRoute.kind === \"command\" ? (\n <OperationCommandPage\n client={client}\n backHref={withBasePath(basePath, \"/explorer\")}\n backLabel=\"Back to API Explorer\"\n renderLink={renderLink}\n commandRuntime={commandRuntime}\n initialValues={commandInitialValues}\n autoRun={true}\n {...(resolvedRoute.operationId ? { operationId: resolvedRoute.operationId } : {})}\n />\n ) : resolvedRoute.kind === \"explorer\" ? (\n <OperationCatalog\n definition={explorerDefinition}\n entities={[]}\n allOperations\n client={client}\n renderLink={renderLink}\n commandRuntime={commandRuntime}\n />\n ) : defaultSurface == null ? (\n <div className=\"text-sm text-muted-foreground\">Loading surfaces…</div>\n ) : (\n <div className=\"text-sm text-muted-foreground\">Redirecting…</div>\n )}\n </AppShell>\n );\n\n return content;\n}\n\ntype ExplorerRoute =\n | { kind: \"root\" }\n | { kind: \"explorer\" }\n | { kind: \"command\"; operationId?: string }\n | { kind: \"surface\"; surfaceKey: string; surface?: ClickySurface }\n | {\n kind: \"entity\";\n surfaceKey: string;\n surface?: ClickySurface;\n id?: string;\n };\n\nfunction parseExplorerRoute(pathname: string): ExplorerRoute {\n const normalized = trimTrailingSlash(pathname) || \"/\";\n if (normalized === \"/\") {\n return { kind: \"root\" };\n }\n\n const segments = normalized.replace(/^\\/+/, \"\").split(\"/\");\n if (segments[0] === \"explorer\") {\n return { kind: \"explorer\" };\n }\n if (segments[0] === \"commands\") {\n return segments[1] ? { kind: \"command\", operationId: segments[1] } : { kind: \"command\" };\n }\n const surfaceKey = segments[0] ?? \"\";\n if (segments[1]) {\n return {\n kind: \"entity\",\n surfaceKey,\n id: decodeURIComponent(segments[1]),\n };\n }\n return { kind: \"surface\", surfaceKey };\n}\n\nfunction resolveRouteSurface(route: ExplorerRoute, surfaces: ClickySurface[]): ExplorerRoute {\n if (route.kind !== \"surface\" && route.kind !== \"entity\") {\n return route;\n }\n const surface = surfaces.find((item) => item.key === route.surfaceKey);\n return surface ? { ...route, surface } : route;\n}\n\nfunction isSurfaceRouteActive(route: ExplorerRoute, surfaceKey: string) {\n return (\n (route.kind === \"surface\" && route.surfaceKey === surfaceKey) ||\n (route.kind === \"entity\" && route.surfaceKey === surfaceKey)\n );\n}\n\nfunction stripBasePath(pathname: string, basePath: string) {\n const base = trimTrailingSlash(basePath);\n if (!base || base === \"/\") {\n return trimTrailingSlash(pathname) || \"/\";\n }\n if (pathname === base) {\n return \"/\";\n }\n if (pathname.startsWith(`${base}/`)) {\n return trimTrailingSlash(pathname.slice(base.length)) || \"/\";\n }\n return trimTrailingSlash(pathname) || \"/\";\n}\n\nfunction UnknownSurface({ surfaceKey }: { surfaceKey: string }) {\n return (\n <div className=\"p-6 text-sm text-muted-foreground\">\n Unknown surface: <code>{surfaceKey}</code>\n </div>\n );\n}\n\nconst LEGACY_AUTORUN_QUERY_PARAM = \"__autoRun\";\n\ntype SurfaceGroup = {\n parent: string; // the slug; \"\" for surfaces that declared no parent\n label: string; // display name in the sidebar\n surfaces: ClickySurface[];\n};\n\n// groupSurfacesByParent buckets surfaces by their ClickySurface.parent slug,\n// preserving the order surfaces appeared in the spec. Surfaces with no parent\n// fall into a trailing \"\" bucket labelled \"Other\".\nfunction groupSurfacesByParent(surfaces: ClickySurface[]): SurfaceGroup[] {\n const order: string[] = [];\n const buckets = new Map<string, ClickySurface[]>();\n for (const surface of surfaces) {\n const parent = surface.parent ?? \"\";\n if (!buckets.has(parent)) {\n buckets.set(parent, []);\n order.push(parent);\n }\n buckets.get(parent)!.push(surface);\n }\n return order.map((parent) => ({\n parent,\n label: parent === \"\" ? \"Other\" : titleCase(parent),\n surfaces: buckets.get(parent)!,\n }));\n}\n\nfunction titleCase(value: string): string {\n if (!value) return value;\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction readCommandQueryParams(): { initialValues: Record<string, string>; autoRun: boolean } {\n if (typeof window === \"undefined\") {\n return { initialValues: {}, autoRun: false };\n }\n const search = new URLSearchParams(window.location.search);\n const initialValues: Record<string, string> = {};\n let autoRun = false;\n const positional: string[] = [];\n\n for (const [key, value] of search.entries()) {\n if (key === AUTORUN_QUERY_PARAM || key === LEGACY_AUTORUN_QUERY_PARAM) {\n autoRun = value === \"1\" || value === \"true\";\n continue;\n }\n if (key.startsWith(ARG_QUERY_PREFIX)) {\n const index = Number.parseInt(key.slice(ARG_QUERY_PREFIX.length), 10);\n if (Number.isFinite(index) && index >= 0) {\n positional[index] = value;\n }\n continue;\n }\n initialValues[key] = value;\n }\n\n const packedArgs = positional.filter((value) => value !== undefined).join(\" \");\n if (packedArgs !== \"\") {\n initialValues.args = packedArgs;\n }\n\n return { initialValues, autoRun };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EntityExplorerApp.js","names":["_Fragment"],"sources":["../../src/rpc/EntityExplorerApp.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport { ExplorerNavContext, type ExplorerNavSlot } from \"./explorer-nav-context\";\nimport { ThemeSwitcher } from \"../components/theme-switcher\";\nimport type { PreExtension, PostExtension } from \"../components/json-schema-form-types\";\nimport type { ClickyCommandRuntime } from \"../data/Clicky\";\nimport { AppShell, type AppShellNavSection } from \"../layout/AppShell\";\nimport { getClickySurfaces, makeSurfaceDefinition } from \"./clickyMetadata\";\nimport {\n ARG_QUERY_PREFIX,\n AUTORUN_QUERY_PARAM,\n buildCommandHref,\n trimTrailingSlash,\n withBasePath,\n} from \"./commandHref\";\nimport { useRouter } from \"./router\";\nimport { OperationCatalog } from \"./OperationCatalog\";\nimport type { ResultRenderer } from \"./OperationResultView\";\nimport { OperationCommandPage } from \"./OperationCommandPage\";\nimport {\n OperationEntityPage,\n type EntityDetailBodyRenderer,\n type EntityDetailHeaderRenderer,\n} from \"./OperationEntityPage\";\nimport type { FormActionsRenderer } from \"./SchemaActionForm\";\nimport { surfaceNavSection } from \"./surfaceNav\";\nimport type { ClickySurface } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\nimport { useOperations } from \"./useOperations\";\n\nexport type SurfaceActionLabels = Record<string, Record<string, string>>;\n\nexport type EntityExplorerAppProps = {\n client: OperationsApiClient;\n basePath?: string;\n showApiExplorer?: boolean;\n /** Right-aligned top-bar cluster forwarded to AppShell's actions slot. */\n actions?: ReactNode;\n /**\n * Custom JsonSchemaForm field extensions applied to every create/edit form the\n * explorer renders — e.g. a SecretKeySelector widget keyed on an\n * `x-clicky-component` schema hint. `pre` transforms a resolved control; `post`\n * can replace the rendered value node with a custom component.\n */\n formExtensions?: { pre?: PreExtension[]; post?: PostExtension[] };\n /**\n * Optional extra footer actions added to every create/edit form (e.g. a\n * connection \"Test\" split-button). The renderer receives the live form value\n * and the action it submits to, so it can scope itself to a given entity.\n */\n formActions?: FormActionsRenderer;\n /** Per-surface labels keyed by x-clicky verb/actionName. */\n surfaceActionLabels?: SurfaceActionLabels;\n /**\n * @deprecated Superseded by per-surface icons emitted by the backend\n * (x-clicky-icon → ClickySurface.icon). AppShell section labels are plain\n * strings, so this group-header icon map is no longer rendered. Kept for\n * source-compatibility only.\n */\n surfaceIcons?: Record<string, ReactNode>;\n /**\n * Optional host override for the result surface. Called where an entity's\n * result table renders, with the current surface key, the raw response, and\n * the default OperationResultView element. Return `defaultView` to keep the\n * standard table, or a custom node (e.g. a LogsTable for trace/log profiles\n * flagged via x-clicky-render). Filtering/sorting policy is the host's choice.\n */\n resultRenderer?: ResultRenderer;\n /** Host override for a loaded entity's body; heading and actions remain. */\n entityDetailBodyRenderer?: EntityDetailBodyRenderer;\n /** Host override for a loaded entity's \"{title}: {id}\" heading. */\n entityDetailHeaderRenderer?: EntityDetailHeaderRenderer;\n /** Compact host controls (e.g. an edit icon) shown right after a surface's title or breadcrumb in the top bar. */\n surfaceTitleActions?: (surfaceKey: string) => ReactNode;\n /**\n * Per-surface paging presentation, forwarded to OperationCatalog's\n * `paginationMode`. Return undefined to keep automatic selection (a cursor\n * walk whenever the list declares a cursor); return \"paged\" for a surface\n * whose readers need prev/next offset controls.\n */\n surfacePaginationMode?: (surfaceKey: string) => \"paged\" | \"infinite\" | undefined;\n};\n\n// SIDEBAR_COLLAPSED_KEY persists the AppShell rail collapsed flag across reloads.\nconst SIDEBAR_COLLAPSED_KEY = \"clicky-ui:sidebar:collapsed\";\n\nexport function EntityExplorerApp({\n client,\n basePath = \"\",\n showApiExplorer = true,\n actions,\n formExtensions,\n formActions,\n surfaceActionLabels,\n resultRenderer,\n entityDetailBodyRenderer,\n entityDetailHeaderRenderer,\n surfaceTitleActions,\n surfacePaginationMode,\n}: EntityExplorerAppProps) {\n const formPre = formExtensions?.pre;\n const formPost = formExtensions?.post;\n const { pathname, renderLink, navigate } = useRouter();\n const { spec } = useOperations(client);\n const surfaces = useMemo(() => getClickySurfaces(spec), [spec]);\n const surfaceGroups = useMemo(() => groupSurfacesByParent(surfaces), [surfaces]);\n const defaultSurface = useMemo(\n () => surfaces.find((surface) => !surface.admin) ?? surfaces[0],\n [surfaces],\n );\n const relativePath = useMemo(() => stripBasePath(pathname, basePath), [basePath, pathname]);\n const route = useMemo(() => parseExplorerRoute(relativePath), [relativePath]);\n const resolvedRoute = useMemo(() => resolveRouteSurface(route, surfaces), [route, surfaces]);\n const commandRuntime = useMemo<ClickyCommandRuntime>(\n () => ({\n client,\n hrefForCommand: (resolved) => buildCommandHref(basePath, resolved),\n onNavigate: (resolved) => {\n const href = buildCommandHref(basePath, resolved);\n if (!href) return;\n navigate(href);\n },\n }),\n [basePath, client, navigate],\n );\n const { initialValues: commandInitialValues } = useMemo(\n () =>\n resolvedRoute.kind === \"command\"\n ? readCommandQueryParams()\n : { initialValues: {}, autoRun: false },\n [resolvedRoute.kind, pathname],\n );\n const explorerDefinition = useMemo(\n () => ({\n key: \"explorer\",\n title: \"API Explorer\",\n description: \"Every operation exposed by the current OpenAPI spec.\",\n }),\n [],\n );\n const navSections = useMemo<AppShellNavSection[]>(() => {\n const sections: AppShellNavSection[] = surfaceGroups.map((group) =>\n surfaceNavSection(group.label, group.surfaces, {\n isActive: (surface) => isSurfaceRouteActive(resolvedRoute, surface.key),\n hrefFor: (surface) => withBasePath(basePath, `/${surface.key}`),\n }),\n );\n if (showApiExplorer) {\n sections.push({\n items: [\n {\n key: explorerDefinition.key,\n label: explorerDefinition.title,\n active: resolvedRoute.kind === \"explorer\" || resolvedRoute.kind === \"command\",\n to: withBasePath(basePath, \"/explorer\"),\n },\n ],\n });\n }\n return sections;\n }, [surfaceGroups, basePath, resolvedRoute, showApiExplorer, explorerDefinition]);\n\n const [navContainer, setNavContainer] = useState<HTMLElement | null>(null);\n const [navClaims, setNavClaims] = useState(0);\n const claimNav = useCallback(() => {\n setNavClaims((count) => count + 1);\n return () => setNavClaims((count) => count - 1);\n }, []);\n const surface = resolvedRoute.kind === \"surface\" ? resolvedRoute.surface : undefined;\n const titleActions = surface ? surfaceTitleActions?.(surface.key) : undefined;\n const paginationMode = surface ? surfacePaginationMode?.(surface.key) : undefined;\n // The container only exists while a surface is resolved, so a portal\n // mounted before the spec loads renders nothing rather than a bare crumb.\n const navSlot = useMemo<ExplorerNavSlot>(\n () => ({\n container: surface ? navContainer : null,\n title: surface?.title ?? \"\",\n titleActions,\n claim: claimNav,\n }),\n [claimNav, navContainer, surface, titleActions],\n );\n\n useEffect(() => {\n if (defaultSurface == null || relativePath !== \"/\") return;\n navigate(withBasePath(basePath, `/${defaultSurface.key}`), { replace: true });\n }, [basePath, defaultSurface, relativePath, navigate]);\n\n const content = (\n <AppShell\n brand={\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-semibold\">\n {spec?.info.title ?? \"Clicky Explorer\"}\n </div>\n <div className=\"truncate text-xs text-sidebar-foreground/60\">\n Metadata-driven entity explorer\n </div>\n </div>\n }\n navSections={navSections}\n sidebarFooter={<ThemeSwitcher />}\n {...(actions ? { actions } : {})}\n // The page header belongs to the host, not to OperationCatalog — the\n // catalog renders only its results. OperationEntityPage still titles\n // itself, so this covers the collection route only.\n //\n // It rides in the top bar rather than a bodyHeader row: next to the rail\n // that bar is otherwise empty, and the row it replaces cost the result\n // table ~72px of the viewport it needs to keep its sticky head and\n // pagination footer on screen without the page itself scrolling.\n {...(resolvedRoute.kind === \"surface\" && resolvedRoute.surface\n ? {\n nav: (\n <>\n {navClaims === 0 && (\n <div className=\"flex min-w-0 flex-1 items-baseline gap-density-2\">\n <h1 className=\"min-w-0 truncate text-base font-semibold tracking-tight\">\n {resolvedRoute.surface.title}\n </h1>\n {titleActions ? (\n <div className=\"flex shrink-0 items-center self-center\">{titleActions}</div>\n ) : null}\n <p className=\"hidden min-w-0 truncate text-sm text-muted-foreground lg:block\">\n {makeSurfaceDefinition(resolvedRoute.surface).description}\n </p>\n </div>\n )}\n <div ref={setNavContainer} data-slot=\"explorer-nav\" className=\"contents\" />\n </>\n ),\n }\n : {})}\n collapsedStorageKey={SIDEBAR_COLLAPSED_KEY}\n // Results are wide tables, not prose — let them use the whole workspace\n // instead of the centred reading column.\n contentWidth=\"full\"\n contentClassName=\"p-6\"\n >\n {resolvedRoute.kind === \"surface\" ? (\n resolvedRoute.surface ? (\n <OperationCatalog\n // Filter state is seeded from the URL when the catalog mounts and\n // written back to it, so one instance spanning two surfaces would\n // carry the first surface's filters onto the second's URL. Keying\n // on the surface makes each one start from its own query string.\n key={resolvedRoute.surface.key}\n definition={makeSurfaceDefinition(resolvedRoute.surface)}\n entities={[resolvedRoute.surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={resolvedRoute.surface.key}\n commandRuntime={commandRuntime}\n {...(formPre ? { formPre } : {})}\n {...(formPost ? { formPost } : {})}\n {...(formActions ? { formActions } : {})}\n {...(surfaceActionLabels?.[resolvedRoute.surface.key]\n ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] }\n : {})}\n {...(resultRenderer ? { resultRenderer } : {})}\n {...(paginationMode ? { paginationMode } : {})}\n />\n ) : (\n <UnknownSurface surfaceKey={resolvedRoute.surfaceKey} />\n )\n ) : resolvedRoute.kind === \"entity\" ? (\n resolvedRoute.surface ? (\n <OperationEntityPage\n definition={makeSurfaceDefinition(resolvedRoute.surface)}\n entities={[resolvedRoute.surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={resolvedRoute.surface.key}\n backHref={withBasePath(basePath, `/${resolvedRoute.surface.key}`)}\n backLabel={`Back to ${resolvedRoute.surface.title}`}\n commandRuntime={commandRuntime}\n {...(formPre ? { formPre } : {})}\n {...(formPost ? { formPost } : {})}\n {...(formActions ? { formActions } : {})}\n {...(surfaceActionLabels?.[resolvedRoute.surface.key]\n ? { actionLabels: surfaceActionLabels[resolvedRoute.surface.key] }\n : {})}\n {...(entityDetailBodyRenderer ? { entityDetailBodyRenderer } : {})}\n {...(entityDetailHeaderRenderer ? { entityDetailHeaderRenderer } : {})}\n {...(resolvedRoute.id ? { id: resolvedRoute.id } : {})}\n />\n ) : (\n <UnknownSurface surfaceKey={resolvedRoute.surfaceKey} />\n )\n ) : resolvedRoute.kind === \"command\" ? (\n <OperationCommandPage\n client={client}\n backHref={withBasePath(basePath, \"/explorer\")}\n backLabel=\"Back to API Explorer\"\n renderLink={renderLink}\n commandRuntime={commandRuntime}\n initialValues={commandInitialValues}\n autoRun={true}\n {...(resolvedRoute.operationId ? { operationId: resolvedRoute.operationId } : {})}\n />\n ) : resolvedRoute.kind === \"explorer\" ? (\n <OperationCatalog\n definition={explorerDefinition}\n entities={[]}\n allOperations\n client={client}\n renderLink={renderLink}\n commandRuntime={commandRuntime}\n />\n ) : defaultSurface == null ? (\n <div className=\"text-sm text-muted-foreground\">Loading surfaces…</div>\n ) : (\n <div className=\"text-sm text-muted-foreground\">Redirecting…</div>\n )}\n </AppShell>\n );\n\n return <ExplorerNavContext.Provider value={navSlot}>{content}</ExplorerNavContext.Provider>;\n}\n\ntype ExplorerRoute =\n | { kind: \"root\" }\n | { kind: \"explorer\" }\n | { kind: \"command\"; operationId?: string }\n | { kind: \"surface\"; surfaceKey: string; surface?: ClickySurface }\n | {\n kind: \"entity\";\n surfaceKey: string;\n surface?: ClickySurface;\n id?: string;\n };\n\nfunction parseExplorerRoute(pathname: string): ExplorerRoute {\n const normalized = trimTrailingSlash(pathname) || \"/\";\n if (normalized === \"/\") {\n return { kind: \"root\" };\n }\n\n const segments = normalized.replace(/^\\/+/, \"\").split(\"/\");\n if (segments[0] === \"explorer\") {\n return { kind: \"explorer\" };\n }\n if (segments[0] === \"commands\") {\n return segments[1] ? { kind: \"command\", operationId: segments[1] } : { kind: \"command\" };\n }\n const surfaceKey = segments[0] ?? \"\";\n if (segments[1]) {\n return {\n kind: \"entity\",\n surfaceKey,\n id: decodeURIComponent(segments[1]),\n };\n }\n return { kind: \"surface\", surfaceKey };\n}\n\nfunction resolveRouteSurface(route: ExplorerRoute, surfaces: ClickySurface[]): ExplorerRoute {\n if (route.kind !== \"surface\" && route.kind !== \"entity\") {\n return route;\n }\n const surface = surfaces.find((item) => item.key === route.surfaceKey);\n return surface ? { ...route, surface } : route;\n}\n\nfunction isSurfaceRouteActive(route: ExplorerRoute, surfaceKey: string) {\n return (\n (route.kind === \"surface\" && route.surfaceKey === surfaceKey) ||\n (route.kind === \"entity\" && route.surfaceKey === surfaceKey)\n );\n}\n\nfunction stripBasePath(pathname: string, basePath: string) {\n const base = trimTrailingSlash(basePath);\n if (!base || base === \"/\") {\n return trimTrailingSlash(pathname) || \"/\";\n }\n if (pathname === base) {\n return \"/\";\n }\n if (pathname.startsWith(`${base}/`)) {\n return trimTrailingSlash(pathname.slice(base.length)) || \"/\";\n }\n return trimTrailingSlash(pathname) || \"/\";\n}\n\nfunction UnknownSurface({ surfaceKey }: { surfaceKey: string }) {\n return (\n <div className=\"p-6 text-sm text-muted-foreground\">\n Unknown surface: <code>{surfaceKey}</code>\n </div>\n );\n}\n\nconst LEGACY_AUTORUN_QUERY_PARAM = \"__autoRun\";\n\ntype SurfaceGroup = {\n parent: string; // the slug; \"\" for surfaces that declared no parent\n label: string; // display name in the sidebar\n surfaces: ClickySurface[];\n};\n\n// groupSurfacesByParent buckets surfaces by their ClickySurface.parent slug,\n// preserving the order surfaces appeared in the spec. Surfaces with no parent\n// fall into a trailing \"\" bucket labelled \"Other\".\nfunction groupSurfacesByParent(surfaces: ClickySurface[]): SurfaceGroup[] {\n const order: string[] = [];\n const buckets = new Map<string, ClickySurface[]>();\n for (const surface of surfaces) {\n const parent = surface.parent ?? \"\";\n if (!buckets.has(parent)) {\n buckets.set(parent, []);\n order.push(parent);\n }\n buckets.get(parent)!.push(surface);\n }\n return order.map((parent) => ({\n parent,\n label: parent === \"\" ? \"Other\" : titleCase(parent),\n surfaces: buckets.get(parent)!,\n }));\n}\n\nfunction titleCase(value: string): string {\n if (!value) return value;\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction readCommandQueryParams(): { initialValues: Record<string, string>; autoRun: boolean } {\n if (typeof window === \"undefined\") {\n return { initialValues: {}, autoRun: false };\n }\n const search = new URLSearchParams(window.location.search);\n const initialValues: Record<string, string> = {};\n let autoRun = false;\n const positional: string[] = [];\n\n for (const [key, value] of search.entries()) {\n if (key === AUTORUN_QUERY_PARAM || key === LEGACY_AUTORUN_QUERY_PARAM) {\n autoRun = value === \"1\" || value === \"true\";\n continue;\n }\n if (key.startsWith(ARG_QUERY_PREFIX)) {\n const index = Number.parseInt(key.slice(ARG_QUERY_PREFIX.length), 10);\n if (Number.isFinite(index) && index >= 0) {\n positional[index] = value;\n }\n continue;\n }\n initialValues[key] = value;\n }\n\n const packedArgs = positional.filter((value) => value !== undefined).join(\" \");\n if (packedArgs !== \"\") {\n initialValues.args = packedArgs;\n }\n\n return { initialValues, autoRun };\n}\n"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ const require_router = require("./router.cjs");
2
+ const require_useOperations = require("./useOperations.cjs");
3
+ const require_clickyMetadata = require("./clickyMetadata.cjs");
4
+ const require_OperationCatalog = require("./OperationCatalog.cjs");
5
+ let react = require("react");
6
+ let react_jsx_runtime = require("react/jsx-runtime");
7
+ // src/rpc/EntitySurface.tsx
8
+ /**
9
+ * EntitySurface lists one surface wherever a host places it — the same listing,
10
+ * filters and result renderer EntityExplorerApp shows on the surface's own
11
+ * route, embedded in another page (e.g. a connection's logs on its detail page).
12
+ * Filter state lives in the current URL's query string, as it does on the route.
13
+ */
14
+ function EntitySurface({ client, surfaceKey, resultRenderer, paginationMode }) {
15
+ const { renderLink } = require_router.useRouter();
16
+ const { spec } = require_useOperations.useOperations(client);
17
+ const surface = (0, react.useMemo)(() => spec ? require_clickyMetadata.getClickySurfaces(spec).find((item) => item.key === surfaceKey) : void 0, [spec, surfaceKey]);
18
+ if (!spec) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
19
+ className: "text-sm text-muted-foreground",
20
+ children: "Loading…"
21
+ });
22
+ if (!surface) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
23
+ className: "text-sm text-muted-foreground",
24
+ children: ["Unknown surface: ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: surfaceKey })]
25
+ });
26
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_OperationCatalog.OperationCatalog, {
27
+ definition: require_clickyMetadata.makeSurfaceDefinition(surface),
28
+ entities: [surface.entity],
29
+ client,
30
+ renderLink,
31
+ surfaceKey: surface.key,
32
+ ...resultRenderer ? { resultRenderer } : {},
33
+ ...paginationMode ? { paginationMode } : {}
34
+ }, surface.key);
35
+ }
36
+ exports.EntitySurface = EntitySurface;
37
+
38
+ //# sourceMappingURL=EntitySurface.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntitySurface.cjs","names":["useRouter","useOperations","useMemo","getClickySurfaces","OperationCatalog","makeSurfaceDefinition"],"sources":["../../src/rpc/EntitySurface.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { getClickySurfaces, makeSurfaceDefinition } from \"./clickyMetadata\";\nimport { OperationCatalog } from \"./OperationCatalog\";\nimport type { ResultRenderer } from \"./OperationResultView\";\nimport { useRouter } from \"./router\";\nimport type { OperationsApiClient } from \"./useOperations\";\nimport { useOperations } from \"./useOperations\";\n\nexport type EntitySurfaceProps = {\n client: OperationsApiClient;\n /** The surface to list, as the OpenAPI spec's `x-clicky.surfaces` keys it. */\n surfaceKey: string;\n resultRenderer?: ResultRenderer;\n paginationMode?: \"paged\" | \"infinite\";\n};\n\n/**\n * EntitySurface lists one surface wherever a host places it — the same listing,\n * filters and result renderer EntityExplorerApp shows on the surface's own\n * route, embedded in another page (e.g. a connection's logs on its detail page).\n * Filter state lives in the current URL's query string, as it does on the route.\n */\nexport function EntitySurface({ client, surfaceKey, resultRenderer, paginationMode }: EntitySurfaceProps) {\n const { renderLink } = useRouter();\n const { spec } = useOperations(client);\n const surface = useMemo(\n () => (spec ? getClickySurfaces(spec).find((item) => item.key === surfaceKey) : undefined),\n [spec, surfaceKey],\n );\n if (!spec) return <div className=\"text-sm text-muted-foreground\">Loading…</div>;\n if (!surface) {\n return (\n <div className=\"text-sm text-muted-foreground\">\n Unknown surface: <code>{surfaceKey}</code>\n </div>\n );\n }\n return (\n <OperationCatalog\n key={surface.key}\n definition={makeSurfaceDefinition(surface)}\n entities={[surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={surface.key}\n {...(resultRenderer ? { resultRenderer } : {})}\n {...(paginationMode ? { paginationMode } : {})}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAsBA,SAAgB,cAAc,EAAE,QAAQ,YAAY,gBAAgB,kBAAsC;CACxG,MAAM,EAAE,eAAeA,eAAAA,UAAU;CACjC,MAAM,EAAE,SAASC,sBAAAA,cAAc,MAAM;CACrC,MAAM,WAAA,GAAUC,MAAAA,QAAAA,OACP,OAAOC,uBAAAA,kBAAkB,IAAI,CAAC,CAAC,MAAM,SAAS,KAAK,QAAQ,UAAU,IAAI,KAAA,GAChF,CAAC,MAAM,UAAU,CACnB;CACA,IAAI,CAAC,MAAM,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EAAgC,UAAA;CAAa,CAAA;CAC9E,IAAI,CAAC,SACH,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CAA+C,qBAC5B,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,WAAiB,CAAA,CACtC;;CAGT,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,yBAAAA,kBAAD;EAEE,YAAYC,uBAAAA,sBAAsB,OAAO;EACzC,UAAU,CAAC,QAAQ,MAAM;EACjB;EACI;EACZ,YAAY,QAAQ;EACpB,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;EAC5C,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;CAC7C,GARM,QAAQ,GAQd;AAEL"}
@@ -0,0 +1,17 @@
1
+ import { ResultRenderer } from './OperationResultView.js';
2
+ import { OperationsApiClient } from './useOperations.js';
3
+ export type EntitySurfaceProps = {
4
+ client: OperationsApiClient;
5
+ /** The surface to list, as the OpenAPI spec's `x-clicky.surfaces` keys it. */
6
+ surfaceKey: string;
7
+ resultRenderer?: ResultRenderer;
8
+ paginationMode?: "paged" | "infinite";
9
+ };
10
+ /**
11
+ * EntitySurface lists one surface wherever a host places it — the same listing,
12
+ * filters and result renderer EntityExplorerApp shows on the surface's own
13
+ * route, embedded in another page (e.g. a connection's logs on its detail page).
14
+ * Filter state lives in the current URL's query string, as it does on the route.
15
+ */
16
+ export declare function EntitySurface({ client, surfaceKey, resultRenderer, paginationMode }: EntitySurfaceProps): import("react").JSX.Element;
17
+ //# sourceMappingURL=EntitySurface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntitySurface.d.ts","sourceRoot":"","sources":["../../src/rpc/EntitySurface.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,cAAc,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,EAAE,kBAAkB,+BA2BvG"}
@@ -0,0 +1,38 @@
1
+ import { useRouter } from "./router.js";
2
+ import { useOperations } from "./useOperations.js";
3
+ import { getClickySurfaces, makeSurfaceDefinition } from "./clickyMetadata.js";
4
+ import { OperationCatalog } from "./OperationCatalog.js";
5
+ import { useMemo } from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ // src/rpc/EntitySurface.tsx
8
+ /**
9
+ * EntitySurface lists one surface wherever a host places it — the same listing,
10
+ * filters and result renderer EntityExplorerApp shows on the surface's own
11
+ * route, embedded in another page (e.g. a connection's logs on its detail page).
12
+ * Filter state lives in the current URL's query string, as it does on the route.
13
+ */
14
+ function EntitySurface({ client, surfaceKey, resultRenderer, paginationMode }) {
15
+ const { renderLink } = useRouter();
16
+ const { spec } = useOperations(client);
17
+ const surface = useMemo(() => spec ? getClickySurfaces(spec).find((item) => item.key === surfaceKey) : void 0, [spec, surfaceKey]);
18
+ if (!spec) return /* @__PURE__ */ jsx("div", {
19
+ className: "text-sm text-muted-foreground",
20
+ children: "Loading…"
21
+ });
22
+ if (!surface) return /* @__PURE__ */ jsxs("div", {
23
+ className: "text-sm text-muted-foreground",
24
+ children: ["Unknown surface: ", /* @__PURE__ */ jsx("code", { children: surfaceKey })]
25
+ });
26
+ return /* @__PURE__ */ jsx(OperationCatalog, {
27
+ definition: makeSurfaceDefinition(surface),
28
+ entities: [surface.entity],
29
+ client,
30
+ renderLink,
31
+ surfaceKey: surface.key,
32
+ ...resultRenderer ? { resultRenderer } : {},
33
+ ...paginationMode ? { paginationMode } : {}
34
+ }, surface.key);
35
+ }
36
+ export { EntitySurface };
37
+
38
+ //# sourceMappingURL=EntitySurface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntitySurface.js","names":[],"sources":["../../src/rpc/EntitySurface.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { getClickySurfaces, makeSurfaceDefinition } from \"./clickyMetadata\";\nimport { OperationCatalog } from \"./OperationCatalog\";\nimport type { ResultRenderer } from \"./OperationResultView\";\nimport { useRouter } from \"./router\";\nimport type { OperationsApiClient } from \"./useOperations\";\nimport { useOperations } from \"./useOperations\";\n\nexport type EntitySurfaceProps = {\n client: OperationsApiClient;\n /** The surface to list, as the OpenAPI spec's `x-clicky.surfaces` keys it. */\n surfaceKey: string;\n resultRenderer?: ResultRenderer;\n paginationMode?: \"paged\" | \"infinite\";\n};\n\n/**\n * EntitySurface lists one surface wherever a host places it — the same listing,\n * filters and result renderer EntityExplorerApp shows on the surface's own\n * route, embedded in another page (e.g. a connection's logs on its detail page).\n * Filter state lives in the current URL's query string, as it does on the route.\n */\nexport function EntitySurface({ client, surfaceKey, resultRenderer, paginationMode }: EntitySurfaceProps) {\n const { renderLink } = useRouter();\n const { spec } = useOperations(client);\n const surface = useMemo(\n () => (spec ? getClickySurfaces(spec).find((item) => item.key === surfaceKey) : undefined),\n [spec, surfaceKey],\n );\n if (!spec) return <div className=\"text-sm text-muted-foreground\">Loading…</div>;\n if (!surface) {\n return (\n <div className=\"text-sm text-muted-foreground\">\n Unknown surface: <code>{surfaceKey}</code>\n </div>\n );\n }\n return (\n <OperationCatalog\n key={surface.key}\n definition={makeSurfaceDefinition(surface)}\n entities={[surface.entity]}\n client={client}\n renderLink={renderLink}\n surfaceKey={surface.key}\n {...(resultRenderer ? { resultRenderer } : {})}\n {...(paginationMode ? { paginationMode } : {})}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAsBA,SAAgB,cAAc,EAAE,QAAQ,YAAY,gBAAgB,kBAAsC;CACxG,MAAM,EAAE,eAAe,UAAU;CACjC,MAAM,EAAE,SAAS,cAAc,MAAM;CACrC,MAAM,UAAU,cACP,OAAO,kBAAkB,IAAI,CAAC,CAAC,MAAM,SAAS,KAAK,QAAQ,UAAU,IAAI,KAAA,GAChF,CAAC,MAAM,UAAU,CACnB;CACA,IAAI,CAAC,MAAM,OAAO,oBAAC,OAAD;EAAK,WAAU;EAAgC,UAAA;CAAa,CAAA;CAC9E,IAAI,CAAC,SACH,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CAA+C,qBAC5B,oBAAC,QAAD,EAAA,UAAO,WAAiB,CAAA,CACtC;;CAGT,OACE,oBAAC,kBAAD;EAEE,YAAY,sBAAsB,OAAO;EACzC,UAAU,CAAC,QAAQ,MAAM;EACjB;EACI;EACZ,YAAY,QAAQ;EACpB,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;EAC5C,GAAK,iBAAiB,EAAE,eAAe,IAAI,CAAC;CAC7C,GARM,QAAQ,GAQd;AAEL"}
@@ -0,0 +1,48 @@
1
+ const require_UiChevronRight = require("../icons/components/UiChevronRight.cjs");
2
+ const require_Icon = require("../data/Icon.cjs");
3
+ const require_router = require("./router.cjs");
4
+ const require_explorer_nav_context = require("./explorer-nav-context.cjs");
5
+ let react = require("react");
6
+ let react_jsx_runtime = require("react/jsx-runtime");
7
+ let react_dom = require("react-dom");
8
+ // src/rpc/ExplorerNav.tsx
9
+ /**
10
+ * Renders a drill-down page's title into EntityExplorerApp's top bar, after a
11
+ * breadcrumb back to the surface it was opened from.
12
+ */
13
+ function ExplorerNavPortal({ parentHref, children }) {
14
+ const slot = (0, react.useContext)(require_explorer_nav_context.ExplorerNavContext);
15
+ const { renderLink } = require_router.useRouter();
16
+ const claim = slot?.claim;
17
+ (0, react.useEffect)(() => claim?.(), [claim]);
18
+ if (!slot) throw new Error("ExplorerNavPortal must render inside EntityExplorerApp");
19
+ const { container, title, titleActions } = slot;
20
+ if (!container) return null;
21
+ return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
22
+ "aria-label": "Breadcrumb",
23
+ className: "flex min-w-0 flex-1 items-center gap-density-2",
24
+ children: [
25
+ renderLink({
26
+ to: parentHref,
27
+ className: "shrink-0 text-base font-semibold tracking-tight text-muted-foreground hover:text-foreground hover:underline",
28
+ children: title
29
+ }),
30
+ titleActions ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
31
+ className: "flex shrink-0 items-center",
32
+ children: titleActions
33
+ }) : null,
34
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Icon.Icon, {
35
+ icon: require_UiChevronRight.UiChevronRight,
36
+ className: "shrink-0 text-muted-foreground"
37
+ }),
38
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39
+ "aria-current": "page",
40
+ className: "flex min-w-0 flex-1 items-center gap-density-2",
41
+ children
42
+ })
43
+ ]
44
+ }), container);
45
+ }
46
+ exports.ExplorerNavPortal = ExplorerNavPortal;
47
+
48
+ //# sourceMappingURL=ExplorerNav.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExplorerNav.cjs","names":["useContext","ExplorerNavContext","useRouter","createPortal","Icon","UiChevronRight"],"sources":["../../src/rpc/ExplorerNav.tsx"],"sourcesContent":["import { useContext, useEffect, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Icon } from \"../data/Icon\";\nimport { UiChevronRight } from \"../icons\";\nimport { useRouter } from \"./router\";\nimport { ExplorerNavContext } from \"./explorer-nav-context\";\n\nexport type ExplorerNavPortalProps = {\n /** Where the surface breadcrumb leads — the surface listing with the host's filters kept. */\n parentHref: string;\n children: ReactNode;\n};\n\n/**\n * Renders a drill-down page's title into EntityExplorerApp's top bar, after a\n * breadcrumb back to the surface it was opened from.\n */\nexport function ExplorerNavPortal({ parentHref, children }: ExplorerNavPortalProps) {\n const slot = useContext(ExplorerNavContext);\n const { renderLink } = useRouter();\n const claim = slot?.claim;\n useEffect(() => claim?.(), [claim]);\n if (!slot) throw new Error(\"ExplorerNavPortal must render inside EntityExplorerApp\");\n const { container, title, titleActions } = slot;\n if (!container) return null;\n return createPortal(\n <nav aria-label=\"Breadcrumb\" className=\"flex min-w-0 flex-1 items-center gap-density-2\">\n {renderLink({\n to: parentHref,\n className: \"shrink-0 text-base font-semibold tracking-tight text-muted-foreground hover:text-foreground hover:underline\",\n children: title,\n })}\n {titleActions ? <div className=\"flex shrink-0 items-center\">{titleActions}</div> : null}\n <Icon icon={UiChevronRight} className=\"shrink-0 text-muted-foreground\" />\n <div aria-current=\"page\" className=\"flex min-w-0 flex-1 items-center gap-density-2\">\n {children}\n </div>\n </nav>,\n container,\n );\n}\n"],"mappings":";;;;;;;;;;;;AAiBA,SAAgB,kBAAkB,EAAE,YAAY,YAAoC;CAClF,MAAM,QAAA,GAAOA,MAAAA,WAAAA,CAAWC,6BAAAA,kBAAkB;CAC1C,MAAM,EAAE,eAAeC,eAAAA,UAAU;CACjC,MAAM,QAAQ,MAAM;CACpB,CAAA,GAAA,MAAA,UAAA,OAAgB,QAAQ,GAAG,CAAC,KAAK,CAAC;CAClC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,wDAAwD;CACnF,MAAM,EAAE,WAAW,OAAO,iBAAiB;CAC3C,IAAI,CAAC,WAAW,OAAO;CACvB,QAAA,GAAOC,UAAAA,aAAAA,CACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,cAAW;EAAa,WAAU;EAAvC,UAAA;GACG,WAAW;IACV,IAAI;IACJ,WAAW;IACX,UAAU;GACZ,CAAC;GACA,eAAe,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAU;IAA8B,UAAA;GAAkB,CAAA,IAAI;GACnF,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,MAAD;IAAM,MAAMC,uBAAAA;IAAgB,WAAU;GAAkC,CAAA;GACxE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,gBAAa;IAAO,WAAU;IAChC;GACE,CAAA;EACF;CACL,CAAA,GAAA,SACF;AACF"}
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ export type ExplorerNavPortalProps = {
3
+ /** Where the surface breadcrumb leads — the surface listing with the host's filters kept. */
4
+ parentHref: string;
5
+ children: ReactNode;
6
+ };
7
+ /**
8
+ * Renders a drill-down page's title into EntityExplorerApp's top bar, after a
9
+ * breadcrumb back to the surface it was opened from.
10
+ */
11
+ export declare function ExplorerNavPortal({ parentHref, children }: ExplorerNavPortalProps): import('react').ReactPortal | null;
12
+ //# sourceMappingURL=ExplorerNav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExplorerNav.d.ts","sourceRoot":"","sources":["../../src/rpc/ExplorerNav.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAO9D,MAAM,MAAM,sBAAsB,GAAG;IACnC,6FAA6F;IAC7F,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,sBAAsB,sCAuBjF"}