@flanksource/clicky-ui 0.1.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/README.md +29 -2
  2. package/dist/api-explorer.d.ts +5 -0
  3. package/dist/api-explorer.d.ts.map +1 -0
  4. package/dist/api-explorer.js +25 -0
  5. package/dist/api-explorer.js.map +1 -0
  6. package/dist/clicky.d.ts +2 -0
  7. package/dist/clicky.d.ts.map +1 -0
  8. package/dist/clicky.js +5 -0
  9. package/dist/clicky.js.map +1 -0
  10. package/dist/components/DatePicker.d.ts +18 -0
  11. package/dist/components/DatePicker.d.ts.map +1 -0
  12. package/dist/components/DatePicker.js +63 -0
  13. package/dist/components/DatePicker.js.map +1 -0
  14. package/dist/components/DateTimePicker.d.ts +18 -0
  15. package/dist/components/DateTimePicker.d.ts.map +1 -0
  16. package/dist/components/DateTimePicker.js +84 -0
  17. package/dist/components/DateTimePicker.js.map +1 -0
  18. package/dist/components/FilterBar.d.ts +180 -0
  19. package/dist/components/FilterBar.d.ts.map +1 -0
  20. package/dist/components/FilterBar.js +1685 -0
  21. package/dist/components/FilterBar.js.map +1 -0
  22. package/dist/components/MultiSelect.d.ts +19 -0
  23. package/dist/components/MultiSelect.d.ts.map +1 -0
  24. package/dist/components/MultiSelect.js +143 -0
  25. package/dist/components/MultiSelect.js.map +1 -0
  26. package/dist/components/RangeSlider.d.ts +16 -0
  27. package/dist/components/RangeSlider.d.ts.map +1 -0
  28. package/dist/components/RangeSlider.js +92 -0
  29. package/dist/components/RangeSlider.js.map +1 -0
  30. package/dist/components/button.d.ts +21 -0
  31. package/dist/components/button.d.ts.map +1 -0
  32. package/dist/components/button.js +126 -0
  33. package/dist/components/button.js.map +1 -0
  34. package/dist/components/density-switcher.d.ts +7 -0
  35. package/dist/components/density-switcher.d.ts.map +1 -0
  36. package/dist/components/density-switcher.js +32 -0
  37. package/dist/components/density-switcher.js.map +1 -0
  38. package/dist/components/icon-menu-picker.d.ts +23 -0
  39. package/dist/components/icon-menu-picker.d.ts.map +1 -0
  40. package/dist/components/icon-menu-picker.js +192 -0
  41. package/dist/components/icon-menu-picker.js.map +1 -0
  42. package/dist/components/select.d.ts +15 -0
  43. package/dist/components/select.d.ts.map +1 -0
  44. package/dist/components/select.js +39 -0
  45. package/dist/components/select.js.map +1 -0
  46. package/dist/components/theme-switcher.d.ts +7 -0
  47. package/dist/components/theme-switcher.d.ts.map +1 -0
  48. package/dist/components/theme-switcher.js +42 -0
  49. package/dist/components/theme-switcher.js.map +1 -0
  50. package/dist/components.d.ts +15 -0
  51. package/dist/components.d.ts.map +1 -0
  52. package/dist/components.js +33 -0
  53. package/dist/components.js.map +1 -0
  54. package/dist/data/AnsiHtml.d.ts +7 -0
  55. package/dist/data/AnsiHtml.d.ts.map +1 -0
  56. package/dist/data/AnsiHtml.js +71 -0
  57. package/dist/data/AnsiHtml.js.map +1 -0
  58. package/dist/data/Avatar.d.ts +32 -0
  59. package/dist/data/Avatar.d.ts.map +1 -0
  60. package/dist/data/Avatar.js +201 -0
  61. package/dist/data/Avatar.js.map +1 -0
  62. package/dist/data/AvatarBadge.d.ts +26 -0
  63. package/dist/data/AvatarBadge.d.ts.map +1 -0
  64. package/dist/data/AvatarBadge.js +104 -0
  65. package/dist/data/AvatarBadge.js.map +1 -0
  66. package/dist/data/Badge.d.ts +44 -0
  67. package/dist/data/Badge.d.ts.map +1 -0
  68. package/dist/data/Badge.js +667 -0
  69. package/dist/data/Badge.js.map +1 -0
  70. package/dist/data/Clicky.d.ts +147 -0
  71. package/dist/data/Clicky.d.ts.map +1 -0
  72. package/dist/data/Clicky.fixtures.d.ts +3 -0
  73. package/dist/data/Clicky.fixtures.d.ts.map +1 -0
  74. package/dist/data/Clicky.js +1960 -0
  75. package/dist/data/Clicky.js.map +1 -0
  76. package/dist/data/DataTable.d.ts +95 -0
  77. package/dist/data/DataTable.d.ts.map +1 -0
  78. package/dist/data/DataTable.js +1464 -0
  79. package/dist/data/DataTable.js.map +1 -0
  80. package/dist/data/FilterPill.d.ts +29 -0
  81. package/dist/data/FilterPill.d.ts.map +1 -0
  82. package/dist/data/FilterPill.js +153 -0
  83. package/dist/data/FilterPill.js.map +1 -0
  84. package/dist/data/Gauge.d.ts +15 -0
  85. package/dist/data/Gauge.d.ts.map +1 -0
  86. package/dist/data/Gauge.js +63 -0
  87. package/dist/data/Gauge.js.map +1 -0
  88. package/dist/data/Icon.d.ts +53 -0
  89. package/dist/data/Icon.d.ts.map +1 -0
  90. package/dist/data/Icon.js +115 -0
  91. package/dist/data/Icon.js.map +1 -0
  92. package/dist/data/JsonView.d.ts +8 -0
  93. package/dist/data/JsonView.d.ts.map +1 -0
  94. package/dist/data/JsonView.js +74 -0
  95. package/dist/data/JsonView.js.map +1 -0
  96. package/dist/data/KeyValueList.d.ts +17 -0
  97. package/dist/data/KeyValueList.d.ts.map +1 -0
  98. package/dist/data/KeyValueList.js +33 -0
  99. package/dist/data/KeyValueList.js.map +1 -0
  100. package/dist/data/LogViewer.d.ts +10 -0
  101. package/dist/data/LogViewer.d.ts.map +1 -0
  102. package/dist/data/LogViewer.js +46 -0
  103. package/dist/data/LogViewer.js.map +1 -0
  104. package/dist/data/LogsTable.d.ts +27 -0
  105. package/dist/data/LogsTable.d.ts.map +1 -0
  106. package/dist/data/LogsTable.js +580 -0
  107. package/dist/data/LogsTable.js.map +1 -0
  108. package/dist/data/Markdown.d.ts +6 -0
  109. package/dist/data/Markdown.d.ts.map +1 -0
  110. package/dist/data/Markdown.js +59 -0
  111. package/dist/data/Markdown.js.map +1 -0
  112. package/dist/data/MatrixTable.d.ts +22 -0
  113. package/dist/data/MatrixTable.d.ts.map +1 -0
  114. package/dist/data/MatrixTable.js +164 -0
  115. package/dist/data/MatrixTable.js.map +1 -0
  116. package/dist/data/MethodBadge.d.ts +6 -0
  117. package/dist/data/MethodBadge.d.ts.map +1 -0
  118. package/dist/data/MethodBadge.js +18 -0
  119. package/dist/data/MethodBadge.js.map +1 -0
  120. package/dist/data/ProgressBar.d.ts +13 -0
  121. package/dist/data/ProgressBar.d.ts.map +1 -0
  122. package/dist/data/ProgressBar.js +34 -0
  123. package/dist/data/ProgressBar.js.map +1 -0
  124. package/dist/data/SortableHeader.d.ts +12 -0
  125. package/dist/data/SortableHeader.d.ts.map +1 -0
  126. package/dist/data/SortableHeader.js +33 -0
  127. package/dist/data/SortableHeader.js.map +1 -0
  128. package/dist/data/TabButton.d.ts +12 -0
  129. package/dist/data/TabButton.d.ts.map +1 -0
  130. package/dist/data/TabButton.js +45 -0
  131. package/dist/data/TabButton.js.map +1 -0
  132. package/dist/data/Tree.d.ts +35 -0
  133. package/dist/data/Tree.d.ts.map +1 -0
  134. package/dist/data/Tree.js +236 -0
  135. package/dist/data/Tree.js.map +1 -0
  136. package/dist/data/TreeGroupHeader.d.ts +11 -0
  137. package/dist/data/TreeGroupHeader.d.ts.map +1 -0
  138. package/dist/data/TreeGroupHeader.js +41 -0
  139. package/dist/data/TreeGroupHeader.js.map +1 -0
  140. package/dist/data/TreeNode.d.ts +43 -0
  141. package/dist/data/TreeNode.d.ts.map +1 -0
  142. package/dist/data/TreeNode.js +100 -0
  143. package/dist/data/TreeNode.js.map +1 -0
  144. package/dist/data/cells/StatusDot.d.ts +11 -0
  145. package/dist/data/cells/StatusDot.d.ts.map +1 -0
  146. package/dist/data/cells/StatusDot.js +38 -0
  147. package/dist/data/cells/StatusDot.js.map +1 -0
  148. package/dist/data/cells/TagList.d.ts +59 -0
  149. package/dist/data/cells/TagList.d.ts.map +1 -0
  150. package/dist/data/cells/TagList.js +257 -0
  151. package/dist/data/cells/TagList.js.map +1 -0
  152. package/dist/data/cells/Timestamp.d.ts +46 -0
  153. package/dist/data/cells/Timestamp.d.ts.map +1 -0
  154. package/dist/data/cells/Timestamp.js +146 -0
  155. package/dist/data/cells/Timestamp.js.map +1 -0
  156. package/dist/data/cells/status-mapping.d.ts +8 -0
  157. package/dist/data/cells/status-mapping.d.ts.map +1 -0
  158. package/dist/data/cells/status-mapping.js +44 -0
  159. package/dist/data/cells/status-mapping.js.map +1 -0
  160. package/dist/data/code-highlight.d.ts +12 -0
  161. package/dist/data/code-highlight.d.ts.map +1 -0
  162. package/dist/data/code-highlight.js +28 -0
  163. package/dist/data/code-highlight.js.map +1 -0
  164. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +9 -0
  165. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -0
  166. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +445 -0
  167. package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -0
  168. package/dist/data/diagnostics/DiagnosticsTree.d.ts +9 -0
  169. package/dist/data/diagnostics/DiagnosticsTree.d.ts.map +1 -0
  170. package/dist/data/diagnostics/DiagnosticsTree.js +78 -0
  171. package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -0
  172. package/dist/data/diagnostics/ErrorDetails.d.ts +20 -0
  173. package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -0
  174. package/dist/data/diagnostics/ErrorDetails.js +157 -0
  175. package/dist/data/diagnostics/ErrorDetails.js.map +1 -0
  176. package/dist/data/diagnostics/GoroutineCard.d.ts +10 -0
  177. package/dist/data/diagnostics/GoroutineCard.d.ts.map +1 -0
  178. package/dist/data/diagnostics/GoroutineCard.js +75 -0
  179. package/dist/data/diagnostics/GoroutineCard.js.map +1 -0
  180. package/dist/data/diagnostics/JvmStackTrace.d.ts +11 -0
  181. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -0
  182. package/dist/data/diagnostics/JvmStackTrace.js +26 -0
  183. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -0
  184. package/dist/data/diagnostics/RenderedStackTrace.d.ts +18 -0
  185. package/dist/data/diagnostics/RenderedStackTrace.d.ts.map +1 -0
  186. package/dist/data/diagnostics/RenderedStackTrace.js +235 -0
  187. package/dist/data/diagnostics/RenderedStackTrace.js.map +1 -0
  188. package/dist/data/diagnostics/ThreadCard.d.ts +10 -0
  189. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -0
  190. package/dist/data/diagnostics/ThreadCard.js +78 -0
  191. package/dist/data/diagnostics/ThreadCard.js.map +1 -0
  192. package/dist/data/diagnostics/error-diagnostics.d.ts +26 -0
  193. package/dist/data/diagnostics/error-diagnostics.d.ts.map +1 -0
  194. package/dist/data/diagnostics/error-diagnostics.js +108 -0
  195. package/dist/data/diagnostics/error-diagnostics.js.map +1 -0
  196. package/dist/data/diagnostics/fixtures.d.ts +3 -0
  197. package/dist/data/diagnostics/fixtures.d.ts.map +1 -0
  198. package/dist/data/diagnostics/jvm-stacktrace.d.ts +34 -0
  199. package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -0
  200. package/dist/data/diagnostics/jvm-stacktrace.js +190 -0
  201. package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -0
  202. package/dist/data/diagnostics/stacktrace-parse.d.ts +11 -0
  203. package/dist/data/diagnostics/stacktrace-parse.d.ts.map +1 -0
  204. package/dist/data/diagnostics/stacktrace-parse.js +87 -0
  205. package/dist/data/diagnostics/stacktrace-parse.js.map +1 -0
  206. package/dist/data/diagnostics/stacktrace.d.ts +38 -0
  207. package/dist/data/diagnostics/stacktrace.d.ts.map +1 -0
  208. package/dist/data/diagnostics/stacktrace.js +119 -0
  209. package/dist/data/diagnostics/stacktrace.js.map +1 -0
  210. package/dist/data/diagnostics/types.d.ts +30 -0
  211. package/dist/data/diagnostics/types.d.ts.map +1 -0
  212. package/dist/data/diagnostics/utils.d.ts +8 -0
  213. package/dist/data/diagnostics/utils.d.ts.map +1 -0
  214. package/dist/data/diagnostics/utils.js +59 -0
  215. package/dist/data/diagnostics/utils.js.map +1 -0
  216. package/dist/data/har/HarPanel.d.ts +9 -0
  217. package/dist/data/har/HarPanel.d.ts.map +1 -0
  218. package/dist/data/har/HarPanel.js +175 -0
  219. package/dist/data/har/HarPanel.js.map +1 -0
  220. package/dist/data/har/fixtures.d.ts +3 -0
  221. package/dist/data/har/fixtures.d.ts.map +1 -0
  222. package/dist/data/har/types.d.ts +47 -0
  223. package/dist/data/har/types.d.ts.map +1 -0
  224. package/dist/data.d.ts +39 -0
  225. package/dist/data.d.ts.map +1 -0
  226. package/dist/data.js +109 -0
  227. package/dist/data.js.map +1 -0
  228. package/dist/hooks/use-density.d.ts +22 -0
  229. package/dist/hooks/use-density.d.ts.map +1 -0
  230. package/dist/hooks/use-density.js +54 -0
  231. package/dist/hooks/use-density.js.map +1 -0
  232. package/dist/hooks/use-history-route.d.ts +6 -0
  233. package/dist/hooks/use-history-route.d.ts.map +1 -0
  234. package/dist/hooks/use-history-route.js +31 -0
  235. package/dist/hooks/use-history-route.js.map +1 -0
  236. package/dist/hooks/use-sort.d.ts +17 -0
  237. package/dist/hooks/use-sort.d.ts.map +1 -0
  238. package/dist/hooks/use-sort.js +42 -0
  239. package/dist/hooks/use-sort.js.map +1 -0
  240. package/dist/hooks/use-theme.d.ts +17 -0
  241. package/dist/hooks/use-theme.d.ts.map +1 -0
  242. package/dist/hooks/use-theme.js +68 -0
  243. package/dist/hooks/use-theme.js.map +1 -0
  244. package/dist/hooks.d.ts +5 -0
  245. package/dist/hooks.d.ts.map +1 -0
  246. package/dist/hooks.js +14 -0
  247. package/dist/hooks.js.map +1 -0
  248. package/dist/index.d.ts +7 -0
  249. package/dist/index.d.ts.map +1 -0
  250. package/dist/index.js +195 -0
  251. package/dist/index.js.map +1 -0
  252. package/dist/layout/Section.d.ts +23 -0
  253. package/dist/layout/Section.d.ts.map +1 -0
  254. package/dist/layout/Section.js +73 -0
  255. package/dist/layout/Section.js.map +1 -0
  256. package/dist/layout/SplitPane.d.ts +13 -0
  257. package/dist/layout/SplitPane.d.ts.map +1 -0
  258. package/dist/layout/SplitPane.js +72 -0
  259. package/dist/layout/SplitPane.js.map +1 -0
  260. package/dist/lib/palette.d.ts +4 -0
  261. package/dist/lib/palette.d.ts.map +1 -0
  262. package/dist/lib/palette.js +35 -0
  263. package/dist/lib/palette.js.map +1 -0
  264. package/dist/lib/size.d.ts +6 -0
  265. package/dist/lib/size.d.ts.map +1 -0
  266. package/dist/lib/size.js +14 -0
  267. package/dist/lib/size.js.map +1 -0
  268. package/dist/lib/utils.d.ts +3 -0
  269. package/dist/lib/utils.d.ts.map +1 -0
  270. package/dist/lib/utils.js +9 -0
  271. package/dist/lib/utils.js.map +1 -0
  272. package/dist/overlay/HoverCard.d.ts +13 -0
  273. package/dist/overlay/HoverCard.d.ts.map +1 -0
  274. package/dist/overlay/HoverCard.js +170 -0
  275. package/dist/overlay/HoverCard.js.map +1 -0
  276. package/dist/overlay/Modal.d.ts +17 -0
  277. package/dist/overlay/Modal.d.ts.map +1 -0
  278. package/dist/overlay/Modal.js +91 -0
  279. package/dist/overlay/Modal.js.map +1 -0
  280. package/dist/rpc/AcceptPicker.d.ts +52 -0
  281. package/dist/rpc/AcceptPicker.d.ts.map +1 -0
  282. package/dist/rpc/AcceptPicker.js +126 -0
  283. package/dist/rpc/AcceptPicker.js.map +1 -0
  284. package/dist/rpc/ApiExplorer.d.ts +11 -0
  285. package/dist/rpc/ApiExplorer.d.ts.map +1 -0
  286. package/dist/rpc/ApiExplorer.js +37 -0
  287. package/dist/rpc/ApiExplorer.js.map +1 -0
  288. package/dist/rpc/CommandForm.d.ts +15 -0
  289. package/dist/rpc/CommandForm.d.ts.map +1 -0
  290. package/dist/rpc/CommandForm.js +356 -0
  291. package/dist/rpc/CommandForm.js.map +1 -0
  292. package/dist/rpc/CommandOutput.d.ts +11 -0
  293. package/dist/rpc/CommandOutput.d.ts.map +1 -0
  294. package/dist/rpc/CommandOutput.js +195 -0
  295. package/dist/rpc/CommandOutput.js.map +1 -0
  296. package/dist/rpc/EndpointList.d.ts +18 -0
  297. package/dist/rpc/EndpointList.d.ts.map +1 -0
  298. package/dist/rpc/EndpointList.js +56 -0
  299. package/dist/rpc/EndpointList.js.map +1 -0
  300. package/dist/rpc/EntityExplorerApp.d.ts +15 -0
  301. package/dist/rpc/EntityExplorerApp.d.ts.map +1 -0
  302. package/dist/rpc/EntityExplorerApp.js +282 -0
  303. package/dist/rpc/EntityExplorerApp.js.map +1 -0
  304. package/dist/rpc/ExecutionResult.d.ts +14 -0
  305. package/dist/rpc/ExecutionResult.d.ts.map +1 -0
  306. package/dist/rpc/ExecutionResult.js +51 -0
  307. package/dist/rpc/ExecutionResult.js.map +1 -0
  308. package/dist/rpc/FilterForm.d.ts +22 -0
  309. package/dist/rpc/FilterForm.d.ts.map +1 -0
  310. package/dist/rpc/FilterForm.js +392 -0
  311. package/dist/rpc/FilterForm.js.map +1 -0
  312. package/dist/rpc/InlineError.d.ts +7 -0
  313. package/dist/rpc/InlineError.d.ts.map +1 -0
  314. package/dist/rpc/InlineError.js +54 -0
  315. package/dist/rpc/InlineError.js.map +1 -0
  316. package/dist/rpc/OperationActionDialog.d.ts +12 -0
  317. package/dist/rpc/OperationActionDialog.d.ts.map +1 -0
  318. package/dist/rpc/OperationActionDialog.js +105 -0
  319. package/dist/rpc/OperationActionDialog.js.map +1 -0
  320. package/dist/rpc/OperationCatalog.d.ts +21 -0
  321. package/dist/rpc/OperationCatalog.d.ts.map +1 -0
  322. package/dist/rpc/OperationCatalog.js +339 -0
  323. package/dist/rpc/OperationCatalog.js.map +1 -0
  324. package/dist/rpc/OperationCommandPage.d.ts +22 -0
  325. package/dist/rpc/OperationCommandPage.d.ts.map +1 -0
  326. package/dist/rpc/OperationCommandPage.js +484 -0
  327. package/dist/rpc/OperationCommandPage.js.map +1 -0
  328. package/dist/rpc/OperationEntityPage.d.ts +23 -0
  329. package/dist/rpc/OperationEntityPage.d.ts.map +1 -0
  330. package/dist/rpc/OperationEntityPage.js +218 -0
  331. package/dist/rpc/OperationEntityPage.js.map +1 -0
  332. package/dist/rpc/classify.d.ts +8 -0
  333. package/dist/rpc/classify.d.ts.map +1 -0
  334. package/dist/rpc/classify.js +76 -0
  335. package/dist/rpc/classify.js.map +1 -0
  336. package/dist/rpc/clickyMetadata.d.ts +12 -0
  337. package/dist/rpc/clickyMetadata.d.ts.map +1 -0
  338. package/dist/rpc/clickyMetadata.js +71 -0
  339. package/dist/rpc/clickyMetadata.js.map +1 -0
  340. package/dist/rpc/formMetadata.d.ts +27 -0
  341. package/dist/rpc/formMetadata.d.ts.map +1 -0
  342. package/dist/rpc/formMetadata.js +250 -0
  343. package/dist/rpc/formMetadata.js.map +1 -0
  344. package/dist/rpc/types.d.ts +109 -0
  345. package/dist/rpc/types.d.ts.map +1 -0
  346. package/dist/rpc/types.js +8 -0
  347. package/dist/rpc/types.js.map +1 -0
  348. package/dist/rpc/useOperations.d.ts +346 -0
  349. package/dist/rpc/useOperations.d.ts.map +1 -0
  350. package/dist/rpc/useOperations.js +31 -0
  351. package/dist/rpc/useOperations.js.map +1 -0
  352. package/dist/rpc.d.ts +14 -0
  353. package/dist/rpc.d.ts.map +1 -0
  354. package/dist/rpc.js +37 -0
  355. package/dist/rpc.js.map +1 -0
  356. package/dist/styles.css +2 -0
  357. package/dist/styles.d.ts +1 -0
  358. package/dist/styles.d.ts.map +1 -0
  359. package/dist/styles.js +2 -0
  360. package/dist/styles.js.map +1 -0
  361. package/dist/tailwind-preset.d.ts +4 -0
  362. package/dist/tailwind-preset.d.ts.map +1 -0
  363. package/dist/tailwind-preset.js +69 -0
  364. package/dist/tailwind-preset.js.map +1 -0
  365. package/dist/utils.d.ts +4 -0
  366. package/dist/utils.d.ts.map +1 -0
  367. package/dist/utils.js +12 -0
  368. package/dist/utils.js.map +1 -0
  369. package/package.json +83 -40
  370. package/dist/index.d.mts +0 -834
  371. package/dist/index.d.mts.map +0 -1
  372. package/dist/index.mjs +0 -2918
  373. package/dist/index.mjs.map +0 -1
  374. package/dist/tailwind-preset.d.mts +0 -7
  375. package/dist/tailwind-preset.d.mts.map +0 -1
  376. package/dist/tailwind-preset.mjs +0 -64
  377. package/dist/tailwind-preset.mjs.map +0 -1
  378. package/src/styles/tokens.css +0 -78
