@flanksource/clicky-ui 0.3.58 → 0.3.60

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 (504) hide show
  1. package/NOTICE.md +58 -0
  2. package/dist/clicky.cjs +3 -1
  3. package/dist/clicky.d.ts +1 -0
  4. package/dist/clicky.d.ts.map +1 -1
  5. package/dist/clicky.js +3 -1
  6. package/dist/data/Clicky.cjs +23 -270
  7. package/dist/data/Clicky.cjs.map +1 -1
  8. package/dist/data/Clicky.d.ts +5 -29
  9. package/dist/data/Clicky.d.ts.map +1 -1
  10. package/dist/data/Clicky.js +11 -259
  11. package/dist/data/Clicky.js.map +1 -1
  12. package/dist/data/PromptBanner.model.cjs +10 -0
  13. package/dist/data/PromptBanner.model.cjs.map +1 -1
  14. package/dist/data/PromptBanner.model.d.ts +2 -0
  15. package/dist/data/PromptBanner.model.d.ts.map +1 -1
  16. package/dist/data/PromptBanner.model.js +10 -1
  17. package/dist/data/PromptBanner.model.js.map +1 -1
  18. package/dist/data/PromptDialog.cjs +16 -49
  19. package/dist/data/PromptDialog.cjs.map +1 -1
  20. package/dist/data/PromptDialog.d.ts +7 -1
  21. package/dist/data/PromptDialog.d.ts.map +1 -1
  22. package/dist/data/PromptDialog.js +17 -50
  23. package/dist/data/PromptDialog.js.map +1 -1
  24. package/dist/data/PromptForm.cjs +79 -0
  25. package/dist/data/PromptForm.cjs.map +1 -0
  26. package/dist/data/PromptForm.d.ts +26 -0
  27. package/dist/data/PromptForm.d.ts.map +1 -0
  28. package/dist/data/PromptForm.js +79 -0
  29. package/dist/data/PromptForm.js.map +1 -0
  30. package/dist/data/PromptIndicator.cjs +82 -0
  31. package/dist/data/PromptIndicator.cjs.map +1 -0
  32. package/dist/data/PromptIndicator.d.ts +19 -0
  33. package/dist/data/PromptIndicator.d.ts.map +1 -0
  34. package/dist/data/PromptIndicator.js +82 -0
  35. package/dist/data/PromptIndicator.js.map +1 -0
  36. package/dist/data/PromptList.cjs +67 -0
  37. package/dist/data/PromptList.cjs.map +1 -0
  38. package/dist/data/PromptList.d.ts +13 -0
  39. package/dist/data/PromptList.d.ts.map +1 -0
  40. package/dist/data/PromptList.js +67 -0
  41. package/dist/data/PromptList.js.map +1 -0
  42. package/dist/data/clicky-download.cjs +251 -0
  43. package/dist/data/clicky-download.cjs.map +1 -0
  44. package/dist/data/clicky-download.d.ts +55 -0
  45. package/dist/data/clicky-download.d.ts.map +1 -0
  46. package/dist/data/clicky-download.js +244 -0
  47. package/dist/data/clicky-download.js.map +1 -0
  48. package/dist/data/git/GitChangeList.cjs +11 -4
  49. package/dist/data/git/GitChangeList.cjs.map +1 -1
  50. package/dist/data/git/GitChangeList.d.ts +2 -35
  51. package/dist/data/git/GitChangeList.d.ts.map +1 -1
  52. package/dist/data/git/GitChangeList.js +11 -4
  53. package/dist/data/git/GitChangeList.js.map +1 -1
  54. package/dist/data/git/GitLink.cjs +13 -0
  55. package/dist/data/git/GitLink.cjs.map +1 -0
  56. package/dist/data/git/GitLink.d.ts +8 -0
  57. package/dist/data/git/GitLink.d.ts.map +1 -0
  58. package/dist/data/git/GitLink.js +13 -0
  59. package/dist/data/git/GitLink.js.map +1 -0
  60. package/dist/data/git/git-links.cjs +54 -0
  61. package/dist/data/git/git-links.cjs.map +1 -0
  62. package/dist/data/git/git-links.d.ts +4 -0
  63. package/dist/data/git/git-links.d.ts.map +1 -0
  64. package/dist/data/git/git-links.js +53 -0
  65. package/dist/data/git/git-links.js.map +1 -0
  66. package/dist/data/git/index.d.ts +3 -0
  67. package/dist/data/git/index.d.ts.map +1 -1
  68. package/dist/data/git/types.d.ts +54 -0
  69. package/dist/data/git/types.d.ts.map +1 -0
  70. package/dist/data/test-runner/MatrixMarks.cjs +4 -3
  71. package/dist/data/test-runner/MatrixMarks.cjs.map +1 -1
  72. package/dist/data/test-runner/MatrixMarks.d.ts +7 -4
  73. package/dist/data/test-runner/MatrixMarks.d.ts.map +1 -1
  74. package/dist/data/test-runner/MatrixMarks.js +4 -3
  75. package/dist/data/test-runner/MatrixMarks.js.map +1 -1
  76. package/dist/data/test-runner/TestRunSummary.cjs +1 -1
  77. package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
  78. package/dist/data/test-runner/TestRunSummary.js +1 -1
  79. package/dist/data/test-runner/TestRunSummary.js.map +1 -1
  80. package/dist/data/test-runner/TestTree.cjs +1 -1
  81. package/dist/data/test-runner/TestTree.cjs.map +1 -1
  82. package/dist/data/test-runner/TestTree.js +1 -1
  83. package/dist/data/test-runner/TestTree.js.map +1 -1
  84. package/dist/data/test-runner/TestTreeNode.cjs +2 -2
  85. package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
  86. package/dist/data/test-runner/TestTreeNode.js +2 -2
  87. package/dist/data/test-runner/TestTreeNode.js.map +1 -1
  88. package/dist/data/test-runner/adapter.cjs +7 -0
  89. package/dist/data/test-runner/adapter.cjs.map +1 -1
  90. package/dist/data/test-runner/adapter.d.ts +7 -0
  91. package/dist/data/test-runner/adapter.d.ts.map +1 -1
  92. package/dist/data/test-runner/adapter.js +7 -0
  93. package/dist/data/test-runner/adapter.js.map +1 -1
  94. package/dist/data/test-runner/index.d.ts +1 -1
  95. package/dist/data/test-runner/index.d.ts.map +1 -1
  96. package/dist/data/test-runner/marks.cjs +3 -3
  97. package/dist/data/test-runner/marks.cjs.map +1 -1
  98. package/dist/data/test-runner/marks.js +3 -3
  99. package/dist/data/test-runner/marks.js.map +1 -1
  100. package/dist/data/test-runner/matrix-marks.cjs +12 -3
  101. package/dist/data/test-runner/matrix-marks.cjs.map +1 -1
  102. package/dist/data/test-runner/matrix-marks.d.ts +13 -0
  103. package/dist/data/test-runner/matrix-marks.d.ts.map +1 -1
  104. package/dist/data/test-runner/matrix-marks.js +12 -3
  105. package/dist/data/test-runner/matrix-marks.js.map +1 -1
  106. package/dist/data/test-runner/status.cjs +1 -1
  107. package/dist/data/test-runner/status.cjs.map +1 -1
  108. package/dist/data/test-runner/status.js +1 -1
  109. package/dist/data/test-runner/status.js.map +1 -1
  110. package/dist/data/test-runner/types.d.ts +2 -0
  111. package/dist/data/test-runner/types.d.ts.map +1 -1
  112. package/dist/data/traces/index.d.ts +2 -0
  113. package/dist/data/traces/index.d.ts.map +1 -1
  114. package/dist/data/traces/otel/OtelTraceDetail.cjs +102 -78
  115. package/dist/data/traces/otel/OtelTraceDetail.cjs.map +1 -1
  116. package/dist/data/traces/otel/OtelTraceDetail.d.ts +6 -2
  117. package/dist/data/traces/otel/OtelTraceDetail.d.ts.map +1 -1
  118. package/dist/data/traces/otel/OtelTraceDetail.js +102 -78
  119. package/dist/data/traces/otel/OtelTraceDetail.js.map +1 -1
  120. package/dist/data/traces/otel/OtelTraceTable.cjs +43 -7
  121. package/dist/data/traces/otel/OtelTraceTable.cjs.map +1 -1
  122. package/dist/data/traces/otel/OtelTraceTable.d.ts +14 -3
  123. package/dist/data/traces/otel/OtelTraceTable.d.ts.map +1 -1
  124. package/dist/data/traces/otel/OtelTraceTable.js +44 -8
  125. package/dist/data/traces/otel/OtelTraceTable.js.map +1 -1
  126. package/dist/data/traces/otel/profile-listing.cjs +61 -0
  127. package/dist/data/traces/otel/profile-listing.cjs.map +1 -0
  128. package/dist/data/traces/otel/profile-listing.d.ts +23 -0
  129. package/dist/data/traces/otel/profile-listing.d.ts.map +1 -0
  130. package/dist/data/traces/otel/profile-listing.js +60 -0
  131. package/dist/data/traces/otel/profile-listing.js.map +1 -0
  132. package/dist/data/traces/otel/profile-spans.cjs +22 -0
  133. package/dist/data/traces/otel/profile-spans.cjs.map +1 -0
  134. package/dist/data/traces/otel/profile-spans.d.ts +4 -0
  135. package/dist/data/traces/otel/profile-spans.d.ts.map +1 -0
  136. package/dist/data/traces/otel/profile-spans.js +22 -0
  137. package/dist/data/traces/otel/profile-spans.js.map +1 -0
  138. package/dist/data/traces/otel/span-traces.cjs +7 -1
  139. package/dist/data/traces/otel/span-traces.cjs.map +1 -1
  140. package/dist/data/traces/otel/span-traces.d.ts +2 -0
  141. package/dist/data/traces/otel/span-traces.d.ts.map +1 -1
  142. package/dist/data/traces/otel/span-traces.js +7 -2
  143. package/dist/data/traces/otel/span-traces.js.map +1 -1
  144. package/dist/data/useClickyTableMenu.cjs +33 -0
  145. package/dist/data/useClickyTableMenu.cjs.map +1 -0
  146. package/dist/data/useClickyTableMenu.d.ts +17 -0
  147. package/dist/data/useClickyTableMenu.d.ts.map +1 -0
  148. package/dist/data/useClickyTableMenu.js +33 -0
  149. package/dist/data/useClickyTableMenu.js.map +1 -0
  150. package/dist/data/verification/adapterViews.cjs +3 -1
  151. package/dist/data/verification/adapterViews.cjs.map +1 -1
  152. package/dist/data/verification/adapterViews.d.ts +5 -2
  153. package/dist/data/verification/adapterViews.d.ts.map +1 -1
  154. package/dist/data/verification/adapterViews.js +4 -2
  155. package/dist/data/verification/adapterViews.js.map +1 -1
  156. package/dist/data/verification/adapters.cjs +28 -7
  157. package/dist/data/verification/adapters.cjs.map +1 -1
  158. package/dist/data/verification/adapters.d.ts +7 -1
  159. package/dist/data/verification/adapters.d.ts.map +1 -1
  160. package/dist/data/verification/adapters.js +28 -7
  161. package/dist/data/verification/adapters.js.map +1 -1
  162. package/dist/data/verification/stepKind.cjs +1 -0
  163. package/dist/data/verification/stepKind.cjs.map +1 -1
  164. package/dist/data/verification/stepKind.d.ts.map +1 -1
  165. package/dist/data/verification/stepKind.js +1 -0
  166. package/dist/data/verification/stepKind.js.map +1 -1
  167. package/dist/data/verification/stepKindViews.cjs +17 -0
  168. package/dist/data/verification/stepKindViews.cjs.map +1 -1
  169. package/dist/data/verification/stepKindViews.d.ts +4 -0
  170. package/dist/data/verification/stepKindViews.d.ts.map +1 -1
  171. package/dist/data/verification/stepKindViews.js +17 -1
  172. package/dist/data/verification/stepKindViews.js.map +1 -1
  173. package/dist/data/version-info.cjs +3 -3
  174. package/dist/data/version-info.js +3 -3
  175. package/dist/data.cjs +121 -2
  176. package/dist/data.d.ts +3 -0
  177. package/dist/data.d.ts.map +1 -1
  178. package/dist/data.js +55 -3
  179. package/dist/git.cjs +6 -0
  180. package/dist/git.d.ts +4 -0
  181. package/dist/git.d.ts.map +1 -0
  182. package/dist/git.js +3 -0
  183. package/dist/hooks/use-prompts.cjs +18 -11
  184. package/dist/hooks/use-prompts.cjs.map +1 -1
  185. package/dist/hooks/use-prompts.d.ts.map +1 -1
  186. package/dist/hooks/use-prompts.js +18 -11
  187. package/dist/hooks/use-prompts.js.map +1 -1
  188. package/dist/icons/components/UiApi.cjs +37 -0
  189. package/dist/icons/components/UiApi.cjs.map +1 -0
  190. package/dist/icons/components/UiApi.d.ts +9 -0
  191. package/dist/icons/components/UiApi.d.ts.map +1 -0
  192. package/dist/icons/components/UiApi.js +35 -0
  193. package/dist/icons/components/UiApi.js.map +1 -0
  194. package/dist/icons/components/UiApiBridge.cjs +38 -0
  195. package/dist/icons/components/UiApiBridge.cjs.map +1 -0
  196. package/dist/icons/components/UiApiBridge.d.ts +9 -0
  197. package/dist/icons/components/UiApiBridge.d.ts.map +1 -0
  198. package/dist/icons/components/UiApiBridge.js +36 -0
  199. package/dist/icons/components/UiApiBridge.js.map +1 -0
  200. package/dist/icons/components/UiApiGateway.cjs +33 -0
  201. package/dist/icons/components/UiApiGateway.cjs.map +1 -0
  202. package/dist/icons/components/UiApiGateway.d.ts +9 -0
  203. package/dist/icons/components/UiApiGateway.d.ts.map +1 -0
  204. package/dist/icons/components/UiApiGateway.js +31 -0
  205. package/dist/icons/components/UiApiGateway.js.map +1 -0
  206. package/dist/icons/components/UiApiRequest.cjs +37 -0
  207. package/dist/icons/components/UiApiRequest.cjs.map +1 -0
  208. package/dist/icons/components/UiApiRequest.d.ts +9 -0
  209. package/dist/icons/components/UiApiRequest.d.ts.map +1 -0
  210. package/dist/icons/components/UiApiRequest.js +35 -0
  211. package/dist/icons/components/UiApiRequest.js.map +1 -0
  212. package/dist/icons/components/UiArrowDecision.cjs +51 -0
  213. package/dist/icons/components/UiArrowDecision.cjs.map +1 -0
  214. package/dist/icons/components/UiArrowDecision.d.ts +15 -0
  215. package/dist/icons/components/UiArrowDecision.d.ts.map +1 -0
  216. package/dist/icons/components/UiArrowDecision.js +48 -0
  217. package/dist/icons/components/UiArrowDecision.js.map +1 -0
  218. package/dist/icons/components/UiArrowSquareIn.cjs +51 -0
  219. package/dist/icons/components/UiArrowSquareIn.cjs.map +1 -0
  220. package/dist/icons/components/UiArrowSquareIn.d.ts +15 -0
  221. package/dist/icons/components/UiArrowSquareIn.d.ts.map +1 -0
  222. package/dist/icons/components/UiArrowSquareIn.js +48 -0
  223. package/dist/icons/components/UiArrowSquareIn.js.map +1 -0
  224. package/dist/icons/components/UiBatchCheck.cjs +55 -0
  225. package/dist/icons/components/UiBatchCheck.cjs.map +1 -0
  226. package/dist/icons/components/UiBatchCheck.d.ts +15 -0
  227. package/dist/icons/components/UiBatchCheck.d.ts.map +1 -0
  228. package/dist/icons/components/UiBatchCheck.js +52 -0
  229. package/dist/icons/components/UiBatchCheck.js.map +1 -0
  230. package/dist/icons/components/UiBatchJob.cjs +39 -0
  231. package/dist/icons/components/UiBatchJob.cjs.map +1 -0
  232. package/dist/icons/components/UiBatchJob.d.ts +9 -0
  233. package/dist/icons/components/UiBatchJob.d.ts.map +1 -0
  234. package/dist/icons/components/UiBatchJob.js +37 -0
  235. package/dist/icons/components/UiBatchJob.js.map +1 -0
  236. package/dist/icons/components/UiBatchRequest.cjs +39 -0
  237. package/dist/icons/components/UiBatchRequest.cjs.map +1 -0
  238. package/dist/icons/components/UiBatchRequest.d.ts +9 -0
  239. package/dist/icons/components/UiBatchRequest.d.ts.map +1 -0
  240. package/dist/icons/components/UiBatchRequest.js +37 -0
  241. package/dist/icons/components/UiBatchRequest.js.map +1 -0
  242. package/dist/icons/components/UiBpmnConditional.cjs +29 -0
  243. package/dist/icons/components/UiBpmnConditional.cjs.map +1 -0
  244. package/dist/icons/components/UiBpmnConditional.d.ts +9 -0
  245. package/dist/icons/components/UiBpmnConditional.d.ts.map +1 -0
  246. package/dist/icons/components/UiBpmnConditional.js +27 -0
  247. package/dist/icons/components/UiBpmnConditional.js.map +1 -0
  248. package/dist/icons/components/UiBranchFlow.cjs +33 -0
  249. package/dist/icons/components/UiBranchFlow.cjs.map +1 -0
  250. package/dist/icons/components/UiBranchFlow.d.ts +9 -0
  251. package/dist/icons/components/UiBranchFlow.d.ts.map +1 -0
  252. package/dist/icons/components/UiBranchFlow.js +31 -0
  253. package/dist/icons/components/UiBranchFlow.js.map +1 -0
  254. package/dist/icons/components/UiClassicBatch.cjs +29 -0
  255. package/dist/icons/components/UiClassicBatch.cjs.map +1 -0
  256. package/dist/icons/components/UiClassicBatch.d.ts +9 -0
  257. package/dist/icons/components/UiClassicBatch.d.ts.map +1 -0
  258. package/dist/icons/components/UiClassicBatch.js +27 -0
  259. package/dist/icons/components/UiClassicBatch.js.map +1 -0
  260. package/dist/icons/components/UiCodeFile.cjs +29 -0
  261. package/dist/icons/components/UiCodeFile.cjs.map +1 -0
  262. package/dist/icons/components/UiCodeFile.d.ts +9 -0
  263. package/dist/icons/components/UiCodeFile.d.ts.map +1 -0
  264. package/dist/icons/components/UiCodeFile.js +27 -0
  265. package/dist/icons/components/UiCodeFile.js.map +1 -0
  266. package/dist/icons/components/UiColumnsLayout.cjs +29 -0
  267. package/dist/icons/components/UiColumnsLayout.cjs.map +1 -0
  268. package/dist/icons/components/UiColumnsLayout.d.ts +9 -0
  269. package/dist/icons/components/UiColumnsLayout.d.ts.map +1 -0
  270. package/dist/icons/components/UiColumnsLayout.js +27 -0
  271. package/dist/icons/components/UiColumnsLayout.js.map +1 -0
  272. package/dist/icons/components/UiCondition.cjs +37 -0
  273. package/dist/icons/components/UiCondition.cjs.map +1 -0
  274. package/dist/icons/components/UiCondition.d.ts +9 -0
  275. package/dist/icons/components/UiCondition.d.ts.map +1 -0
  276. package/dist/icons/components/UiCondition.js +35 -0
  277. package/dist/icons/components/UiCondition.js.map +1 -0
  278. package/dist/icons/components/UiConditions.cjs +29 -0
  279. package/dist/icons/components/UiConditions.cjs.map +1 -0
  280. package/dist/icons/components/UiConditions.d.ts +9 -0
  281. package/dist/icons/components/UiConditions.d.ts.map +1 -0
  282. package/dist/icons/components/UiConditions.js +27 -0
  283. package/dist/icons/components/UiConditions.js.map +1 -0
  284. package/dist/icons/components/UiDelayQueue.cjs +40 -0
  285. package/dist/icons/components/UiDelayQueue.cjs.map +1 -0
  286. package/dist/icons/components/UiDelayQueue.d.ts +9 -0
  287. package/dist/icons/components/UiDelayQueue.d.ts.map +1 -0
  288. package/dist/icons/components/UiDelayQueue.js +38 -0
  289. package/dist/icons/components/UiDelayQueue.js.map +1 -0
  290. package/dist/icons/components/UiDynamicForm.cjs +51 -0
  291. package/dist/icons/components/UiDynamicForm.cjs.map +1 -0
  292. package/dist/icons/components/UiDynamicForm.d.ts +15 -0
  293. package/dist/icons/components/UiDynamicForm.d.ts.map +1 -0
  294. package/dist/icons/components/UiDynamicForm.js +48 -0
  295. package/dist/icons/components/UiDynamicForm.js.map +1 -0
  296. package/dist/icons/components/UiFlowArrow.cjs +51 -0
  297. package/dist/icons/components/UiFlowArrow.cjs.map +1 -0
  298. package/dist/icons/components/UiFlowArrow.d.ts +15 -0
  299. package/dist/icons/components/UiFlowArrow.d.ts.map +1 -0
  300. package/dist/icons/components/UiFlowArrow.js +48 -0
  301. package/dist/icons/components/UiFlowArrow.js.map +1 -0
  302. package/dist/icons/components/UiFormFields.cjs +33 -0
  303. package/dist/icons/components/UiFormFields.cjs.map +1 -0
  304. package/dist/icons/components/UiFormFields.d.ts +9 -0
  305. package/dist/icons/components/UiFormFields.d.ts.map +1 -0
  306. package/dist/icons/components/UiFormFields.js +31 -0
  307. package/dist/icons/components/UiFormFields.js.map +1 -0
  308. package/dist/icons/components/UiFormStep.cjs +38 -0
  309. package/dist/icons/components/UiFormStep.cjs.map +1 -0
  310. package/dist/icons/components/UiFormStep.d.ts +9 -0
  311. package/dist/icons/components/UiFormStep.d.ts.map +1 -0
  312. package/dist/icons/components/UiFormStep.js +36 -0
  313. package/dist/icons/components/UiFormStep.js.map +1 -0
  314. package/dist/icons/components/UiGatewayApi.cjs +32 -0
  315. package/dist/icons/components/UiGatewayApi.cjs.map +1 -0
  316. package/dist/icons/components/UiGatewayApi.d.ts +9 -0
  317. package/dist/icons/components/UiGatewayApi.d.ts.map +1 -0
  318. package/dist/icons/components/UiGatewayApi.js +30 -0
  319. package/dist/icons/components/UiGatewayApi.js.map +1 -0
  320. package/dist/icons/components/UiImportArrow.cjs +29 -0
  321. package/dist/icons/components/UiImportArrow.cjs.map +1 -0
  322. package/dist/icons/components/UiImportArrow.d.ts +9 -0
  323. package/dist/icons/components/UiImportArrow.d.ts.map +1 -0
  324. package/dist/icons/components/UiImportArrow.js +27 -0
  325. package/dist/icons/components/UiImportArrow.js.map +1 -0
  326. package/dist/icons/components/UiInputField.cjs +33 -0
  327. package/dist/icons/components/UiInputField.cjs.map +1 -0
  328. package/dist/icons/components/UiInputField.d.ts +9 -0
  329. package/dist/icons/components/UiInputField.d.ts.map +1 -0
  330. package/dist/icons/components/UiInputField.js +31 -0
  331. package/dist/icons/components/UiInputField.js.map +1 -0
  332. package/dist/icons/components/UiInsertTable.cjs +29 -0
  333. package/dist/icons/components/UiInsertTable.cjs.map +1 -0
  334. package/dist/icons/components/UiInsertTable.d.ts +9 -0
  335. package/dist/icons/components/UiInsertTable.d.ts.map +1 -0
  336. package/dist/icons/components/UiInsertTable.js +27 -0
  337. package/dist/icons/components/UiInsertTable.js.map +1 -0
  338. package/dist/icons/components/UiLayoutTemplate.cjs +32 -0
  339. package/dist/icons/components/UiLayoutTemplate.cjs.map +1 -0
  340. package/dist/icons/components/UiLayoutTemplate.d.ts +9 -0
  341. package/dist/icons/components/UiLayoutTemplate.d.ts.map +1 -0
  342. package/dist/icons/components/UiLayoutTemplate.js +30 -0
  343. package/dist/icons/components/UiLayoutTemplate.js.map +1 -0
  344. package/dist/icons/components/UiLayoutWindow.cjs +56 -0
  345. package/dist/icons/components/UiLayoutWindow.cjs.map +1 -0
  346. package/dist/icons/components/UiLayoutWindow.d.ts +15 -0
  347. package/dist/icons/components/UiLayoutWindow.d.ts.map +1 -0
  348. package/dist/icons/components/UiLayoutWindow.js +53 -0
  349. package/dist/icons/components/UiLayoutWindow.js.map +1 -0
  350. package/dist/icons/components/UiListEnd.cjs +33 -0
  351. package/dist/icons/components/UiListEnd.cjs.map +1 -0
  352. package/dist/icons/components/UiListEnd.d.ts +9 -0
  353. package/dist/icons/components/UiListEnd.d.ts.map +1 -0
  354. package/dist/icons/components/UiListEnd.js +31 -0
  355. package/dist/icons/components/UiListEnd.js.map +1 -0
  356. package/dist/icons/components/UiListEndLine.cjs +51 -0
  357. package/dist/icons/components/UiListEndLine.cjs.map +1 -0
  358. package/dist/icons/components/UiListEndLine.d.ts +15 -0
  359. package/dist/icons/components/UiListEndLine.d.ts.map +1 -0
  360. package/dist/icons/components/UiListEndLine.js +48 -0
  361. package/dist/icons/components/UiListEndLine.js.map +1 -0
  362. package/dist/icons/components/UiListNumbers.cjs +51 -0
  363. package/dist/icons/components/UiListNumbers.cjs.map +1 -0
  364. package/dist/icons/components/UiListNumbers.d.ts +15 -0
  365. package/dist/icons/components/UiListNumbers.d.ts.map +1 -0
  366. package/dist/icons/components/UiListNumbers.js +48 -0
  367. package/dist/icons/components/UiListNumbers.js.map +1 -0
  368. package/dist/icons/components/UiLowPriority.cjs +29 -0
  369. package/dist/icons/components/UiLowPriority.cjs.map +1 -0
  370. package/dist/icons/components/UiLowPriority.d.ts +9 -0
  371. package/dist/icons/components/UiLowPriority.d.ts.map +1 -0
  372. package/dist/icons/components/UiLowPriority.js +27 -0
  373. package/dist/icons/components/UiLowPriority.js.map +1 -0
  374. package/dist/icons/components/UiMergeQueue.cjs +38 -0
  375. package/dist/icons/components/UiMergeQueue.cjs.map +1 -0
  376. package/dist/icons/components/UiMergeQueue.d.ts +9 -0
  377. package/dist/icons/components/UiMergeQueue.d.ts.map +1 -0
  378. package/dist/icons/components/UiMergeQueue.js +36 -0
  379. package/dist/icons/components/UiMergeQueue.js.map +1 -0
  380. package/dist/icons/components/UiPipelineStage.cjs +33 -0
  381. package/dist/icons/components/UiPipelineStage.cjs.map +1 -0
  382. package/dist/icons/components/UiPipelineStage.d.ts +9 -0
  383. package/dist/icons/components/UiPipelineStage.d.ts.map +1 -0
  384. package/dist/icons/components/UiPipelineStage.js +31 -0
  385. package/dist/icons/components/UiPipelineStage.js.map +1 -0
  386. package/dist/icons/components/UiPlaylistRemove.cjs +29 -0
  387. package/dist/icons/components/UiPlaylistRemove.cjs.map +1 -0
  388. package/dist/icons/components/UiPlaylistRemove.d.ts +9 -0
  389. package/dist/icons/components/UiPlaylistRemove.d.ts.map +1 -0
  390. package/dist/icons/components/UiPlaylistRemove.js +27 -0
  391. package/dist/icons/components/UiPlaylistRemove.js.map +1 -0
  392. package/dist/icons/components/UiReportForms.cjs +51 -0
  393. package/dist/icons/components/UiReportForms.cjs.map +1 -0
  394. package/dist/icons/components/UiReportForms.d.ts +15 -0
  395. package/dist/icons/components/UiReportForms.d.ts.map +1 -0
  396. package/dist/icons/components/UiReportForms.js +48 -0
  397. package/dist/icons/components/UiReportForms.js.map +1 -0
  398. package/dist/icons/components/UiScreenTemplate.cjs +29 -0
  399. package/dist/icons/components/UiScreenTemplate.cjs.map +1 -0
  400. package/dist/icons/components/UiScreenTemplate.d.ts +9 -0
  401. package/dist/icons/components/UiScreenTemplate.d.ts.map +1 -0
  402. package/dist/icons/components/UiScreenTemplate.js +27 -0
  403. package/dist/icons/components/UiScreenTemplate.js.map +1 -0
  404. package/dist/icons/components/UiServices.cjs +29 -0
  405. package/dist/icons/components/UiServices.cjs.map +1 -0
  406. package/dist/icons/components/UiServices.d.ts +9 -0
  407. package/dist/icons/components/UiServices.d.ts.map +1 -0
  408. package/dist/icons/components/UiServices.js +27 -0
  409. package/dist/icons/components/UiServices.js.map +1 -0
  410. package/dist/icons/components/UiSkipCircle.cjs +51 -0
  411. package/dist/icons/components/UiSkipCircle.cjs.map +1 -0
  412. package/dist/icons/components/UiSkipCircle.d.ts +15 -0
  413. package/dist/icons/components/UiSkipCircle.d.ts.map +1 -0
  414. package/dist/icons/components/UiSkipCircle.js +48 -0
  415. package/dist/icons/components/UiSkipCircle.js.map +1 -0
  416. package/dist/icons/components/UiTaskBatch.cjs +33 -0
  417. package/dist/icons/components/UiTaskBatch.cjs.map +1 -0
  418. package/dist/icons/components/UiTaskBatch.d.ts +9 -0
  419. package/dist/icons/components/UiTaskBatch.d.ts.map +1 -0
  420. package/dist/icons/components/UiTaskBatch.js +31 -0
  421. package/dist/icons/components/UiTaskBatch.js.map +1 -0
  422. package/dist/icons/components/UiTodoList.cjs +29 -0
  423. package/dist/icons/components/UiTodoList.cjs.map +1 -0
  424. package/dist/icons/components/UiTodoList.d.ts +9 -0
  425. package/dist/icons/components/UiTodoList.d.ts.map +1 -0
  426. package/dist/icons/components/UiTodoList.js +27 -0
  427. package/dist/icons/components/UiTodoList.js.map +1 -0
  428. package/dist/icons/components/UiTrayArrowDown.cjs +51 -0
  429. package/dist/icons/components/UiTrayArrowDown.cjs.map +1 -0
  430. package/dist/icons/components/UiTrayArrowDown.d.ts +15 -0
  431. package/dist/icons/components/UiTrayArrowDown.d.ts.map +1 -0
  432. package/dist/icons/components/UiTrayArrowDown.js +48 -0
  433. package/dist/icons/components/UiTrayArrowDown.js.map +1 -0
  434. package/dist/icons/components/UiVault.cjs +51 -0
  435. package/dist/icons/components/UiVault.cjs.map +1 -0
  436. package/dist/icons/components/UiVault.d.ts +15 -0
  437. package/dist/icons/components/UiVault.d.ts.map +1 -0
  438. package/dist/icons/components/UiVault.js +48 -0
  439. package/dist/icons/components/UiVault.js.map +1 -0
  440. package/dist/icons/components/UiWebServiceDefinition.cjs +39 -0
  441. package/dist/icons/components/UiWebServiceDefinition.cjs.map +1 -0
  442. package/dist/icons/components/UiWebServiceDefinition.d.ts +9 -0
  443. package/dist/icons/components/UiWebServiceDefinition.d.ts.map +1 -0
  444. package/dist/icons/components/UiWebServiceDefinition.js +37 -0
  445. package/dist/icons/components/UiWebServiceDefinition.js.map +1 -0
  446. package/dist/icons/components/UiWebhook.cjs +29 -0
  447. package/dist/icons/components/UiWebhook.cjs.map +1 -0
  448. package/dist/icons/components/UiWebhook.d.ts +9 -0
  449. package/dist/icons/components/UiWebhook.d.ts.map +1 -0
  450. package/dist/icons/components/UiWebhook.js +27 -0
  451. package/dist/icons/components/UiWebhook.js.map +1 -0
  452. package/dist/icons/components/UiWebhookLine.cjs +51 -0
  453. package/dist/icons/components/UiWebhookLine.cjs.map +1 -0
  454. package/dist/icons/components/UiWebhookLine.d.ts +15 -0
  455. package/dist/icons/components/UiWebhookLine.d.ts.map +1 -0
  456. package/dist/icons/components/UiWebhookLine.js +48 -0
  457. package/dist/icons/components/UiWebhookLine.js.map +1 -0
  458. package/dist/icons/index.d.ts +58 -0
  459. package/dist/icons/index.d.ts.map +1 -1
  460. package/dist/icons/registry.cjs +90 -0
  461. package/dist/icons/registry.cjs.map +1 -1
  462. package/dist/icons/registry.d.ts.map +1 -1
  463. package/dist/icons/registry.js +90 -0
  464. package/dist/icons/registry.js.map +1 -1
  465. package/dist/icons.cjs +103 -0
  466. package/dist/icons.js +46 -1
  467. package/dist/index.cjs +128 -3
  468. package/dist/index.js +59 -4
  469. package/dist/overlay/DropdownMenu.cjs +17 -14
  470. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  471. package/dist/overlay/DropdownMenu.d.ts +1 -0
  472. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  473. package/dist/overlay/DropdownMenu.js +18 -15
  474. package/dist/overlay/DropdownMenu.js.map +1 -1
  475. package/dist/rpc/EntityExplorerApp.cjs +49 -12
  476. package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
  477. package/dist/rpc/EntityExplorerApp.d.ts +10 -1
  478. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
  479. package/dist/rpc/EntityExplorerApp.js +51 -14
  480. package/dist/rpc/EntityExplorerApp.js.map +1 -1
  481. package/dist/rpc/EntitySurface.cjs +38 -0
  482. package/dist/rpc/EntitySurface.cjs.map +1 -0
  483. package/dist/rpc/EntitySurface.d.ts +17 -0
  484. package/dist/rpc/EntitySurface.d.ts.map +1 -0
  485. package/dist/rpc/EntitySurface.js +38 -0
  486. package/dist/rpc/EntitySurface.js.map +1 -0
  487. package/dist/rpc/ExplorerNav.cjs +48 -0
  488. package/dist/rpc/ExplorerNav.cjs.map +1 -0
  489. package/dist/rpc/ExplorerNav.d.ts +12 -0
  490. package/dist/rpc/ExplorerNav.d.ts.map +1 -0
  491. package/dist/rpc/ExplorerNav.js +48 -0
  492. package/dist/rpc/ExplorerNav.js.map +1 -0
  493. package/dist/rpc/explorer-nav-context.cjs +5 -0
  494. package/dist/rpc/explorer-nav-context.cjs.map +1 -0
  495. package/dist/rpc/explorer-nav-context.d.ts +11 -0
  496. package/dist/rpc/explorer-nav-context.d.ts.map +1 -0
  497. package/dist/rpc/explorer-nav-context.js +6 -0
  498. package/dist/rpc/explorer-nav-context.js.map +1 -0
  499. package/dist/rpc.cjs +4 -0
  500. package/dist/rpc.d.ts +2 -0
  501. package/dist/rpc.d.ts.map +1 -1
  502. package/dist/rpc.js +3 -1
  503. package/dist/styles.css +1 -1
  504. package/package.json +6 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.js","names":[],"sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingNode,\n FloatingPortal,\n FloatingTree,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport {\n MENU_POPOVER_CLASS,\n MenuContext,\n menuViewportSize,\n} from \"./dropdownMenuContext\";\nimport { MenuItemList } from \"./DropdownMenuSubmenu\";\nimport { useEscapeLayer, useFloatingZIndex } from \"./modalStack\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. Ignored when the item has `children`. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** CSS colour applied to this item's icon (the glyph fills `currentColor`). */\n iconColor?: string;\n /** Theme-aware classes applied to this item's icon. */\n iconClassName?: string | undefined;\n /**\n * Section header. A non-interactive header renders above the first item of\n * each contiguous group — provide items pre-sorted by `group`. Items without\n * a `group` render no header.\n */\n group?: string;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n /**\n * Nested submenu items. When present the item becomes a submenu trigger: it\n * opens a flyout of `children` (recursively) on hover / click / ArrowRight\n * instead of firing `onSelect`.\n */\n children?: DropdownMenuItem[];\n /** Editor or explanatory content above a submenu's choices. */\n header?: ReactNode;\n};\n\nexport type DropdownMenuProps = {\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Custom trigger element. Its root receives menu state and interaction props. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Rendered at the top of the menu, above the items/children. */\n header?: ReactNode;\n /** Rendered at the bottom of the menu, below the items/children (e.g. a \"Show more…\" link). */\n footer?: ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Accessible label (`aria-label`) for the floating menu element itself. */\n menuLabel?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\n/**\n * A trigger + floating menu. Flat `items` render as a single list; an item with\n * `children` opens a flyout submenu. The FloatingTree lets every level cooperate\n * on focus and dismissal, so selecting any leaf closes the whole menu.\n */\nexport function DropdownMenu(props: DropdownMenuProps) {\n return (\n <FloatingTree>\n <DropdownMenuRoot {...props} />\n </FloatingTree>\n );\n}\n\nfunction DropdownMenuRoot({\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n header,\n footer,\n align = \"right\",\n onOpenChange,\n title,\n menuLabel,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const floatingZ = useFloatingZIndex();\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n const elementsRef = useRef<Array<HTMLElement | null>>([]);\n\n const onOpenChangeRef = useRef(onOpenChange);\n onOpenChangeRef.current = onOpenChange;\n useEffect(() => {\n onOpenChangeRef.current?.(open);\n }, [open]);\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n // nodeId is always defined inside the FloatingTree; guard for the type only.\n ...(nodeId ? { nodeId } : {}),\n open,\n onOpenChange: setOpen,\n // bottom-end / bottom-start reproduce the previous right/left alignment.\n placement: align === \"right\" ? \"bottom-end\" : \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and\n // shift slides the menu back on-screen at the horizontal edges.\n middleware: [\n offset(4),\n flip({ padding: 8 }),\n shift({ padding: 8 }),\n menuViewportSize,\n ],\n });\n\n const click = useClick(context);\n // useDismiss is React-tree aware: a press inside anything rendered through the\n // menu's `children` render-prop — including a Modal that portals to\n // document.body — propagates via React's synthetic events to the floating\n // element and counts as \"inside\", so it won't dismiss the menu (which would\n // unmount that child Modal). A Modal owned by a sibling/parent instead of this\n // menu correctly does dismiss the menu, which is harmless since closing the\n // menu does not unmount a Modal it doesn't own.\n const dismiss = useDismiss(context, { escapeKey: false });\n const role = useRole(context, { role: \"menu\" });\n const listNav = useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(\n [click, dismiss, role, listNav],\n );\n\n const closeMenu = () => {\n setOpen(false);\n if (refs.domReference.current instanceof HTMLElement)\n refs.domReference.current.focus();\n };\n useEscapeLayer(open, closeMenu);\n\n // Selecting any leaf (at any depth) emits a tree-wide \"click\"; the root closes\n // and restores focus to the trigger.\n const closeMenuRef = useRef(closeMenu);\n closeMenuRef.current = closeMenu;\n useEffect(() => {\n if (!tree) return;\n const onTreeClick = () => closeMenuRef.current();\n tree.events.on(\"click\", onTreeClick);\n return () => tree.events.off(\"click\", onTreeClick);\n }, [tree]);\n\n return (\n <FloatingNode id={nodeId}>\n <div className={cn(\"relative inline-flex\", className)}>\n {trigger ? (\n <Slot\n ref={refs.setReference}\n className=\"inline-flex\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {trigger}\n </Slot>\n ) : (\n <Button\n ref={refs.setReference as React.Ref<HTMLButtonElement>}\n // Opening a menu never submits the form the trigger sits in.\n type=\"button\"\n variant={variant}\n size={size}\n title={title}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {icon && (\n <Icon\n {...(typeof icon === \"string\" ? { name: icon } : { icon })}\n />\n )}\n {label}\n {!hideChevron && <Icon icon={UiChevronDown} />}\n </Button>\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager\n context={context}\n modal={false}\n closeOnFocusOut={false}\n >\n <div\n ref={refs.setFloating}\n {...getFloatingProps()}\n role=\"menu\"\n aria-label={menuLabel}\n {...(menuLabel ? { \"aria-labelledby\": undefined } : {})}\n style={{ ...floatingStyles, zIndex: floatingZ }}\n className={cn(MENU_POPOVER_CLASS, menuClassName)}\n >\n {header != null && (\n <div className=\"border-b border-border px-3 py-1.5\">\n {header}\n </div>\n )}\n {children ? (\n children(closeMenu)\n ) : (\n <MenuContext.Provider\n value={{\n getItemProps,\n activeIndex,\n setActiveIndex,\n setHasFocusInside: () => {},\n isOpen: open,\n }}\n >\n <FloatingList elementsRef={elementsRef}>\n <MenuItemList items={items ?? []} />\n </FloatingList>\n </MenuContext.Provider>\n )}\n {footer != null && (\n <div className=\"border-t border-border px-3 py-1.5\">\n {footer}\n </div>\n )}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n </FloatingNode>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.js","names":[],"sources":["../../src/overlay/DropdownMenu.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState, type ReactNode } from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingNode,\n FloatingPortal,\n FloatingTree,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Button, type ButtonProps } from \"../components/button\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiChevronDown } from \"../icons\";\nimport {\n MENU_POPOVER_CLASS,\n MenuContext,\n menuViewportSize,\n} from \"./dropdownMenuContext\";\nimport { MenuItemList } from \"./DropdownMenuSubmenu\";\nimport { useEscapeLayer, useFloatingZIndex } from \"./modalStack\";\n\nexport type DropdownMenuItem = {\n /** Visible label. */\n label: ReactNode;\n /** Called when the item is chosen. Ignored when the item has `children`. */\n onSelect: () => void;\n /** Iconify name or imported icon component rendered before the label. */\n icon?: string | StaticIconComponent;\n /** CSS colour applied to this item's icon (the glyph fills `currentColor`). */\n iconColor?: string;\n /** Theme-aware classes applied to this item's icon. */\n iconClassName?: string | undefined;\n /**\n * Section header. A non-interactive header renders above the first item of\n * each contiguous group — provide items pre-sorted by `group`. Items without\n * a `group` render no header.\n */\n group?: string;\n /** Browser tooltip for the item. */\n title?: string;\n /** Disable selection. */\n disabled?: boolean;\n /**\n * Nested submenu items. When present the item becomes a submenu trigger: it\n * opens a flyout of `children` (recursively) on hover / click / ArrowRight\n * instead of firing `onSelect`.\n */\n children?: DropdownMenuItem[];\n /** Editor or explanatory content above a submenu's choices. */\n header?: ReactNode;\n};\n\nexport type DropdownMenuProps = {\n role?: \"menu\" | \"dialog\";\n /** Trigger label. Ignored when `trigger` is provided. */\n label?: ReactNode;\n /** Icon shown before the trigger label. Ignored when `trigger` is provided. */\n icon?: string | StaticIconComponent;\n /** Hide the trailing chevron on the default trigger. */\n hideChevron?: boolean;\n /** Variant forwarded to the default Button trigger. */\n variant?: ButtonProps[\"variant\"];\n /** Size forwarded to the default Button trigger. */\n size?: ButtonProps[\"size\"];\n /** Custom trigger element. Its root receives menu state and interaction props. */\n trigger?: ReactNode;\n /** Declarative menu items. Provide this or `children`, not both. */\n items?: DropdownMenuItem[];\n /** Custom menu content. Use `closeMenu` to dismiss after a selection. */\n children?: (closeMenu: () => void) => ReactNode;\n /** Rendered at the top of the menu, above the items/children. */\n header?: ReactNode;\n /** Rendered at the bottom of the menu, below the items/children (e.g. a \"Show more…\" link). */\n footer?: ReactNode;\n /** Horizontal alignment of the menu relative to the trigger. */\n align?: \"left\" | \"right\";\n /** Notified whenever the menu opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /** Browser tooltip / accessible label for the default trigger. */\n title?: string;\n /** Accessible label (`aria-label`) for the floating menu element itself. */\n menuLabel?: string;\n /** Classes applied to the wrapper. */\n className?: string;\n /** Classes applied to the floating menu. */\n menuClassName?: string;\n};\n\n/**\n * A trigger + floating menu. Flat `items` render as a single list; an item with\n * `children` opens a flyout submenu. The FloatingTree lets every level cooperate\n * on focus and dismissal, so selecting any leaf closes the whole menu.\n */\nexport function DropdownMenu(props: DropdownMenuProps) {\n return (\n <FloatingTree>\n <DropdownMenuRoot {...props} />\n </FloatingTree>\n );\n}\n\nfunction DropdownMenuRoot({\n role: popupRole = \"menu\",\n label,\n icon,\n hideChevron = false,\n variant = \"outline\",\n size = \"sm\",\n trigger,\n items,\n children,\n header,\n footer,\n align = \"right\",\n onOpenChange,\n title,\n menuLabel,\n className,\n menuClassName,\n}: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const floatingZ = useFloatingZIndex();\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n const elementsRef = useRef<Array<HTMLElement | null>>([]);\n\n // Every open/close goes through here, so the host hears each change from the\n // event that caused it rather than from an effect after the render.\n const changeOpen = (next: boolean) => {\n if (next === open) return;\n setOpen(next);\n onOpenChange?.(next);\n };\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n // nodeId is always defined inside the FloatingTree; guard for the type only.\n ...(nodeId ? { nodeId } : {}),\n open,\n onOpenChange: changeOpen,\n // bottom-end / bottom-start reproduce the previous right/left alignment.\n placement: align === \"right\" ? \"bottom-end\" : \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(4) ≈ the previous mt-1; flip opens upward at the bottom edge and\n // shift slides the menu back on-screen at the horizontal edges.\n middleware: [\n offset(4),\n flip({ padding: 8 }),\n shift({ padding: 8 }),\n menuViewportSize,\n ],\n });\n\n const click = useClick(context);\n // useDismiss is React-tree aware: a press inside anything rendered through the\n // menu's `children` render-prop — including a Modal that portals to\n // document.body — propagates via React's synthetic events to the floating\n // element and counts as \"inside\", so it won't dismiss the menu (which would\n // unmount that child Modal). A Modal owned by a sibling/parent instead of this\n // menu correctly does dismiss the menu, which is harmless since closing the\n // menu does not unmount a Modal it doesn't own.\n const dismiss = useDismiss(context, { escapeKey: false });\n const role = useRole(context, { role: popupRole });\n const listNav = useListNavigation(context, {\n listRef: elementsRef,\n activeIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(\n [click, dismiss, role, ...(popupRole === \"menu\" ? [listNav] : [])],\n );\n\n const closeMenu = () => {\n changeOpen(false);\n if (refs.domReference.current instanceof HTMLElement)\n refs.domReference.current.focus();\n };\n useEscapeLayer(open, closeMenu);\n\n // Selecting any leaf (at any depth) emits a tree-wide \"click\"; the root closes\n // and restores focus to the trigger.\n // The listener subscribes once per tree; it reads the latest closeMenu,\n // which is published after each commit rather than during render.\n const closeMenuRef = useRef(closeMenu);\n useLayoutEffect(() => {\n closeMenuRef.current = closeMenu;\n });\n useEffect(() => {\n if (!tree) return;\n const onTreeClick = () => closeMenuRef.current();\n tree.events.on(\"click\", onTreeClick);\n return () => tree.events.off(\"click\", onTreeClick);\n }, [tree]);\n\n return (\n <FloatingNode id={nodeId}>\n <div className={cn(\"relative inline-flex\", className)}>\n {trigger ? (\n <Slot\n ref={refs.setReference}\n className=\"inline-flex\"\n aria-haspopup={popupRole}\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {trigger}\n </Slot>\n ) : (\n <Button\n ref={refs.setReference as React.Ref<HTMLButtonElement>}\n // Opening a menu never submits the form the trigger sits in.\n type=\"button\"\n variant={variant}\n size={size}\n title={title}\n aria-haspopup={popupRole}\n aria-expanded={open}\n {...getReferenceProps()}\n >\n {icon && (\n <Icon\n {...(typeof icon === \"string\" ? { name: icon } : { icon })}\n />\n )}\n {label}\n {!hideChevron && <Icon icon={UiChevronDown} />}\n </Button>\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager\n context={context}\n modal={false}\n closeOnFocusOut={false}\n >\n <div\n ref={refs.setFloating}\n {...getFloatingProps()}\n role={popupRole}\n aria-modal={popupRole === \"dialog\" ? false : undefined}\n aria-label={menuLabel}\n {...(menuLabel ? { \"aria-labelledby\": undefined } : {})}\n style={{ ...floatingStyles, zIndex: floatingZ }}\n className={cn(MENU_POPOVER_CLASS, menuClassName)}\n >\n {header != null && (\n <div className=\"border-b border-border px-3 py-1.5\">\n {header}\n </div>\n )}\n {children ? (\n children(closeMenu)\n ) : (\n <MenuContext.Provider\n value={{\n getItemProps,\n activeIndex,\n setActiveIndex,\n setHasFocusInside: () => {},\n isOpen: open,\n }}\n >\n <FloatingList elementsRef={elementsRef}>\n <MenuItemList items={items ?? []} />\n </FloatingList>\n </MenuContext.Provider>\n )}\n {footer != null && (\n <div className=\"border-t border-border px-3 py-1.5\">\n {footer}\n </div>\n )}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n </FloatingNode>\n );\n}\n"],"mappings":"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"}