@@ -0,0 +1,1960 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query";
3
+ import { useState, useMemo, useEffect, createContext, useRef, useContext, Fragment as Fragment$1 } from "react";
4
+ import { FilterForm } from "../rpc/FilterForm.js";
5
+ import { parseJsonBody } from "../rpc/classify.js";
6
+ import { packParameterValues, pruneParameterValues } from "../rpc/formMetadata.js";
7
+ import { isPositionalParam } from "../rpc/types.js";
8
+ import { useOperations } from "../rpc/useOperations.js";
9
+ import { cn } from "../lib/utils.js";
10
+ import { DataTable } from "./DataTable.js";
11
+ import { Tree } from "./Tree.js";
12
+ import { Icon } from "./Icon.js";
13
+ import { JsonView } from "./JsonView.js";
14
+ import { highlightCode } from "./code-highlight.js";
15
+ import { StackTrace } from "./diagnostics/RenderedStackTrace.js";
16
+ import { Badge } from "./Badge.js";
17
+ import { HoverCard } from "../overlay/HoverCard.js";
18
+ import { Modal } from "../overlay/Modal.js";
19
+ import { TagList, normalizeTags, TagActionsProvider } from "./cells/TagList.js";
20
+ const CLICKY_PRIMARY_VIEW_FORMATS = ["clicky", "json"];
21
+ const CLICKY_OVERFLOW_VIEW_FORMATS = [
22
+ "pdf",
23
+ "html",
24
+ "markdown",
25
+ "yaml",
26
+ "csv",
27
+ "pretty",
28
+ "excel",
29
+ "slack"
30
+ ];
31
+ const CLICKY_DOWNLOAD_FORMATS = ["json", "clicky", ...CLICKY_OVERFLOW_VIEW_FORMATS];
32
+ const clickyRuntimeContextDefault = {
33
+ operations: [],
34
+ operationsLoading: false
35
+ };
36
+ const ClickyRuntimeContext = createContext(clickyRuntimeContextDefault);
37
+ function Clicky(props) {
38
+ const [queryClient] = useState(
39
+ () => new QueryClient({
40
+ defaultOptions: {
41
+ queries: {
42
+ staleTime: 3e4,
43
+ retry: 1
44
+ }
45
+ }
46
+ })
47
+ );
48
+ const content = /* @__PURE__ */ jsx(
49
+ ClickyRuntimeProvider,
50
+ {
51
+ ...props.commandRuntime ? { commandRuntime: props.commandRuntime } : {},
52
+ ...props.onTableRowClick ? { onTableRowClick: props.onTableRowClick } : {},
53
+ ...props.getTableRowHref ? { getTableRowHref: props.getTableRowHref } : {},
54
+ ...props.isTableRowClickable ? { isTableRowClickable: props.isTableRowClickable } : {},
55
+ children: props.url ? /* @__PURE__ */ jsx(ClickyRemoteRenderer, { ...props, url: props.url }) : /* @__PURE__ */ jsx(
56
+ ClickyContent,
57
+ {
58
+ data: props.data,
59
+ ...props.className ? { className: props.className } : {}
60
+ }
61
+ )
62
+ }
63
+ );
64
+ if (props.url || props.commandRuntime) {
65
+ return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: content });
66
+ }
67
+ return content;
68
+ }
69
+ function ClickyRuntimeProvider({
70
+ commandRuntime,
71
+ onTableRowClick,
72
+ getTableRowHref,
73
+ isTableRowClickable,
74
+ children
75
+ }) {
76
+ if (!commandRuntime) {
77
+ return /* @__PURE__ */ jsx(
78
+ ClickyRuntimeContext.Provider,
79
+ {
80
+ value: onTableRowClick || getTableRowHref || isTableRowClickable ? {
81
+ ...clickyRuntimeContextDefault,
82
+ onTableRowClick,
83
+ getTableRowHref,
84
+ isTableRowClickable
85
+ } : clickyRuntimeContextDefault,
86
+ children
87
+ }
88
+ );
89
+ }
90
+ return /* @__PURE__ */ jsx(
91
+ ClickyCommandRuntimeProvider,
92
+ {
93
+ commandRuntime,
94
+ ...onTableRowClick ? { onTableRowClick } : {},
95
+ ...getTableRowHref ? { getTableRowHref } : {},
96
+ ...isTableRowClickable ? { isTableRowClickable } : {},
97
+ children
98
+ }
99
+ );
100
+ }
101
+ function ClickyCommandRuntimeProvider({
102
+ commandRuntime,
103
+ onTableRowClick,
104
+ getTableRowHref,
105
+ isTableRowClickable,
106
+ children
107
+ }) {
108
+ const { operations, isLoading } = useOperations(commandRuntime.client);
109
+ const value = useMemo(
110
+ () => ({
111
+ commandRuntime,
112
+ onTableRowClick,
113
+ getTableRowHref,
114
+ isTableRowClickable,
115
+ operations,
116
+ operationsLoading: isLoading
117
+ }),
118
+ [commandRuntime, getTableRowHref, isLoading, isTableRowClickable, onTableRowClick, operations]
119
+ );
120
+ return /* @__PURE__ */ jsx(ClickyRuntimeContext.Provider, { value, children });
121
+ }
122
+ function ClickyContent({
123
+ data,
124
+ className
125
+ }) {
126
+ if (data === void 0) {
127
+ return /* @__PURE__ */ jsx(
128
+ ClickyNotice,
129
+ {
130
+ className,
131
+ title: "No Clicky data",
132
+ message: "Provide either a local data payload or a URL."
133
+ }
134
+ );
135
+ }
136
+ const parsed = parseClickyData(data);
137
+ if (!parsed.ok) {
138
+ return /* @__PURE__ */ jsx(ClickyInvalidPayload, { parsed, className });
139
+ }
140
+ return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: parsed.document.node }) });
141
+ }
142
+ function ClickyRemoteRenderer({
143
+ data,
144
+ url,
145
+ view,
146
+ download,
147
+ className
148
+ }) {
149
+ var _a, _b;
150
+ const availableViews = useMemo(() => getAvailableViews({ data, url, view }), [data, url, view]);
151
+ const primaryViews = useMemo(() => availableViews.filter(isPrimaryViewFormat), [availableViews]);
152
+ const overflowViews = useMemo(
153
+ () => availableViews.filter(isOverflowViewFormat),
154
+ [availableViews]
155
+ );
156
+ const downloadFormats = useMemo(() => getDownloadFormats({ url, download }), [download, url]);
157
+ const [activeView, setActiveView] = useState(
158
+ () => availableViews[0] ?? "clicky"
159
+ );
160
+ useEffect(() => {
161
+ if (!availableViews.includes(activeView)) {
162
+ setActiveView(availableViews[0] ?? "clicky");
163
+ }
164
+ }, [activeView, availableViews]);
165
+ const formattedUrl = buildFormatUrl(url, activeView);
166
+ const activeQuery = useQuery({
167
+ queryKey: ["clicky", activeView, formattedUrl],
168
+ enabled: shouldFetchRemoteView(activeView),
169
+ queryFn: async () => fetchRemoteFormat(formattedUrl, activeView)
170
+ });
171
+ const effectiveClickyData = activeView === "clicky" && ((_a = activeQuery.data) == null ? void 0 : _a.kind) === "text" ? activeQuery.data.text : data;
172
+ const fallbackJsonData = useMemo(() => parseJsonValue(data), [data]);
173
+ const effectiveJsonData = activeView === "json" && ((_b = activeQuery.data) == null ? void 0 : _b.kind) === "text" ? parseJsonValue(activeQuery.data.text) : fallbackJsonData;
174
+ const activeOverflowView = isOverflowViewFormat(activeView) ? activeView : null;
175
+ const canDownload = downloadFormats.length > 0;
176
+ const loadingMessage = `Fetching ${formattedUrl}`;
177
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-density-3", className), children: [
178
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 rounded-md border border-border bg-muted/20 px-density-3 py-density-2", children: [
179
+ primaryViews.length > 1 && /* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": "Clicky view mode", className: "flex flex-wrap gap-1", children: primaryViews.map((mode) => /* @__PURE__ */ jsx(
180
+ "button",
181
+ {
182
+ type: "button",
183
+ role: "radio",
184
+ "aria-checked": activeView === mode,
185
+ onClick: () => setActiveView(mode),
186
+ className: cn(
187
+ "rounded-md border px-2.5 py-1 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
188
+ activeView === mode ? "border-foreground/20 bg-accent text-foreground" : "border-transparent text-muted-foreground hover:border-foreground/20 hover:text-foreground"
189
+ ),
190
+ children: formatViewLabel(mode)
191
+ },
192
+ mode
193
+ )) }),
194
+ overflowViews.length > 0 && /* @__PURE__ */ jsx(
195
+ ClickyViewMenu,
196
+ {
197
+ activeFormat: activeOverflowView,
198
+ formats: overflowViews,
199
+ onSelect: setActiveView
200
+ }
201
+ ),
202
+ /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
203
+ shouldFetchRemoteView(activeView) && activeQuery.isFetching && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Refreshing…" }),
204
+ canDownload && /* @__PURE__ */ jsx(ClickyDownloadMenu, { url, formats: downloadFormats, label: download == null ? void 0 : download.label })
205
+ ] })
206
+ ] }),
207
+ activeView === "pdf" ? /* @__PURE__ */ jsx(ClickyPdfPreview, { src: formattedUrl }) : activeView === "html" ? /* @__PURE__ */ jsx(ClickyHtmlPreview, { src: formattedUrl }) : activeView === "excel" ? /* @__PURE__ */ jsx(
208
+ ClickyUnsupportedPreview,
209
+ {
210
+ title: "Excel preview",
211
+ message: "Excel output is available for download, but not inline preview.",
212
+ href: formattedUrl
213
+ }
214
+ ) : activeView === "clicky" ? activeQuery.isPending && effectiveClickyData === void 0 ? /* @__PURE__ */ jsx(ClickyNotice, { title: "Loading Clicky", message: loadingMessage }) : activeQuery.isError && effectiveClickyData === void 0 ? /* @__PURE__ */ jsx(
215
+ ClickyNotice,
216
+ {
217
+ title: "Clicky request failed",
218
+ message: activeQuery.error instanceof Error ? activeQuery.error.message : "Request failed",
219
+ tone: "destructive"
220
+ }
221
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
222
+ activeQuery.isError && data !== void 0 && /* @__PURE__ */ jsx(
223
+ ClickyNotice,
224
+ {
225
+ title: "Remote refresh failed",
226
+ message: "Showing the local fallback payload instead.",
227
+ tone: "warning"
228
+ }
229
+ ),
230
+ /* @__PURE__ */ jsx(ClickyContent, { data: effectiveClickyData })
231
+ ] }) : activeView === "json" ? activeQuery.isPending && effectiveJsonData === void 0 ? /* @__PURE__ */ jsx(ClickyNotice, { title: "Loading JSON", message: loadingMessage }) : activeQuery.isError && effectiveJsonData === void 0 ? /* @__PURE__ */ jsx(
232
+ ClickyNotice,
233
+ {
234
+ title: "JSON request failed",
235
+ message: activeQuery.error instanceof Error ? activeQuery.error.message : "Request failed",
236
+ tone: "destructive"
237
+ }
238
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
239
+ activeQuery.isError && fallbackJsonData !== void 0 && /* @__PURE__ */ jsx(
240
+ ClickyNotice,
241
+ {
242
+ title: "Remote refresh failed",
243
+ message: "Showing the local fallback payload instead.",
244
+ tone: "warning"
245
+ }
246
+ ),
247
+ /* @__PURE__ */ jsx(ClickyJsonTree, { value: effectiveJsonData })
248
+ ] }) : activeQuery.isPending ? /* @__PURE__ */ jsx(ClickyNotice, { title: `Loading ${formatViewLabel(activeView)}`, message: loadingMessage }) : activeQuery.isError ? /* @__PURE__ */ jsx(
249
+ ClickyNotice,
250
+ {
251
+ title: `${formatViewLabel(activeView)} request failed`,
252
+ message: activeQuery.error instanceof Error ? activeQuery.error.message : "Request failed",
253
+ tone: "destructive"
254
+ }
255
+ ) : /* @__PURE__ */ jsx(ClickyRemotePreview, { format: activeView, response: activeQuery.data })
256
+ ] });
257
+ }
258
+ function ClickyViewMenu({
259
+ activeFormat,
260
+ formats,
261
+ onSelect
262
+ }) {
263
+ const rootRef = useRef(null);
264
+ const triggerRef = useRef(null);
265
+ const [open, setOpen] = useState(false);
266
+ useDismissablePopup(open, rootRef, triggerRef, () => setOpen(false));
267
+ return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: "relative", children: [
268
+ /* @__PURE__ */ jsx(
269
+ "button",
270
+ {
271
+ ref: triggerRef,
272
+ type: "button",
273
+ "aria-label": "Open additional view menu",
274
+ "aria-haspopup": "menu",
275
+ "aria-expanded": open,
276
+ "aria-pressed": activeFormat != null,
277
+ className: cn(
278
+ "inline-flex h-[34px] w-[34px] items-center justify-center rounded-md border border-input bg-background text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
279
+ activeFormat && "border-foreground/20 bg-accent text-foreground"
280
+ ),
281
+ onClick: () => setOpen((current) => !current),
282
+ children: /* @__PURE__ */ jsx(Icon, { name: "codicon:ellipsis", className: "text-sm" })
283
+ }
284
+ ),
285
+ open && /* @__PURE__ */ jsx(
286
+ "div",
287
+ {
288
+ role: "menu",
289
+ className: "absolute left-0 top-[calc(100%+0.375rem)] z-50 min-w-[18rem] rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-lg shadow-black/5",
290
+ children: formats.map((format) => {
291
+ const active = format === activeFormat;
292
+ const meta = getRemoteFormatMeta(format);
293
+ return /* @__PURE__ */ jsxs(
294
+ "button",
295
+ {
296
+ type: "button",
297
+ role: "menuitemradio",
298
+ "aria-checked": active,
299
+ className: cn(
300
+ "flex w-full items-start gap-3 rounded-md px-3 py-2 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none",
301
+ active && "bg-accent/70"
302
+ ),
303
+ onClick: () => {
304
+ onSelect(format);
305
+ setOpen(false);
306
+ },
307
+ children: [
308
+ /* @__PURE__ */ jsx(
309
+ Icon,
310
+ {
311
+ name: meta.icon,
312
+ className: cn(
313
+ "mt-0.5 shrink-0 text-base text-muted-foreground",
314
+ active && "text-foreground"
315
+ )
316
+ }
317
+ ),
318
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
319
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-between gap-3", children: [
320
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: meta.label }),
321
+ active && /* @__PURE__ */ jsx(Icon, { name: "codicon:check", className: "text-xs text-muted-foreground" })
322
+ ] }),
323
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: meta.description })
324
+ ] })
325
+ ]
326
+ },
327
+ format
328
+ );
329
+ })
330
+ }
331
+ )
332
+ ] });
333
+ }
334
+ function ClickyDownloadMenu({
335
+ url,
336
+ formats,
337
+ label
338
+ }) {
339
+ const rootRef = useRef(null);
340
+ const triggerRef = useRef(null);
341
+ const [open, setOpen] = useState(false);
342
+ const primaryFormat = "json";
343
+ const primaryMeta = getRemoteFormatMeta(primaryFormat);
344
+ useDismissablePopup(open, rootRef, triggerRef, () => setOpen(false));
345
+ return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: "relative", children: [
346
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
347
+ /* @__PURE__ */ jsxs(
348
+ "button",
349
+ {
350
+ type: "button",
351
+ "aria-label": label ? `Download ${primaryMeta.label} ${label}` : `Download ${primaryMeta.label}`,
352
+ className: "inline-flex items-center gap-2 rounded-md border border-input bg-background px-3 py-1.5 text-xs font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
353
+ onClick: () => submitDownloadRequest(buildFormatUrl(url, primaryFormat)),
354
+ children: [
355
+ /* @__PURE__ */ jsx(Icon, { name: "codicon:cloud-download", className: "text-sm" }),
356
+ /* @__PURE__ */ jsx("span", { children: `Download ${primaryMeta.label}` })
357
+ ]
358
+ }
359
+ ),
360
+ /* @__PURE__ */ jsx(
361
+ "button",
362
+ {
363
+ ref: triggerRef,
364
+ type: "button",
365
+ "aria-label": "Open download menu",
366
+ "aria-haspopup": "menu",
367
+ "aria-expanded": open,
368
+ className: "inline-flex h-[34px] w-[34px] items-center justify-center rounded-md border border-input bg-background text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
369
+ onClick: () => setOpen((current) => !current),
370
+ children: /* @__PURE__ */ jsx(Icon, { name: open ? "codicon:chevron-up" : "codicon:chevron-down", className: "text-sm" })
371
+ }
372
+ )
373
+ ] }),
374
+ open && /* @__PURE__ */ jsx(
375
+ "div",
376
+ {
377
+ role: "menu",
378
+ className: "absolute right-0 top-[calc(100%+0.375rem)] z-50 min-w-[18rem] rounded-md border border-border bg-popover p-1.5 text-popover-foreground shadow-lg shadow-black/5",
379
+ children: formats.map((format) => {
380
+ const meta = getRemoteFormatMeta(format);
381
+ return /* @__PURE__ */ jsxs(
382
+ "button",
383
+ {
384
+ type: "button",
385
+ role: "menuitem",
386
+ className: cn(
387
+ "flex w-full items-start gap-3 rounded-md px-3 py-2 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:outline-none"
388
+ ),
389
+ onClick: () => {
390
+ submitDownloadRequest(buildFormatUrl(url, format));
391
+ setOpen(false);
392
+ },
393
+ children: [
394
+ /* @__PURE__ */ jsx(
395
+ Icon,
396
+ {
397
+ name: meta.icon,
398
+ className: "mt-0.5 shrink-0 text-base text-muted-foreground"
399
+ }
400
+ ),
401
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
402
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: meta.label }),
403
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: meta.description })
404
+ ] })
405
+ ]
406
+ },
407
+ format
408
+ );
409
+ })
410
+ }
411
+ )
412
+ ] });
413
+ }
414
+ function useDismissablePopup(open, rootRef, triggerRef, onClose) {
415
+ useEffect(() => {
416
+ if (!open) return;
417
+ const onPointerDown = (event) => {
418
+ var _a;
419
+ if (!((_a = rootRef.current) == null ? void 0 : _a.contains(event.target))) {
420
+ onClose();
421
+ }
422
+ };
423
+ const onKeyDown = (event) => {
424
+ var _a;
425
+ if (event.key === "Escape") {
426
+ onClose();
427
+ (_a = triggerRef.current) == null ? void 0 : _a.focus();
428
+ }
429
+ };
430
+ document.addEventListener("mousedown", onPointerDown);
431
+ document.addEventListener("keydown", onKeyDown);
432
+ return () => {
433
+ document.removeEventListener("mousedown", onPointerDown);
434
+ document.removeEventListener("keydown", onKeyDown);
435
+ };
436
+ }, [onClose, open, rootRef, triggerRef]);
437
+ }
438
+ function parseClickyData(data) {
439
+ if (typeof data === "string") {
440
+ try {
441
+ return normalizeClickyDocument(JSON.parse(data));
442
+ } catch (error) {
443
+ return {
444
+ ok: false,
445
+ message: error instanceof Error ? error.message : "Failed to parse JSON",
446
+ raw: data
447
+ };
448
+ }
449
+ }
450
+ return normalizeClickyDocument(data);
451
+ }
452
+ function fetchRemoteFormat(url, format) {
453
+ return fetch(url, {
454
+ headers: {
455
+ Accept: getRemoteFormatMeta(format).accept
456
+ }
457
+ }).then(async (response) => {
458
+ if (!response.ok) {
459
+ throw new Error(`Request failed with ${response.status} ${response.statusText}`.trim());
460
+ }
461
+ const contentType = response.headers.get("Content-Type") ?? "";
462
+ if (format === "excel") {
463
+ return {
464
+ kind: "blob",
465
+ blob: await response.blob(),
466
+ contentType
467
+ };
468
+ }
469
+ return {
470
+ kind: "text",
471
+ text: await response.text(),
472
+ contentType
473
+ };
474
+ });
475
+ }
476
+ function ClickyInvalidPayload({
477
+ parsed,
478
+ className
479
+ }) {
480
+ return /* @__PURE__ */ jsxs(
481
+ "div",
482
+ {
483
+ className: cn(
484
+ "rounded-md border border-destructive/30 bg-destructive/5 p-density-3",
485
+ className
486
+ ),
487
+ children: [
488
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-destructive", children: "Invalid Clicky payload" }),
489
+ /* @__PURE__ */ jsxs("pre", { className: "mt-2 whitespace-pre-wrap break-all text-xs text-muted-foreground", children: [
490
+ parsed.message,
491
+ parsed.raw ? `
492
+
493
+ ${parsed.raw}` : ""
494
+ ] })
495
+ ]
496
+ }
497
+ );
498
+ }
499
+ function ClickyNotice({
500
+ title,
501
+ message,
502
+ tone = "default",
503
+ className
504
+ }) {
505
+ return /* @__PURE__ */ jsxs(
506
+ "div",
507
+ {
508
+ className: cn(
509
+ "rounded-md border p-density-3",
510
+ tone === "destructive" && "border-destructive/30 bg-destructive/5",
511
+ tone === "warning" && "border-yellow-500/30 bg-yellow-500/5",
512
+ tone === "default" && "border-border bg-muted/30",
513
+ className
514
+ ),
515
+ children: [
516
+ /* @__PURE__ */ jsx(
517
+ "div",
518
+ {
519
+ className: cn(
520
+ "text-sm font-medium",
521
+ tone === "destructive" && "text-destructive",
522
+ tone === "warning" && "text-yellow-700 dark:text-yellow-400"
523
+ ),
524
+ children: title
525
+ }
526
+ ),
527
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-xs text-muted-foreground", children: message })
528
+ ]
529
+ }
530
+ );
531
+ }
532
+ function ClickyPdfPreview({ src }) {
533
+ return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md border border-border bg-background", children: [
534
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2 text-xs text-muted-foreground", children: [
535
+ /* @__PURE__ */ jsx("span", { children: "PDF preview" }),
536
+ /* @__PURE__ */ jsx("a", { href: src, target: "_blank", rel: "noreferrer", className: "text-primary hover:underline", children: "Open in new tab" })
537
+ ] }),
538
+ /* @__PURE__ */ jsx("iframe", { title: "Clicky PDF preview", src, className: "h-[720px] w-full bg-white" })
539
+ ] });
540
+ }
541
+ function ClickyHtmlPreview({ src }) {
542
+ return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md border border-border bg-background", children: [
543
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 py-2 text-xs text-muted-foreground", children: [
544
+ /* @__PURE__ */ jsx("span", { children: "HTML preview" }),
545
+ /* @__PURE__ */ jsx("a", { href: src, target: "_blank", rel: "noreferrer", className: "text-primary hover:underline", children: "Open in new tab" })
546
+ ] }),
547
+ /* @__PURE__ */ jsx(
548
+ "iframe",
549
+ {
550
+ title: "Clicky HTML preview",
551
+ src,
552
+ className: "h-[720px] w-full bg-white",
553
+ sandbox: "allow-same-origin"
554
+ }
555
+ )
556
+ ] });
557
+ }
558
+ function ClickyUnsupportedPreview({
559
+ title,
560
+ message,
561
+ href
562
+ }) {
563
+ return /* @__PURE__ */ jsx(
564
+ ClickyNotice,
565
+ {
566
+ title,
567
+ message: /* @__PURE__ */ jsxs(Fragment, { children: [
568
+ /* @__PURE__ */ jsxs("span", { children: [
569
+ message,
570
+ " "
571
+ ] }),
572
+ /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noreferrer", className: "text-primary hover:underline", children: "Open format" })
573
+ ] })
574
+ }
575
+ );
576
+ }
577
+ function ClickyRemotePreview({
578
+ format,
579
+ response
580
+ }) {
581
+ const meta = getRemoteFormatMeta(format);
582
+ if (format === "slack") {
583
+ const parsed = (response == null ? void 0 : response.kind) === "text" ? parseJsonValue(response.text) : void 0;
584
+ return /* @__PURE__ */ jsx(ClickyJsonTree, { value: parsed, emptyLabel: meta.label });
585
+ }
586
+ return /* @__PURE__ */ jsx(
587
+ ClickyTextPreview,
588
+ {
589
+ title: `${meta.label} output`,
590
+ content: (response == null ? void 0 : response.kind) === "text" ? response.text : ""
591
+ }
592
+ );
593
+ }
594
+ function ClickyTextPreview({ title, content }) {
595
+ return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md border border-border bg-background", children: [
596
+ /* @__PURE__ */ jsx("div", { className: "border-b border-border px-3 py-2 text-xs text-muted-foreground", children: title }),
597
+ /* @__PURE__ */ jsx(
598
+ "pre",
599
+ {
600
+ "aria-label": "Clicky text preview",
601
+ className: "overflow-auto whitespace-pre-wrap break-words px-3 py-3 font-mono text-xs text-foreground",
602
+ children: content || "No content"
603
+ }
604
+ )
605
+ ] });
606
+ }
607
+ function ClickyJsonTree({ value, emptyLabel = "JSON" }) {
608
+ const roots = useMemo(() => buildJsonTree(value), [value]);
609
+ if (value === void 0) {
610
+ return /* @__PURE__ */ jsx(
611
+ ClickyNotice,
612
+ {
613
+ title: `No ${emptyLabel} payload`,
614
+ message: "The response did not include a JSON body to inspect."
615
+ }
616
+ );
617
+ }
618
+ return /* @__PURE__ */ jsx(
619
+ "div",
620
+ {
621
+ "aria-label": "JSON tree",
622
+ className: "overflow-hidden rounded-md border border-border bg-background",
623
+ children: /* @__PURE__ */ jsx(
624
+ Tree,
625
+ {
626
+ roots,
627
+ className: "min-h-[12rem]",
628
+ showControls: roots.some((node) => {
629
+ var _a;
630
+ return (((_a = node.children) == null ? void 0 : _a.length) ?? 0) > 0;
631
+ }),
632
+ getKey: (node) => node.id,
633
+ getChildren: (node) => node.children,
634
+ renderRow: ({ node }) => /* @__PURE__ */ jsx(ClickyJsonTreeRow, { node }),
635
+ rowClass: () => "hover:bg-accent",
636
+ empty: /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground", children: "No JSON fields." }),
637
+ toolbarClassName: "pl-3"
638
+ }
639
+ )
640
+ }
641
+ );
642
+ }
643
+ function ClickyJsonTreeRow({ node }) {
644
+ const primitiveClass = typeof node.value === "string" ? "text-emerald-700 dark:text-emerald-400" : typeof node.value === "number" ? "text-sky-700 dark:text-sky-400" : typeof node.value === "boolean" || node.value === null ? "text-violet-700 dark:text-violet-400" : "text-muted-foreground";
645
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-2 font-mono text-xs", children: [
646
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-foreground", children: node.key }),
647
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-muted-foreground", children: ":" }),
648
+ /* @__PURE__ */ jsx("span", { className: cn("min-w-0 break-words", primitiveClass), children: node.preview })
649
+ ] });
650
+ }
651
+ function getAvailableViews({
652
+ data,
653
+ url,
654
+ view
655
+ }) {
656
+ const allowClicky = resolveViewConfigFlag(view, "clicky", data, url);
657
+ const allowJson = resolveViewConfigFlag(view, "json", data, url);
658
+ const next = [];
659
+ if (allowClicky && (url || data !== void 0)) {
660
+ next.push("clicky");
661
+ }
662
+ if (allowJson && (url || data !== void 0)) {
663
+ next.push("json");
664
+ }
665
+ for (const format of CLICKY_OVERFLOW_VIEW_FORMATS) {
666
+ if (resolveViewConfigFlag(view, format, data, url) && url) {
667
+ next.push(format);
668
+ }
669
+ }
670
+ if (next.length === 0 && (url || data !== void 0)) {
671
+ next.push("clicky");
672
+ }
673
+ return next;
674
+ }
675
+ function getDownloadFormats({
676
+ url,
677
+ download
678
+ }) {
679
+ const enabled = download ? download.all ?? true : !!url;
680
+ if (!enabled || !url) {
681
+ return [];
682
+ }
683
+ return [...CLICKY_DOWNLOAD_FORMATS];
684
+ }
685
+ function getRemoteFormatMeta(format) {
686
+ switch (format) {
687
+ case "clicky":
688
+ return {
689
+ label: "Clicky",
690
+ description: "Rendered Clicky JSON with the rich Clicky viewer",
691
+ icon: "codicon:preview",
692
+ accept: "application/json+clicky, application/clicky+json;q=0.9, application/json;q=0.8,*/*;q=0.7"
693
+ };
694
+ case "json":
695
+ return {
696
+ label: "JSON",
697
+ description: "Plain JSON for inspecting the raw response body",
698
+ icon: "vscode-icons:file-type-json",
699
+ accept: "application/json, text/plain;q=0.8,*/*;q=0.7"
700
+ };
701
+ case "pdf":
702
+ return {
703
+ label: "PDF",
704
+ description: "Portable document for sharing and printing",
705
+ icon: "vscode-icons:file-type-pdf2",
706
+ accept: "application/pdf, */*;q=0.7"
707
+ };
708
+ case "html":
709
+ return {
710
+ label: "HTML",
711
+ description: "Browser-ready HTML preview of the formatted output",
712
+ icon: "vscode-icons:file-type-html",
713
+ accept: "text/html, */*;q=0.7"
714
+ };
715
+ case "markdown":
716
+ return {
717
+ label: "Markdown",
718
+ description: "Markdown formatted for docs, comments, and chat",
719
+ icon: "vscode-icons:file-type-markdown",
720
+ accept: "text/markdown, text/plain;q=0.8,*/*;q=0.7"
721
+ };
722
+ case "yaml":
723
+ return {
724
+ label: "YAML",
725
+ description: "YAML for config-friendly inspection and export",
726
+ icon: "vscode-icons:file-type-yaml",
727
+ accept: "application/yaml, text/yaml;q=0.9, text/plain;q=0.8,*/*;q=0.7"
728
+ };
729
+ case "csv":
730
+ return {
731
+ label: "CSV",
732
+ description: "Comma-separated values for spreadsheets and imports",
733
+ icon: "codicon:table",
734
+ accept: "text/csv, text/plain;q=0.8,*/*;q=0.7"
735
+ };
736
+ case "pretty":
737
+ return {
738
+ label: "Pretty",
739
+ description: "Human-readable plain text output from the formatter",
740
+ icon: "codicon:file-code",
741
+ accept: "text/plain, */*;q=0.7"
742
+ };
743
+ case "excel":
744
+ return {
745
+ label: "Excel",
746
+ description: "Spreadsheet workbook for offline analysis",
747
+ icon: "codicon:table",
748
+ accept: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, */*;q=0.7"
749
+ };
750
+ case "slack":
751
+ return {
752
+ label: "Slack",
753
+ description: "Slack Block Kit JSON for chat-native output",
754
+ icon: "codicon:comment-discussion",
755
+ accept: "application/vnd.slack.block-kit+json, application/json;q=0.8,*/*;q=0.7"
756
+ };
757
+ }
758
+ }
759
+ function formatViewLabel(mode) {
760
+ return getRemoteFormatMeta(mode).label;
761
+ }
762
+ function buildFormatUrl(url, format) {
763
+ const base = typeof window === "undefined" ? "http://localhost" : window.location.origin;
764
+ const resolved = new URL(url, base);
765
+ resolved.searchParams.set("format", format === "clicky" ? "clicky-json" : format);
766
+ if (isAbsoluteUrl(url)) {
767
+ return resolved.toString();
768
+ }
769
+ return `${resolved.pathname}${resolved.search}${resolved.hash}`;
770
+ }
771
+ function shouldFetchRemoteView(format) {
772
+ return format !== "pdf" && format !== "html" && format !== "excel";
773
+ }
774
+ function isPrimaryViewFormat(format) {
775
+ return CLICKY_PRIMARY_VIEW_FORMATS.includes(format);
776
+ }
777
+ function isOverflowViewFormat(format) {
778
+ return CLICKY_OVERFLOW_VIEW_FORMATS.includes(format);
779
+ }
780
+ function resolveViewConfigFlag(view, format, data, url) {
781
+ const defaultEnabled = format === "clicky" || format === "json" ? url != null || data !== void 0 : !!url;
782
+ if (view === void 0) {
783
+ return defaultEnabled;
784
+ }
785
+ if (Array.isArray(view)) {
786
+ if (view.length === 0) {
787
+ return false;
788
+ }
789
+ if (format === "clicky") {
790
+ return view.includes("clicky") || view.includes("json");
791
+ }
792
+ return view.includes(format);
793
+ }
794
+ if (format in view) {
795
+ return Boolean(view[format]);
796
+ }
797
+ if (format === "clicky" && view.json === true) {
798
+ return true;
799
+ }
800
+ return defaultEnabled;
801
+ }
802
+ function parseJsonValue(data) {
803
+ if (data === void 0) {
804
+ return void 0;
805
+ }
806
+ if (typeof data !== "string") {
807
+ return data;
808
+ }
809
+ const trimmed = data.trim();
810
+ if (!trimmed) {
811
+ return "";
812
+ }
813
+ try {
814
+ return JSON.parse(trimmed);
815
+ } catch {
816
+ return data;
817
+ }
818
+ }
819
+ function buildJsonTree(value) {
820
+ if (Array.isArray(value)) {
821
+ return value.map((entry, index) => buildJsonTreeNode(String(index), entry, `$[${index}]`));
822
+ }
823
+ if (isPlainObject(value)) {
824
+ return Object.entries(value).map(([key, entry]) => buildJsonTreeNode(key, entry, `$.${key}`));
825
+ }
826
+ if (value === void 0) {
827
+ return [];
828
+ }
829
+ return [buildJsonTreeNode("$", value, "$")];
830
+ }
831
+ function buildJsonTreeNode(key, value, id) {
832
+ const children = getJsonChildren(value, id);
833
+ return {
834
+ id,
835
+ key,
836
+ value,
837
+ preview: summarizeJsonValue(value),
838
+ ...children ? { children } : {}
839
+ };
840
+ }
841
+ function getJsonChildren(value, path) {
842
+ if (Array.isArray(value)) {
843
+ return value.map(
844
+ (entry, index) => buildJsonTreeNode(String(index), entry, `${path}[${index}]`)
845
+ );
846
+ }
847
+ if (isPlainObject(value)) {
848
+ return Object.entries(value).map(
849
+ ([key, entry]) => buildJsonTreeNode(key, entry, `${path}.${key}`)
850
+ );
851
+ }
852
+ return void 0;
853
+ }
854
+ function summarizeJsonValue(value) {
855
+ if (Array.isArray(value)) {
856
+ return `[${value.length} item${value.length === 1 ? "" : "s"}]`;
857
+ }
858
+ if (isPlainObject(value)) {
859
+ const count = Object.keys(value).length;
860
+ return `{${count} key${count === 1 ? "" : "s"}}`;
861
+ }
862
+ if (typeof value === "string") {
863
+ return JSON.stringify(value);
864
+ }
865
+ if (value === void 0) {
866
+ return "undefined";
867
+ }
868
+ return String(value);
869
+ }
870
+ function isPlainObject(value) {
871
+ return value != null && typeof value === "object" && !Array.isArray(value);
872
+ }
873
+ function submitDownloadRequest(url) {
874
+ if (typeof document === "undefined") return;
875
+ const form = document.createElement("form");
876
+ form.method = "GET";
877
+ form.action = url;
878
+ form.style.display = "none";
879
+ document.body.appendChild(form);
880
+ form.submit();
881
+ document.body.removeChild(form);
882
+ }
883
+ function isAbsoluteUrl(url) {
884
+ return /^[a-z][a-z\d+\-.]*:/i.test(url) || url.startsWith("//");
885
+ }
886
+ function normalizeClickyDocument(data) {
887
+ if (!data || typeof data !== "object") {
888
+ return {
889
+ ok: false,
890
+ message: "Payload must be an object",
891
+ raw: String(data ?? "")
892
+ };
893
+ }
894
+ const candidate = data;
895
+ if ("version" in candidate && candidate.version === 1 && candidate.node && isClickyNode(candidate.node)) {
896
+ return { ok: true, document: candidate };
897
+ }
898
+ if (isClickyNode(candidate)) {
899
+ return { ok: true, document: { version: 1, node: candidate } };
900
+ }
901
+ return {
902
+ ok: false,
903
+ message: "Payload is neither a Clicky document nor a Clicky node",
904
+ raw: JSON.stringify(data, null, 2)
905
+ };
906
+ }
907
+ function isClickyNode(value) {
908
+ return !!value && typeof value === "object" && typeof value.kind === "string";
909
+ }
910
+ function ClickyNodeRenderer({ node }) {
911
+ if (!node) return null;
912
+ switch (node.kind) {
913
+ case "text":
914
+ return /* @__PURE__ */ jsx(ClickyText, { node });
915
+ case "link":
916
+ return /* @__PURE__ */ jsx(ClickyLinkNode, { node });
917
+ case "link-command":
918
+ return /* @__PURE__ */ jsx(ClickyLinkCommandNode, { node });
919
+ case "icon":
920
+ return /* @__PURE__ */ jsx(ClickyIconNode, { node });
921
+ case "list":
922
+ return /* @__PURE__ */ jsx(ClickyList, { node });
923
+ case "map":
924
+ return /* @__PURE__ */ jsx(ClickyMap, { node });
925
+ case "table":
926
+ return /* @__PURE__ */ jsx(ClickyTable, { node });
927
+ case "tree":
928
+ return /* @__PURE__ */ jsx(ClickyTreeNode, { node });
929
+ case "code":
930
+ return /* @__PURE__ */ jsx(ClickyCodeBlock, { node });
931
+ case "collapsed":
932
+ return /* @__PURE__ */ jsx(ClickyCollapsed, { node });
933
+ case "stacktrace":
934
+ return /* @__PURE__ */ jsx(ClickyStackTraceNode, { node });
935
+ case "button":
936
+ return /* @__PURE__ */ jsx(ClickyButtonNode, { node });
937
+ case "button-group":
938
+ return /* @__PURE__ */ jsx(ClickyButtonGroup, { node });
939
+ case "html":
940
+ return /* @__PURE__ */ jsx(ClickyHtmlNode, { node });
941
+ case "comment":
942
+ return /* @__PURE__ */ jsx(ClickyComment, { node });
943
+ case "badge":
944
+ return /* @__PURE__ */ jsx(ClickyBadgeNode, { node });
945
+ default:
946
+ return /* @__PURE__ */ jsx("pre", { className: "rounded-md border border-border bg-muted p-density-3 text-xs", children: JSON.stringify(node, null, 2) });
947
+ }
948
+ }
949
+ function ClickyComment({ node }) {
950
+ var _a, _b, _c, _d, _e;
951
+ const text = node.text ?? node.plain;
952
+ const content = /* @__PURE__ */ jsx(ClickyInlineContent, { node });
953
+ const maxWidth = ((_a = node.style) == null ? void 0 : _a.maxWidth) && node.style.maxWidth > 0 ? Math.min(node.style.maxWidth, 50) : 50;
954
+ const maxLines = ((_b = node.style) == null ? void 0 : _b.maxLines) && node.style.maxLines > 0 ? Math.min(node.style.maxLines, 3) : 3;
955
+ const inlineStyle = toInlineStyle(
956
+ {
957
+ ...node.style,
958
+ maxWidth,
959
+ maxLines
960
+ },
961
+ text
962
+ );
963
+ if (!text && !((_c = node.children) == null ? void 0 : _c.length)) return null;
964
+ return /* @__PURE__ */ jsx(
965
+ "div",
966
+ {
967
+ className: cn("mt-1 text-xs leading-snug text-muted-foreground", (_d = node.style) == null ? void 0 : _d.className),
968
+ style: inlineStyle,
969
+ title: ((_e = node.tooltip) == null ? void 0 : _e.plain) ?? text,
970
+ children: content
971
+ }
972
+ );
973
+ }
974
+ function ClickyText({ node }) {
975
+ var _a, _b;
976
+ const inlineStyle = toInlineStyle(node.style, node.text ?? node.plain);
977
+ const content = /* @__PURE__ */ jsx(ClickyInlineContent, { node });
978
+ if (!node.style && !node.tooltip) {
979
+ return /* @__PURE__ */ jsx(Fragment, { children: content });
980
+ }
981
+ return /* @__PURE__ */ jsx(
982
+ "span",
983
+ {
984
+ style: inlineStyle,
985
+ title: (_a = node.tooltip) == null ? void 0 : _a.plain,
986
+ className: cn(
987
+ (_b = node.style) == null ? void 0 : _b.className,
988
+ (node.text ?? "").includes("\n") && "whitespace-pre-wrap"
989
+ ),
990
+ children: content
991
+ }
992
+ );
993
+ }
994
+ function ClickyInlineContent({ node }) {
995
+ var _a;
996
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
997
+ node.text,
998
+ (_a = node.children) == null ? void 0 : _a.map((child, index) => /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: child }) }, index))
999
+ ] });
1000
+ }
1001
+ function ClickyLinkNode({ node }) {
1002
+ var _a, _b;
1003
+ const content = /* @__PURE__ */ jsx(ClickyInlineContent, { node });
1004
+ const inlineStyle = toInlineStyle(node.style, node.text ?? node.plain);
1005
+ const target = browserAnchorTarget(node.target);
1006
+ const rel = target === "_blank" ? "noopener noreferrer" : void 0;
1007
+ if (!node.href) {
1008
+ return /* @__PURE__ */ jsx("span", { style: inlineStyle, children: content });
1009
+ }
1010
+ return /* @__PURE__ */ jsx(
1011
+ "a",
1012
+ {
1013
+ href: node.href,
1014
+ target,
1015
+ rel,
1016
+ title: (_a = node.tooltip) == null ? void 0 : _a.plain,
1017
+ style: inlineStyle,
1018
+ className: cn((_b = node.style) == null ? void 0 : _b.className, "inline cursor-pointer"),
1019
+ children: content
1020
+ }
1021
+ );
1022
+ }
1023
+ function ClickyLinkCommandNode({ node }) {
1024
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1025
+ const runtime = useContext(ClickyRuntimeContext);
1026
+ const request = useMemo(() => clickyNodeToCommandRequest(node), [node]);
1027
+ const resolved = useMemo(
1028
+ () => resolveClickyCommand(request, runtime.commandRuntime, runtime.operations),
1029
+ [request, runtime.commandRuntime, runtime.operations]
1030
+ );
1031
+ const target = request.target ?? "Dialog";
1032
+ const hasRuntime = runtime.commandRuntime != null;
1033
+ const [dialogOpen, setDialogOpen] = useState(false);
1034
+ const [expanded, setExpanded] = useState(false);
1035
+ if (!hasRuntime) {
1036
+ return /* @__PURE__ */ jsx("span", { title: (_a = node.tooltip) == null ? void 0 : _a.plain, className: cn((_b = node.style) == null ? void 0 : _b.className), children: /* @__PURE__ */ jsx(ClickyInlineContent, { node }) });
1037
+ }
1038
+ if (target === "_self" || target === "_window" || target === "_tab") {
1039
+ const href = ((_d = (_c = runtime.commandRuntime) == null ? void 0 : _c.hrefForCommand) == null ? void 0 : _d.call(_c, resolved)) ?? buildCommandExecutionHref(resolved);
1040
+ if (!href) {
1041
+ return /* @__PURE__ */ jsx("span", { title: (_e = node.tooltip) == null ? void 0 : _e.plain, className: cn((_f = node.style) == null ? void 0 : _f.className), children: /* @__PURE__ */ jsx(ClickyInlineContent, { node }) });
1042
+ }
1043
+ return /* @__PURE__ */ jsx(
1044
+ "a",
1045
+ {
1046
+ href,
1047
+ target: browserAnchorTarget(target),
1048
+ rel: target === "_self" ? void 0 : "noopener noreferrer",
1049
+ title: (_g = node.tooltip) == null ? void 0 : _g.plain,
1050
+ style: toInlineStyle(node.style, node.text ?? node.plain),
1051
+ className: cn((_h = node.style) == null ? void 0 : _h.className, "inline cursor-pointer"),
1052
+ children: /* @__PURE__ */ jsx(ClickyInlineContent, { node })
1053
+ }
1054
+ );
1055
+ }
1056
+ if (target === "_clicky") {
1057
+ return /* @__PURE__ */ jsx(
1058
+ ClickyLinkCommandTrigger,
1059
+ {
1060
+ node,
1061
+ onClick: () => {
1062
+ var _a2, _b2;
1063
+ return (_b2 = (_a2 = runtime.commandRuntime) == null ? void 0 : _a2.onNavigate) == null ? void 0 : _b2.call(_a2, resolved);
1064
+ }
1065
+ }
1066
+ );
1067
+ }
1068
+ if (target === "Hover") {
1069
+ return /* @__PURE__ */ jsx(
1070
+ HoverCard,
1071
+ {
1072
+ delay: 75,
1073
+ cardClassName: "w-[28rem] max-w-[calc(100vw-2rem)] whitespace-normal p-0",
1074
+ trigger: /* @__PURE__ */ jsx(ClickyLinkCommandTrigger, { node }),
1075
+ children: /* @__PURE__ */ jsx("div", { className: "max-h-[26rem] overflow-auto p-density-3", children: /* @__PURE__ */ jsx(ClickyAsyncCommandResult, { resolved }) })
1076
+ }
1077
+ );
1078
+ }
1079
+ if (target === "Expand") {
1080
+ return /* @__PURE__ */ jsxs("span", { className: "inline", children: [
1081
+ /* @__PURE__ */ jsx(
1082
+ ClickyLinkCommandTrigger,
1083
+ {
1084
+ node,
1085
+ ariaExpanded: expanded,
1086
+ onClick: () => setExpanded((current) => !current)
1087
+ }
1088
+ ),
1089
+ expanded && /* @__PURE__ */ jsx("div", { className: "mt-2 rounded-md border border-border bg-background p-density-3", children: /* @__PURE__ */ jsx(ClickyAsyncCommandResult, { resolved }) })
1090
+ ] });
1091
+ }
1092
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1093
+ /* @__PURE__ */ jsx(
1094
+ ClickyLinkCommandTrigger,
1095
+ {
1096
+ node,
1097
+ ariaExpanded: dialogOpen,
1098
+ onClick: () => setDialogOpen(true)
1099
+ }
1100
+ ),
1101
+ /* @__PURE__ */ jsx(
1102
+ ClickyCommandDialog,
1103
+ {
1104
+ open: dialogOpen,
1105
+ onClose: () => setDialogOpen(false),
1106
+ resolved
1107
+ }
1108
+ )
1109
+ ] });
1110
+ }
1111
+ function ClickyLinkCommandTrigger({
1112
+ node,
1113
+ onClick,
1114
+ ariaExpanded
1115
+ }) {
1116
+ var _a, _b;
1117
+ const inlineStyle = toInlineStyle(node.style, node.text ?? node.plain);
1118
+ const handleClick = (event) => {
1119
+ event.preventDefault();
1120
+ onClick == null ? void 0 : onClick();
1121
+ };
1122
+ return /* @__PURE__ */ jsx(
1123
+ "button",
1124
+ {
1125
+ type: "button",
1126
+ title: (_a = node.tooltip) == null ? void 0 : _a.plain,
1127
+ "aria-expanded": ariaExpanded,
1128
+ onClick: handleClick,
1129
+ style: inlineStyle,
1130
+ className: cn(
1131
+ "inline cursor-pointer appearance-none border-0 bg-transparent p-0 text-left align-baseline text-inherit",
1132
+ (_b = node.style) == null ? void 0 : _b.className
1133
+ ),
1134
+ children: /* @__PURE__ */ jsx(ClickyInlineContent, { node })
1135
+ }
1136
+ );
1137
+ }
1138
+ function ClickyCommandDialog({
1139
+ open,
1140
+ onClose,
1141
+ resolved
1142
+ }) {
1143
+ const runtime = useContext(ClickyRuntimeContext);
1144
+ const operation = resolved.operation;
1145
+ const parameters = (operation == null ? void 0 : operation.operation.parameters) ?? [];
1146
+ const initialValues = useMemo(
1147
+ () => buildCommandParameterValues(parameters, resolved.request),
1148
+ [parameters, resolved.request]
1149
+ );
1150
+ const [result, setResult] = useState(null);
1151
+ const [error, setError] = useState("");
1152
+ const [isExecuting, setIsExecuting] = useState(false);
1153
+ const [hasAutoStarted, setHasAutoStarted] = useState(false);
1154
+ const shouldAutoRun = open && resolved.request.autoRun === true && operation != null && missingRequiredParameters(parameters, initialValues).length === 0;
1155
+ useEffect(() => {
1156
+ if (!open) {
1157
+ setHasAutoStarted(false);
1158
+ setResult(null);
1159
+ setError("");
1160
+ }
1161
+ }, [open, resolved.request.command]);
1162
+ async function runCommand(values) {
1163
+ if (!runtime.commandRuntime || !operation) {
1164
+ return;
1165
+ }
1166
+ setIsExecuting(true);
1167
+ setError("");
1168
+ try {
1169
+ const response = await executeClickyCommand(runtime.commandRuntime.client, operation, values);
1170
+ setResult(response);
1171
+ } catch (err) {
1172
+ setResult(null);
1173
+ setError(err instanceof Error ? err.message : String(err ?? "Unknown error"));
1174
+ } finally {
1175
+ setIsExecuting(false);
1176
+ }
1177
+ }
1178
+ useEffect(() => {
1179
+ if (!shouldAutoRun || hasAutoStarted) {
1180
+ return;
1181
+ }
1182
+ setHasAutoStarted(true);
1183
+ void runCommand(initialValues);
1184
+ }, [hasAutoStarted, initialValues, shouldAutoRun]);
1185
+ return /* @__PURE__ */ jsx(
1186
+ Modal,
1187
+ {
1188
+ open,
1189
+ onClose,
1190
+ title: (operation == null ? void 0 : operation.operation.summary) || resolved.request.command,
1191
+ size: "xl",
1192
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1193
+ operation ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3 text-xs text-muted-foreground", children: [
1194
+ /* @__PURE__ */ jsx("span", { className: "rounded-md border border-border bg-muted px-2 py-1 font-medium uppercase", children: operation.method }),
1195
+ /* @__PURE__ */ jsx("code", { children: operation.path })
1196
+ ] }) : runtime.operationsLoading ? /* @__PURE__ */ jsx(ClickyNotice, { title: "Loading commands", message: "Resolving the command definition." }) : /* @__PURE__ */ jsx(
1197
+ ClickyNotice,
1198
+ {
1199
+ title: "Unknown command",
1200
+ message: `No operation matched "${resolved.request.command}".`,
1201
+ tone: "destructive"
1202
+ }
1203
+ ),
1204
+ operation && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-border bg-muted/20 p-density-3", children: /* @__PURE__ */ jsx(
1205
+ FilterForm,
1206
+ {
1207
+ client: runtime.commandRuntime.client,
1208
+ path: operation.path,
1209
+ method: operation.method,
1210
+ parameters,
1211
+ initialValues,
1212
+ isSubmitting: isExecuting,
1213
+ submitLabel: "Run command",
1214
+ submittingLabel: "Running…",
1215
+ onSubmit: runCommand
1216
+ }
1217
+ ) }),
1218
+ error ? /* @__PURE__ */ jsx(ClickyNotice, { title: "Command failed", message: error, tone: "destructive" }) : /* @__PURE__ */ jsx(
1219
+ ClickyCommandResponse,
1220
+ {
1221
+ response: result,
1222
+ pending: isExecuting,
1223
+ emptyMessage: "Run the command to load a Clicky response."
1224
+ }
1225
+ )
1226
+ ] })
1227
+ }
1228
+ );
1229
+ }
1230
+ function ClickyAsyncCommandResult({ resolved }) {
1231
+ const runtime = useContext(ClickyRuntimeContext);
1232
+ const operation = resolved.operation;
1233
+ const parameters = (operation == null ? void 0 : operation.operation.parameters) ?? [];
1234
+ const initialValues = useMemo(
1235
+ () => buildCommandParameterValues(parameters, resolved.request),
1236
+ [parameters, resolved.request]
1237
+ );
1238
+ const missing = useMemo(
1239
+ () => missingRequiredParameters(parameters, initialValues),
1240
+ [initialValues, parameters]
1241
+ );
1242
+ const query = useQuery({
1243
+ queryKey: [
1244
+ "clicky-command",
1245
+ resolved.request.command,
1246
+ operation == null ? void 0 : operation.method,
1247
+ operation == null ? void 0 : operation.path,
1248
+ initialValues
1249
+ ],
1250
+ enabled: runtime.commandRuntime != null && operation != null && missing.length === 0,
1251
+ retry: 0,
1252
+ queryFn: async () => executeClickyCommand(runtime.commandRuntime.client, operation, initialValues)
1253
+ });
1254
+ if (!runtime.commandRuntime) {
1255
+ return /* @__PURE__ */ jsx(
1256
+ ClickyNotice,
1257
+ {
1258
+ title: "Command runtime unavailable",
1259
+ message: "This Clicky view was rendered without a command runtime.",
1260
+ tone: "warning"
1261
+ }
1262
+ );
1263
+ }
1264
+ if (!operation) {
1265
+ if (runtime.operationsLoading) {
1266
+ return /* @__PURE__ */ jsx(ClickyNotice, { title: "Loading commands", message: "Resolving the command definition." });
1267
+ }
1268
+ return /* @__PURE__ */ jsx(
1269
+ ClickyNotice,
1270
+ {
1271
+ title: "Unknown command",
1272
+ message: `No operation matched "${resolved.request.command}".`,
1273
+ tone: "destructive"
1274
+ }
1275
+ );
1276
+ }
1277
+ if (missing.length > 0) {
1278
+ return /* @__PURE__ */ jsx(
1279
+ ClickyNotice,
1280
+ {
1281
+ title: "Missing required parameters",
1282
+ message: `This link is missing: ${missing.map((param) => prettifyName(param.name)).join(", ")}.`,
1283
+ tone: "warning"
1284
+ }
1285
+ );
1286
+ }
1287
+ if (query.isPending) {
1288
+ return /* @__PURE__ */ jsx(ClickyNotice, { title: "Running command", message: "Loading Clicky response…" });
1289
+ }
1290
+ if (query.isError) {
1291
+ return /* @__PURE__ */ jsx(
1292
+ ClickyNotice,
1293
+ {
1294
+ title: "Command failed",
1295
+ message: query.error instanceof Error ? query.error.message : "Request failed",
1296
+ tone: "destructive"
1297
+ }
1298
+ );
1299
+ }
1300
+ return /* @__PURE__ */ jsx(ClickyCommandResponse, { response: query.data, emptyMessage: "No response body returned." });
1301
+ }
1302
+ function ClickyCommandResponse({
1303
+ response,
1304
+ pending = false,
1305
+ emptyMessage
1306
+ }) {
1307
+ if (pending) {
1308
+ return /* @__PURE__ */ jsx(ClickyNotice, { title: "Running command", message: "Loading Clicky response…" });
1309
+ }
1310
+ if (!response) {
1311
+ return /* @__PURE__ */ jsx(ClickyNotice, { title: "No response", message: emptyMessage });
1312
+ }
1313
+ const parsedPayload = isExecutionResponse(response) ? response.parsed ?? parseJsonBody(response) : response;
1314
+ const rawText = isExecutionResponse(response) ? response.stdout || response.output || response.message || "" : typeof response === "string" ? response : JSON.stringify(response, null, 2);
1315
+ const clickyPayload = typeof parsedPayload === "string" || parsedPayload != null && typeof parsedPayload === "object" ? parsedPayload : rawText;
1316
+ const parsedClicky = clickyPayload === "" ? null : parseClickyData(clickyPayload);
1317
+ if (parsedClicky == null ? void 0 : parsedClicky.ok) {
1318
+ return /* @__PURE__ */ jsx("div", { className: "rounded-md border border-border bg-background p-density-3", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: parsedClicky.document.node }) });
1319
+ }
1320
+ if (parsedPayload != null && typeof parsedPayload === "object") {
1321
+ return /* @__PURE__ */ jsx(ClickyJsonTree, { value: parsedPayload });
1322
+ }
1323
+ return /* @__PURE__ */ jsx(ClickyTextPreview, { title: "Response body", content: rawText });
1324
+ }
1325
+ function ClickyIconNode({ node }) {
1326
+ var _a;
1327
+ const inlineStyle = toInlineStyle(node.style, node.plain ?? node.unicode);
1328
+ return /* @__PURE__ */ jsx("span", { style: inlineStyle, title: (_a = node.tooltip) == null ? void 0 : _a.plain, className: "inline-flex items-center", children: node.iconify ? /* @__PURE__ */ jsx(Icon, { name: node.iconify }) : /* @__PURE__ */ jsx("span", { children: node.unicode ?? node.plain }) });
1329
+ }
1330
+ function ClickyList({ node }) {
1331
+ const items = node.items ?? [];
1332
+ if (items.length === 0) return null;
1333
+ if (node.inline) {
1334
+ return /* @__PURE__ */ jsx("span", { className: "inline-flex flex-wrap items-start gap-1", children: items.map((item, index) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
1335
+ index > 0 && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "," }),
1336
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
1337
+ !node.ordered && node.bullet && /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: node.bullet }),
1338
+ node.ordered && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
1339
+ index + 1,
1340
+ "."
1341
+ ] }),
1342
+ /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: item })
1343
+ ] })
1344
+ ] }, index)) });
1345
+ }
1346
+ if (node.unstyled) {
1347
+ return /* @__PURE__ */ jsx("div", { className: "space-y-1", children: items.map((item, index) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
1348
+ !node.ordered && node.bullet && /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: node.bullet }),
1349
+ node.ordered && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
1350
+ index + 1,
1351
+ "."
1352
+ ] }),
1353
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: item }) })
1354
+ ] }, index)) });
1355
+ }
1356
+ const Tag = node.ordered ? "ol" : "ul";
1357
+ const listClass = node.ordered ? "list-decimal" : "list-disc";
1358
+ return /* @__PURE__ */ jsx(Tag, { className: cn("ml-5 space-y-1 text-sm", listClass), children: items.map((item, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: item }) }, index)) });
1359
+ }
1360
+ function ClickyMap({ node }) {
1361
+ const fields = node.fields ?? [];
1362
+ if (fields.length === 0) return null;
1363
+ const inlineFields = fields.filter((field) => isInlineNode(field.value));
1364
+ const blockFields = fields.filter((field) => !isInlineNode(field.value));
1365
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-density-4", children: [
1366
+ inlineFields.length > 0 && /* @__PURE__ */ jsx("dl", { className: "grid gap-density-3 md:grid-cols-2", children: inlineFields.map((field) => /* @__PURE__ */ jsxs("div", { children: [
1367
+ /* @__PURE__ */ jsx("dt", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: field.label || prettifyName(field.name) }),
1368
+ /* @__PURE__ */ jsx("dd", { className: "mt-1 text-sm text-foreground", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: field.value }) })
1369
+ ] }, field.name)) }),
1370
+ blockFields.map((field) => /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
1371
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: field.label || prettifyName(field.name) }),
1372
+ /* @__PURE__ */ jsx("div", { className: "rounded-md border border-border bg-background p-density-3", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: field.value }) })
1373
+ ] }, field.name))
1374
+ ] });
1375
+ }
1376
+ function ClickyTable({ node }) {
1377
+ const runtime = useContext(ClickyRuntimeContext);
1378
+ const columns = node.columns ?? [];
1379
+ const rows = node.rows ?? [];
1380
+ if (columns.length === 0 || rows.length === 0) {
1381
+ return /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: "No data" });
1382
+ }
1383
+ if (shouldRenderRowsAsCollapsedStructs(columns, rows)) {
1384
+ return /* @__PURE__ */ jsx(ClickyCollapsedStructRows, { columns, rows });
1385
+ }
1386
+ const tableColumns = columns.map((column) => {
1387
+ const tagColumn = isClickyTagColumn(column);
1388
+ const base = {
1389
+ key: `cells.${column.name}`,
1390
+ label: column.header ? /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: column.header }) : column.label || prettifyName(column.name),
1391
+ ...column.align ? { align: column.align } : {},
1392
+ ...column.sortable !== void 0 ? { sortable: column.sortable } : {},
1393
+ ...column.filterable !== void 0 ? { filterable: column.filterable } : {},
1394
+ ...column.grow !== void 0 ? { grow: column.grow } : {},
1395
+ ...column.shrink !== void 0 ? { shrink: column.shrink } : {}
1396
+ };
1397
+ if (tagColumn) {
1398
+ return {
1399
+ ...base,
1400
+ kind: "tags",
1401
+ render: (value) => {
1402
+ const tags = clickyNodeTags(value, column);
1403
+ return /* @__PURE__ */ jsx(TagList, { tags, maxVisible: 3 });
1404
+ },
1405
+ sortValue: (value) => clickyNodeTags(value, column).length,
1406
+ filterValue: (value) => clickyNodeTags(value, column).map((tag) => tag.token)
1407
+ };
1408
+ }
1409
+ return {
1410
+ ...base,
1411
+ ...column.kind ? { kind: column.kind } : {},
1412
+ render: (value) => /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: value }),
1413
+ sortValue: (value) => clickyNodeText(value),
1414
+ filterValue: (value) => clickyNodeText(value)
1415
+ };
1416
+ });
1417
+ const defaultSortColumn = columns.find((column) => column.sortable !== false) ?? columns[0];
1418
+ return /* @__PURE__ */ jsx(
1419
+ DataTable,
1420
+ {
1421
+ data: rows,
1422
+ columns: tableColumns,
1423
+ ...node.autoFilter !== void 0 ? { autoFilter: node.autoFilter } : {},
1424
+ ...defaultSortColumn ? { defaultSort: { key: `cells.${defaultSortColumn.name}`, dir: "asc" } } : {},
1425
+ getRowId: (row, index) => `${index}-${columns.map((column) => clickyNodeText(row.cells[column.name])).filter(Boolean).join("|")}`,
1426
+ renderExpandedRow: (row, context) => /* @__PURE__ */ jsx(ClickyTableRowDetail, { row, columns, context }),
1427
+ ...runtime.onTableRowClick ? { onRowClick: runtime.onTableRowClick } : {},
1428
+ ...runtime.getTableRowHref ? { getRowHref: runtime.getTableRowHref } : {},
1429
+ ...runtime.onTableRowClick && (runtime.isTableRowClickable || runtime.getTableRowHref) ? {
1430
+ isRowClickable: runtime.isTableRowClickable ?? ((row) => {
1431
+ var _a;
1432
+ return Boolean((_a = runtime.getTableRowHref) == null ? void 0 : _a.call(runtime, row));
1433
+ })
1434
+ } : {}
1435
+ }
1436
+ );
1437
+ }
1438
+ function ClickyTableRowDetail({
1439
+ row,
1440
+ columns,
1441
+ context
1442
+ }) {
1443
+ const tagFields = columns.map((column) => ({
1444
+ column,
1445
+ tags: clickyNodeTags(row.cells[column.name], column),
1446
+ tableKey: `cells.${column.name}`
1447
+ })).filter((field) => field.tags.length > 0);
1448
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
1449
+ tagFields.length > 0 && /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
1450
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Tags" }),
1451
+ /* @__PURE__ */ jsx("div", { className: "grid gap-2", children: tagFields.map(({ column, tags, tableKey }) => {
1452
+ const tagActions = context.tagActionsByColumn[tableKey];
1453
+ const content = /* @__PURE__ */ jsx(TagList, { tags, maxVisible: tags.length, actions: "inline" });
1454
+ return /* @__PURE__ */ jsxs(
1455
+ "div",
1456
+ {
1457
+ className: "grid gap-2 rounded-md border border-border bg-background p-2 md:grid-cols-[9rem_minmax(0,1fr)]",
1458
+ children: [
1459
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: column.label || prettifyName(column.name) }),
1460
+ /* @__PURE__ */ jsx("div", { className: "min-w-0", children: tagActions ? /* @__PURE__ */ jsx(TagActionsProvider, { value: tagActions, children: content }) : content })
1461
+ ]
1462
+ },
1463
+ column.name
1464
+ );
1465
+ }) })
1466
+ ] }),
1467
+ /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
1468
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Fields" }),
1469
+ /* @__PURE__ */ jsx("dl", { className: "grid gap-2 md:grid-cols-2", children: columns.map((column) => /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border bg-background p-2", children: [
1470
+ /* @__PURE__ */ jsx("dt", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: column.label || prettifyName(column.name) }),
1471
+ /* @__PURE__ */ jsx("dd", { className: "mt-1 min-w-0 text-sm text-foreground", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: row.cells[column.name] }) })
1472
+ ] }, column.name)) })
1473
+ ] }),
1474
+ row.detail && /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
1475
+ /* @__PURE__ */ jsx("div", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Detail" }),
1476
+ /* @__PURE__ */ jsx("div", { className: "rounded-md border border-border bg-background p-density-3", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: row.detail }) })
1477
+ ] })
1478
+ ] });
1479
+ }
1480
+ function ClickyCollapsedStructRows({
1481
+ columns,
1482
+ rows
1483
+ }) {
1484
+ return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: rows.map((row, index) => {
1485
+ const label = rowStructLabel(row, columns, index);
1486
+ const content = rowAsMap(row, columns);
1487
+ return /* @__PURE__ */ jsxs(
1488
+ "details",
1489
+ {
1490
+ className: "rounded-md border border-border bg-background",
1491
+ children: [
1492
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer px-3 py-2 text-sm font-medium text-foreground", children: label }),
1493
+ /* @__PURE__ */ jsx("div", { className: "border-t border-border p-3", children: /* @__PURE__ */ jsx(ClickyMap, { node: content }) })
1494
+ ]
1495
+ },
1496
+ rowStructKey(row, columns, index)
1497
+ );
1498
+ }) });
1499
+ }
1500
+ function shouldRenderRowsAsCollapsedStructs(columns, rows) {
1501
+ if (rows.length === 0) return false;
1502
+ return rows.every((row) => {
1503
+ const cells = columns.map((column) => row.cells[column.name]).filter(Boolean);
1504
+ if (cells.length === 0) return false;
1505
+ const complexCells = cells.filter(isStructCellNode);
1506
+ return complexCells.length > 0 && complexCells.length === cells.length;
1507
+ });
1508
+ }
1509
+ function isClickyTagColumn(column) {
1510
+ if (column.kind === "tags") return true;
1511
+ const normalized = column.name.toLowerCase();
1512
+ return /(^|[._-])(tags?|labels?|annotations?)$/.test(normalized);
1513
+ }
1514
+ function clickyNodeTags(node, column) {
1515
+ if (!isClickyTagColumn(column)) return [];
1516
+ const value = clickyNodeTagsValue(node);
1517
+ return normalizeTags(value);
1518
+ }
1519
+ function clickyNodeTagsValue(node) {
1520
+ var _a, _b;
1521
+ if (!node) return [];
1522
+ if (node.kind === "map" && ((_a = node.fields) == null ? void 0 : _a.length)) {
1523
+ return Object.fromEntries(
1524
+ node.fields.map((field) => [field.name, clickyNodeText(field.value)]).filter(([, value]) => value.trim() !== "")
1525
+ );
1526
+ }
1527
+ if (node.kind === "list" && ((_b = node.items) == null ? void 0 : _b.length)) {
1528
+ return node.items.map((item) => clickyNodeText(item)).filter(Boolean);
1529
+ }
1530
+ const text = clickyNodeText(node).trim();
1531
+ if (!text) return [];
1532
+ return text.split(/[,\s]+/).map((value) => value.trim()).filter(Boolean);
1533
+ }
1534
+ function isStructCellNode(node) {
1535
+ if (!node) return false;
1536
+ if (node.kind === "map") return (node.fields ?? []).length > 0;
1537
+ if (node.kind === "table") return (node.rows ?? []).length > 0;
1538
+ if (node.kind !== "list") return false;
1539
+ const items = node.items ?? [];
1540
+ return items.length > 0 && items.every(isStructCellNode);
1541
+ }
1542
+ function rowAsMap(row, columns) {
1543
+ return {
1544
+ kind: "map",
1545
+ fields: columns.flatMap((column) => {
1546
+ const value = row.cells[column.name];
1547
+ if (!value) return [];
1548
+ return [
1549
+ {
1550
+ name: column.name,
1551
+ label: clickyNodeText(column.header) || column.label || prettifyName(column.name),
1552
+ value
1553
+ }
1554
+ ];
1555
+ })
1556
+ };
1557
+ }
1558
+ function rowStructLabel(row, columns, index) {
1559
+ var _a, _b, _c;
1560
+ const entityLabel = singularizeLabel(
1561
+ ((_a = columns.find((column) => hasMeaningfulText(row.cells[column.name]))) == null ? void 0 : _a.label) ?? ((_b = columns[0]) == null ? void 0 : _b.label) ?? ((_c = columns[0]) == null ? void 0 : _c.name) ?? "Item"
1562
+ );
1563
+ const title = rowTitle(row, columns);
1564
+ return title ? `${entityLabel} ${index + 1}: ${title}` : `${entityLabel} ${index + 1}`;
1565
+ }
1566
+ function rowStructKey(row, columns, index) {
1567
+ const title = rowTitle(row, columns);
1568
+ return `${index}-${title || columns.map((column) => clickyNodeText(row.cells[column.name])).join("|")}`;
1569
+ }
1570
+ function rowTitle(row, columns) {
1571
+ const preferredFieldNames = [
1572
+ "name",
1573
+ "title",
1574
+ "agreementname",
1575
+ "companyname",
1576
+ "customernumber",
1577
+ "id",
1578
+ "guid"
1579
+ ];
1580
+ for (const preferred of preferredFieldNames) {
1581
+ for (const column of columns) {
1582
+ const candidate = findFieldText(row.cells[column.name], preferred);
1583
+ if (candidate) return candidate;
1584
+ }
1585
+ }
1586
+ for (const column of columns) {
1587
+ const candidate = clickyNodeText(row.cells[column.name]).trim();
1588
+ if (candidate) return candidate;
1589
+ }
1590
+ return "";
1591
+ }
1592
+ function findFieldText(node, preferredName) {
1593
+ if (!node) return "";
1594
+ if (node.kind === "map") {
1595
+ for (const field of node.fields ?? []) {
1596
+ if (normalizeFieldName(field.name) === preferredName) {
1597
+ const text = clickyNodeText(field.value).trim();
1598
+ if (text) return text;
1599
+ }
1600
+ }
1601
+ }
1602
+ for (const field of node.fields ?? []) {
1603
+ const text = findFieldText(field.value, preferredName);
1604
+ if (text) return text;
1605
+ }
1606
+ for (const item of node.items ?? []) {
1607
+ const text = findFieldText(item, preferredName);
1608
+ if (text) return text;
1609
+ }
1610
+ return "";
1611
+ }
1612
+ function hasMeaningfulText(node) {
1613
+ return Boolean(clickyNodeText(node).trim() || ((node == null ? void 0 : node.fields) ?? []).length > 0);
1614
+ }
1615
+ function normalizeFieldName(name) {
1616
+ return name.toLowerCase().replace(/[^a-z0-9]/g, "");
1617
+ }
1618
+ function singularizeLabel(label) {
1619
+ const normalized = prettifyName(label).trim();
1620
+ return normalized.endsWith("s") ? normalized.slice(0, -1) : normalized;
1621
+ }
1622
+ function ClickyTreeNode({ node }) {
1623
+ const roots = node.roots ?? [];
1624
+ if (roots.length === 0) return null;
1625
+ return /* @__PURE__ */ jsx(
1626
+ Tree,
1627
+ {
1628
+ roots,
1629
+ getChildren: (item) => item.children,
1630
+ getKey: (item) => item.id,
1631
+ defaultOpen: (_, depth) => depth < 1,
1632
+ renderRow: ({ node: item }) => /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 truncate", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: item.label }) })
1633
+ }
1634
+ );
1635
+ }
1636
+ function ClickyCodeBlock({ node }) {
1637
+ const language = (node.language ?? "").toLowerCase().replace(/^\.+/, "");
1638
+ const source = node.source ?? node.plain ?? "";
1639
+ const chromaHtml = node.highlightedHtml ? sanitizeHtml(node.highlightedHtml) : "";
1640
+ const parsedJson = useMemo(
1641
+ () => language === "json" ? tryParseJson(source) : JSON_PARSE_FAILED,
1642
+ [language, source]
1643
+ );
1644
+ const [shikiHtml, setShikiHtml] = useState(null);
1645
+ const wantsClientHighlight = !chromaHtml && !!language && !!source;
1646
+ useEffect(() => {
1647
+ if (!wantsClientHighlight) {
1648
+ setShikiHtml(null);
1649
+ return;
1650
+ }
1651
+ let cancelled = false;
1652
+ highlightCode(source, { lang: language }).then((out) => {
1653
+ if (!cancelled) setShikiHtml(out);
1654
+ });
1655
+ return () => {
1656
+ cancelled = true;
1657
+ };
1658
+ }, [wantsClientHighlight, language, source]);
1659
+ if (parsedJson !== JSON_PARSE_FAILED) {
1660
+ return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md border border-border bg-muted/40", children: [
1661
+ /* @__PURE__ */ jsx("div", { className: "border-b border-border px-3 py-1.5 text-[11px] uppercase tracking-wide text-muted-foreground", children: "json" }),
1662
+ /* @__PURE__ */ jsx("div", { className: "overflow-auto p-3 text-xs", children: /* @__PURE__ */ jsx(JsonView, { data: parsedJson, defaultOpenDepth: 2 }) })
1663
+ ] });
1664
+ }
1665
+ const xmlClasses = language === "xml" || language === "xslt" || language === "html" ? " [&_.chroma_.nt]:text-pink-700 [&_.chroma_.nt]:dark:text-pink-300 [&_.chroma_.nt]:font-semibold [&_.chroma_.na]:text-amber-700 [&_.chroma_.na]:dark:text-amber-300 [&_.chroma_.s]:text-emerald-700 [&_.chroma_.s]:dark:text-emerald-300 [&_.chroma_.c]:text-slate-500 [&_.chroma_.c]:italic [&_.chroma_.cp]:text-slate-500 [&_.chroma_.cp]:italic [&_pre]:leading-relaxed" : "";
1666
+ return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md border border-border bg-muted/40", children: [
1667
+ /* @__PURE__ */ jsx("div", { className: "border-b border-border px-3 py-1.5 text-[11px] uppercase tracking-wide text-muted-foreground", children: node.language || "text" }),
1668
+ chromaHtml ? /* @__PURE__ */ jsx(
1669
+ "div",
1670
+ {
1671
+ className: "overflow-auto p-3 text-xs font-mono [&_.chroma]:bg-transparent [&_pre]:m-0 [&_pre]:whitespace-pre-wrap [&_pre]:bg-transparent" + xmlClasses,
1672
+ dangerouslySetInnerHTML: { __html: chromaHtml }
1673
+ }
1674
+ ) : shikiHtml ? /* @__PURE__ */ jsx(
1675
+ "div",
1676
+ {
1677
+ className: "overflow-auto p-3 text-xs font-mono [&_pre]:m-0 [&_pre.shiki]:!bg-transparent [&_pre]:whitespace-pre-wrap",
1678
+ dangerouslySetInnerHTML: { __html: shikiHtml }
1679
+ }
1680
+ ) : /* @__PURE__ */ jsx("pre", { className: "overflow-auto whitespace-pre-wrap break-words p-3 text-xs font-mono text-foreground", children: source })
1681
+ ] });
1682
+ }
1683
+ const JSON_PARSE_FAILED = Symbol("json-parse-failed");
1684
+ function tryParseJson(source) {
1685
+ const trimmed = source.trim();
1686
+ if (!trimmed) return JSON_PARSE_FAILED;
1687
+ try {
1688
+ return JSON.parse(trimmed);
1689
+ } catch {
1690
+ return JSON_PARSE_FAILED;
1691
+ }
1692
+ }
1693
+ function isBadgeShape(value) {
1694
+ return value === "pill" || value === "rounded" || value === "square";
1695
+ }
1696
+ function ClickyBadgeNode({ node }) {
1697
+ const props = { variant: "label" };
1698
+ if (node.badgeLabel !== void 0) props.label = node.badgeLabel;
1699
+ if (node.badgeValue !== void 0) props.value = node.badgeValue;
1700
+ if (node.badgeColor !== void 0) props.color = node.badgeColor;
1701
+ if (node.badgeText !== void 0) props.textColor = node.badgeText;
1702
+ if (node.badgeIcon !== void 0) props.icon = node.badgeIcon;
1703
+ if (isBadgeShape(node.badgeShape)) props.shape = node.badgeShape;
1704
+ return /* @__PURE__ */ jsx(Badge, { ...props });
1705
+ }
1706
+ function ClickyStackTraceNode({ node }) {
1707
+ const input = {
1708
+ causedBy: node.causedBy ?? [],
1709
+ frames: node.frames ?? [],
1710
+ language: "java",
1711
+ ...node.exceptionClass !== void 0 ? { exceptionClass: node.exceptionClass } : {},
1712
+ ...node.message !== void 0 ? { message: node.message } : {}
1713
+ };
1714
+ return /* @__PURE__ */ jsx(StackTrace, { input, className: "space-y-1" });
1715
+ }
1716
+ function ClickyCollapsed({ node }) {
1717
+ return /* @__PURE__ */ jsxs("details", { className: "rounded-md border border-border bg-background", children: [
1718
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer px-3 py-2 text-sm font-medium text-foreground", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: node.label }) }),
1719
+ node.content && /* @__PURE__ */ jsx("div", { className: "border-t border-border px-3 py-3", children: /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: node.content }) })
1720
+ ] });
1721
+ }
1722
+ function ClickyButtonNode({ node }) {
1723
+ const title = [node.id, node.payload].filter(Boolean).join("\n") || void 0;
1724
+ const content = node.label ? /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: node.label }) : node.text;
1725
+ if (node.href) {
1726
+ return /* @__PURE__ */ jsx(
1727
+ "a",
1728
+ {
1729
+ href: node.href,
1730
+ target: "_blank",
1731
+ rel: "noopener noreferrer",
1732
+ title,
1733
+ className: "inline-flex items-center rounded-md border border-border bg-background px-3 py-1.5 text-sm font-medium text-foreground hover:bg-accent",
1734
+ children: content
1735
+ }
1736
+ );
1737
+ }
1738
+ return /* @__PURE__ */ jsx(
1739
+ "button",
1740
+ {
1741
+ type: "button",
1742
+ title,
1743
+ className: "inline-flex items-center rounded-md border border-border bg-muted px-3 py-1.5 text-sm font-medium text-foreground",
1744
+ children: content
1745
+ }
1746
+ );
1747
+ }
1748
+ function ClickyButtonGroup({ node }) {
1749
+ const items = node.items ?? [];
1750
+ if (items.length === 0) return null;
1751
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: items.map((item, index) => /* @__PURE__ */ jsx(ClickyNodeRenderer, { node: item }, index)) });
1752
+ }
1753
+ function ClickyHtmlNode({ node }) {
1754
+ const sanitized = sanitizeHtml(node.html ?? "");
1755
+ if (!sanitized) return null;
1756
+ const Tag = isBlockHtml(sanitized) ? "div" : "span";
1757
+ return /* @__PURE__ */ jsx(Tag, { dangerouslySetInnerHTML: { __html: sanitized } });
1758
+ }
1759
+ function toInlineStyle(style, text) {
1760
+ if (!style) return (text == null ? void 0 : text.includes("\n")) ? { whiteSpace: "pre-wrap" } : void 0;
1761
+ const inlineStyle = {};
1762
+ if (style.color) inlineStyle.color = style.color;
1763
+ if (style.backgroundColor) inlineStyle.backgroundColor = style.backgroundColor;
1764
+ if (style.bold) inlineStyle.fontWeight = 700;
1765
+ if (style.faint) inlineStyle.opacity = 0.7;
1766
+ if (style.italic) inlineStyle.fontStyle = "italic";
1767
+ const decorations = [];
1768
+ if (style.underline) decorations.push("underline");
1769
+ if (style.strikethrough) decorations.push("line-through");
1770
+ if (decorations.length > 0) inlineStyle.textDecoration = decorations.join(" ");
1771
+ if (style.textTransform === "uppercase" || style.textTransform === "lowercase" || style.textTransform === "capitalize") {
1772
+ inlineStyle.textTransform = style.textTransform;
1773
+ }
1774
+ if (style.maxWidth && style.maxWidth > 0) {
1775
+ inlineStyle.maxWidth = `${style.maxWidth}ch`;
1776
+ }
1777
+ if (style.maxLines && style.maxLines > 0) {
1778
+ inlineStyle.display = "-webkit-box";
1779
+ inlineStyle.overflow = "hidden";
1780
+ inlineStyle.WebkitLineClamp = style.maxLines;
1781
+ inlineStyle.WebkitBoxOrient = "vertical";
1782
+ inlineStyle.whiteSpace = "pre-wrap";
1783
+ }
1784
+ if (style.truncateMode === "suffix" && style.maxWidth && (!style.maxLines || style.maxLines <= 1)) {
1785
+ inlineStyle.overflow = "hidden";
1786
+ inlineStyle.textOverflow = "ellipsis";
1787
+ inlineStyle.whiteSpace = "nowrap";
1788
+ inlineStyle.display = "inline-block";
1789
+ inlineStyle.verticalAlign = "bottom";
1790
+ }
1791
+ if (style.monospace) {
1792
+ inlineStyle.fontFamily = 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace';
1793
+ }
1794
+ if (!inlineStyle.whiteSpace && (text == null ? void 0 : text.includes("\n"))) {
1795
+ inlineStyle.whiteSpace = "pre-wrap";
1796
+ }
1797
+ return Object.keys(inlineStyle).length > 0 ? inlineStyle : void 0;
1798
+ }
1799
+ function sanitizeHtml(raw) {
1800
+ if (!raw) return "";
1801
+ if (typeof DOMParser === "undefined") {
1802
+ return raw.replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi, "").replace(/\son\w+="[^"]*"/gi, "").replace(/\son\w+='[^']*'/gi, "");
1803
+ }
1804
+ const doc = new DOMParser().parseFromString(raw, "text/html");
1805
+ doc.querySelectorAll("script,iframe,object,embed,form").forEach((element) => element.remove());
1806
+ doc.querySelectorAll("*").forEach((element) => {
1807
+ Array.from(element.attributes).forEach((attribute) => {
1808
+ const name = attribute.name.toLowerCase();
1809
+ const value = attribute.value.trim().toLowerCase();
1810
+ if (name.startsWith("on") || name === "srcdoc") {
1811
+ element.removeAttribute(attribute.name);
1812
+ }
1813
+ if ((name === "href" || name === "src") && value.startsWith("javascript:")) {
1814
+ element.removeAttribute(attribute.name);
1815
+ }
1816
+ });
1817
+ });
1818
+ return doc.body.innerHTML;
1819
+ }
1820
+ function prettifyName(name) {
1821
+ return name.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/_/g, " ").replace(/\b\w/g, (value) => value.toUpperCase());
1822
+ }
1823
+ function clickyNodeToCommandRequest(node) {
1824
+ return {
1825
+ command: node.command ?? "",
1826
+ args: node.args ?? [],
1827
+ flags: node.flags ?? {},
1828
+ target: node.target ?? "Dialog",
1829
+ autoRun: node.autoRun ?? false
1830
+ };
1831
+ }
1832
+ function resolveClickyCommand(request, runtime, operations) {
1833
+ var _a;
1834
+ const resolved = ((_a = runtime == null ? void 0 : runtime.resolveCommand) == null ? void 0 : _a.call(runtime, request, operations)) ?? defaultResolveClickyCommand(request, operations);
1835
+ return { request, operation: resolved };
1836
+ }
1837
+ function defaultResolveClickyCommand(request, operations) {
1838
+ const wanted = normalizeCommandPath(request.command);
1839
+ if (!wanted) return void 0;
1840
+ return operations.find((operation) => {
1841
+ var _a, _b;
1842
+ const metaCommand = normalizeCommandPath((_a = operation.operation["x-clicky"]) == null ? void 0 : _a.command);
1843
+ if (metaCommand && metaCommand === wanted) {
1844
+ return true;
1845
+ }
1846
+ const operationId = normalizeCommandPath((_b = operation.operation.operationId) == null ? void 0 : _b.replaceAll("_", "/"));
1847
+ return operationId === wanted;
1848
+ });
1849
+ }
1850
+ function normalizeCommandPath(value) {
1851
+ return (value ?? "").trim().replace(/^\//, "").replace(/\s+/g, "/").replace(/\/+/g, "/").toLowerCase();
1852
+ }
1853
+ function buildCommandParameterValues(parameters, request) {
1854
+ const values = { ...request.flags };
1855
+ const args = [...request.args ?? []];
1856
+ const positionalParams = parameters.filter((param) => isPositionalParam(param));
1857
+ let argIndex = 0;
1858
+ for (const param of positionalParams) {
1859
+ if (param.name === "args") {
1860
+ const remaining = args.slice(argIndex);
1861
+ if (remaining.length > 0) {
1862
+ values.args = remaining.join(",");
1863
+ }
1864
+ argIndex = args.length;
1865
+ continue;
1866
+ }
1867
+ if (argIndex < args.length) {
1868
+ values[param.name] = args[argIndex] ?? "";
1869
+ argIndex += 1;
1870
+ }
1871
+ }
1872
+ return values;
1873
+ }
1874
+ function missingRequiredParameters(parameters, values) {
1875
+ return parameters.filter((param) => param.required && (values[param.name] ?? "").trim() === "");
1876
+ }
1877
+ async function executeClickyCommand(client, operation, values) {
1878
+ return client.executeCommand(
1879
+ operation.path,
1880
+ operation.method,
1881
+ packParameterValues(pruneParameterValues(values), operation.operation.parameters ?? []),
1882
+ { Accept: "application/json+clicky" }
1883
+ );
1884
+ }
1885
+ function buildCommandExecutionHref(resolved) {
1886
+ const operation = resolved.operation;
1887
+ if (!operation) {
1888
+ return void 0;
1889
+ }
1890
+ const values = buildCommandParameterValues(
1891
+ operation.operation.parameters ?? [],
1892
+ resolved.request
1893
+ );
1894
+ const params = packParameterValues(
1895
+ pruneParameterValues(values),
1896
+ operation.operation.parameters ?? []
1897
+ );
1898
+ const url = substituteOperationPath(operation.path, params);
1899
+ if (operation.method.toUpperCase() !== "GET") {
1900
+ return url;
1901
+ }
1902
+ return url;
1903
+ }
1904
+ function substituteOperationPath(path, params) {
1905
+ const url = new URL(path, "http://localhost");
1906
+ const remaining = { ...params };
1907
+ for (const [key, value] of Object.entries(params)) {
1908
+ if (url.pathname.includes(`{${key}}`)) {
1909
+ url.pathname = url.pathname.replace(`{${key}}`, encodeURIComponent(value));
1910
+ delete remaining[key];
1911
+ }
1912
+ }
1913
+ for (const [key, value] of Object.entries(remaining)) {
1914
+ url.searchParams.set(key, value);
1915
+ }
1916
+ return `${url.pathname}${url.search}`;
1917
+ }
1918
+ function browserAnchorTarget(target) {
1919
+ if (target === "_self") {
1920
+ return "_self";
1921
+ }
1922
+ if (target === "_window" || target === "_tab") {
1923
+ return "_blank";
1924
+ }
1925
+ return void 0;
1926
+ }
1927
+ function isExecutionResponse(value) {
1928
+ return value != null && typeof value === "object" && ("stdout" in value || "output" in value || "message" in value);
1929
+ }
1930
+ function clickyNodeText(node) {
1931
+ var _a, _b;
1932
+ if (!node) return "";
1933
+ if (node.plain) return node.plain;
1934
+ if (node.text) return node.text;
1935
+ if (node.kind === "html")
1936
+ return sanitizeHtml(node.html ?? "").replace(/<[^>]+>/g, " ").trim();
1937
+ if (node.kind === "code") return node.source ?? "";
1938
+ if ((node.kind === "link" || node.kind === "link-command") && ((_a = node.children) == null ? void 0 : _a.length)) {
1939
+ return [node.text, ...node.children.map((child) => clickyNodeText(child))].join("");
1940
+ }
1941
+ if (node.kind === "button" && node.label) return clickyNodeText(node.label);
1942
+ if (node.kind === "button-group") {
1943
+ return (node.items ?? []).map((item) => clickyNodeText(item)).join(" ");
1944
+ }
1945
+ if (node.kind === "text" && ((_b = node.children) == null ? void 0 : _b.length)) {
1946
+ return [node.text, ...node.children.map((child) => clickyNodeText(child))].join("");
1947
+ }
1948
+ return "";
1949
+ }
1950
+ function isInlineNode(node) {
1951
+ return node.kind === "text" || node.kind === "link" || node.kind === "link-command" || node.kind === "icon" || node.kind === "html" || node.kind === "button" || node.kind === "button-group";
1952
+ }
1953
+ function isBlockHtml(html) {
1954
+ return /<(div|p|pre|table|ul|ol|li|details|blockquote|h[1-6])/i.test(html);
1955
+ }
1956
+ export {
1957
+ Clicky,
1958
+ parseClickyData
1959
+ };
1960
+ //# sourceMappingURL=Clicky.js.map