@@ -4,6 +4,7 @@ const require_AppShell = require("../layout/AppShell.cjs");
4
4
  const require_useOperations = require("./useOperations.cjs");
5
5
  const require_clickyMetadata = require("./clickyMetadata.cjs");
6
6
  const require_OperationCatalog = require("./OperationCatalog.cjs");
7
+ const require_explorer_nav_context = require("./explorer-nav-context.cjs");
7
8
  const require_commandHref = require("./commandHref.cjs");
8
9
  const require_OperationCommandPage = require("./OperationCommandPage.cjs");
9
10
  const require_OperationEntityPage = require("./OperationEntityPage.cjs");
@@ -12,7 +13,7 @@ let react = require("react");
12
13
  let react_jsx_runtime = require("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 } = require_router.useRouter();
@@ -64,6 +65,26 @@ function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, acti
64
65
  showApiExplorer,
65
66
  explorerDefinition
66
67
  ]);
68
+ const [navContainer, setNavContainer] = (0, react.useState)(null);
69
+ const [navClaims, setNavClaims] = (0, react.useState)(0);
70
+ const claimNav = (0, react.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 = (0, react.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
  (0, react.useEffect)(() => {
68
89
  if (defaultSurface == null || relativePath !== "/") return;
69
90
  navigate(require_commandHref.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__ */ (0, react_jsx_runtime.jsx)(require_AppShell.AppShell, {
97
+ const content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_AppShell.AppShell, {
77
98
  brand: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
78
99
  className: "min-w-0",
79
100
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -87,16 +108,27 @@ function EntityExplorerApp({ client, basePath = "", showApiExplorer = true, acti
87
108
  navSections,
88
109
  sidebarFooter: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_theme_switcher.ThemeSwitcher, {}),
89
110
  ...actions ? { actions } : {},
90
- ...resolvedRoute.kind === "surface" && resolvedRoute.surface ? { nav: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
111
+ ...resolvedRoute.kind === "surface" && resolvedRoute.surface ? { nav: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [navClaims === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
91
112
  className: "flex min-w-0 flex-1 items-baseline gap-density-2",
92
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
93
- className: "min-w-0 truncate text-base font-semibold tracking-tight",
94
- children: resolvedRoute.surface.title
95
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
96
- className: "hidden min-w-0 truncate text-sm text-muted-foreground lg:block",
97
- children: require_clickyMetadata.makeSurfaceDefinition(resolvedRoute.surface).description
98
- })]
99
- }) } : {},
113
+ children: [
114
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", {
115
+ className: "min-w-0 truncate text-base font-semibold tracking-tight",
116
+ children: resolvedRoute.surface.title
117
+ }),
118
+ titleActions ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
119
+ className: "flex shrink-0 items-center self-center",
120
+ children: titleActions
121
+ }) : null,
122
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
123
+ className: "hidden min-w-0 truncate text-sm text-muted-foreground lg:block",
124
+ children: require_clickyMetadata.makeSurfaceDefinition(resolvedRoute.surface).description
125
+ })
126
+ ]
127
+ }), /* @__PURE__ */ (0, react_jsx_runtime.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__ */ (0, react_jsx_runtime.jsx)(UnknownSurface, { surfaceKey: resolvedRoute.surfaceKey }) : resolvedRoute.kind === "entity" ? resolvedRoute.surface ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_OperationEntityPage.OperationEntityPage, {
116
149
  definition: require_clickyMetadata.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__ */ (0, react_jsx_runtime.jsx)(require_explorer_nav_context.ExplorerNavContext.Provider, {
189
+ value: navSlot,
190
+ children: content
191
+ });
155
192
  }
156
193
  function parseExplorerRoute(pathname) {
157
194
  const normalized = require_commandHref.trimTrailingSlash(pathname) || "/";
@@ -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