@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,392 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { useMemo, useState, useRef, useEffect } from "react";
3
+ import { useQuery } from "@tanstack/react-query";
4
+ import { Button } from "../components/button.js";
5
+ import { FilterPill } from "../data/FilterPill.js";
6
+ import { Icon } from "../data/Icon.js";
7
+ import { cn } from "../lib/utils.js";
8
+ import { buildInitialParameterValues, useDebouncedRecord, packParameterValues, parametersToFormConfig, pruneParameterValues, titleCase } from "./formMetadata.js";
9
+ function FilterForm({
10
+ client,
11
+ path,
12
+ method,
13
+ parameters = [],
14
+ initialValues = {},
15
+ lockedValues = {},
16
+ hideLocked = false,
17
+ enableLookup = method.toUpperCase() === "GET",
18
+ autoSubmit = false,
19
+ submitLabel = "Execute request",
20
+ submittingLabel = "Executing…",
21
+ emptyMessage = "This operation does not require input.",
22
+ isSubmitting = false,
23
+ className,
24
+ onSubmit
25
+ }) {
26
+ const resetKey = useMemo(
27
+ () => `${method}:${path}:${JSON.stringify(initialValues)}:${JSON.stringify(lockedValues)}`,
28
+ [initialValues, lockedValues, method, path]
29
+ );
30
+ const [values, setValues] = useState(
31
+ () => buildInitialParameterValues(parameters, method, lockedValues, initialValues)
32
+ );
33
+ const [error, setError] = useState("");
34
+ const debouncedValues = useDebouncedRecord(values, 250);
35
+ const lastAutoSubmitted = useRef(null);
36
+ const lookupQuery = useQuery({
37
+ queryKey: ["filter-form-lookup", method, path, debouncedValues],
38
+ queryFn: async () => {
39
+ var _a;
40
+ return await ((_a = client.lookupFilters) == null ? void 0 : _a.call(
41
+ client,
42
+ path,
43
+ method,
44
+ packParameterValues(debouncedValues, parameters),
45
+ { Accept: "application/json+clicky" }
46
+ )) ?? { filters: {} };
47
+ },
48
+ enabled: enableLookup && !!client.lookupFilters && parameters.some((param) => param.in === "query"),
49
+ staleTime: 3e4,
50
+ retry: 0
51
+ });
52
+ const formConfig = useMemo(
53
+ () => parametersToFormConfig(parameters, values, setValues, {
54
+ lookup: lookupQuery.data,
55
+ lockedValues,
56
+ hideLocked
57
+ }),
58
+ [hideLocked, lockedValues, lookupQuery.data, parameters, values]
59
+ );
60
+ const hasFields = formConfig.filters.length > 0 || formConfig.timeRange != null;
61
+ async function handleSubmit(event) {
62
+ event == null ? void 0 : event.preventDefault();
63
+ const missingRequired = parameters.filter((param) => {
64
+ if (!param.required) return false;
65
+ const value = lockedValues[param.name] ?? values[param.name] ?? "";
66
+ return value.trim() === "";
67
+ });
68
+ if (missingRequired.length > 0) {
69
+ setError(
70
+ `Missing required fields: ${missingRequired.map((param) => titleCase(param.name)).join(", ")}`
71
+ );
72
+ return;
73
+ }
74
+ setError("");
75
+ await onSubmit(pruneParameterValues(values));
76
+ }
77
+ useEffect(() => {
78
+ setValues(buildInitialParameterValues(parameters, method, lockedValues, initialValues));
79
+ setError("");
80
+ lastAutoSubmitted.current = null;
81
+ }, [resetKey]);
82
+ useEffect(() => {
83
+ if (!autoSubmit) {
84
+ return;
85
+ }
86
+ const missingRequired = parameters.filter((param) => {
87
+ if (!param.required) return false;
88
+ const value = lockedValues[param.name] ?? debouncedValues[param.name] ?? "";
89
+ return value.trim() === "";
90
+ });
91
+ if (missingRequired.length > 0) {
92
+ return;
93
+ }
94
+ const submittedValues = pruneParameterValues(debouncedValues);
95
+ const signature = JSON.stringify(submittedValues);
96
+ if (lastAutoSubmitted.current === signature) {
97
+ return;
98
+ }
99
+ lastAutoSubmitted.current = signature;
100
+ setError("");
101
+ void onSubmit(submittedValues);
102
+ }, [autoSubmit, debouncedValues, lockedValues, onSubmit, parameters]);
103
+ return /* @__PURE__ */ jsxs("form", { className: "space-y-3", onSubmit: handleSubmit, children: [
104
+ hasFields ? /* @__PURE__ */ jsx(
105
+ ParameterGrid,
106
+ {
107
+ autoSubmit,
108
+ filters: formConfig.filters,
109
+ isSubmitting,
110
+ submitLabel,
111
+ submittingLabel,
112
+ ...formConfig.timeRange ? { timeRange: formConfig.timeRange } : {},
113
+ ...className ? { className } : {}
114
+ }
115
+ ) : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4", children: [
116
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage }),
117
+ /* @__PURE__ */ jsx(Button, { type: "button", onClick: handleSubmit, disabled: isSubmitting, children: isSubmitting ? submittingLabel : submitLabel })
118
+ ] }),
119
+ error && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive", children: error })
120
+ ] });
121
+ }
122
+ function ParameterGrid({
123
+ filters,
124
+ timeRange,
125
+ autoSubmit,
126
+ isSubmitting,
127
+ submitLabel,
128
+ submittingLabel,
129
+ className
130
+ }) {
131
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), children: [
132
+ /* @__PURE__ */ jsxs("div", { className: "divide-y divide-border border-y border-border", children: [
133
+ filters.map((filter) => /* @__PURE__ */ jsx(ParameterRow, { filter }, filter.key)),
134
+ timeRange && /* @__PURE__ */ jsx(TimeRangeRow, { timeRange })
135
+ ] }),
136
+ !autoSubmit && /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? submittingLabel : submitLabel }) })
137
+ ] });
138
+ }
139
+ function ParameterRow({ filter }) {
140
+ const id = `clicky-param-${filter.key.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
141
+ return /* @__PURE__ */ jsxs(
142
+ "div",
143
+ {
144
+ title: filter.description,
145
+ className: cn(
146
+ "grid grid-cols-1 gap-2 py-2 sm:grid-cols-[minmax(8rem,14rem)_minmax(0,1fr)] sm:items-center",
147
+ filter.disabled && "opacity-60"
148
+ ),
149
+ children: [
150
+ /* @__PURE__ */ jsx("label", { htmlFor: id, className: "text-sm font-medium text-muted-foreground", children: filter.label }),
151
+ /* @__PURE__ */ jsx("div", { className: "min-w-0", children: renderParameterInput(filter, id) })
152
+ ]
153
+ }
154
+ );
155
+ }
156
+ function renderParameterInput(filter, id) {
157
+ if (filter.kind === "enum") {
158
+ return /* @__PURE__ */ jsxs(
159
+ "select",
160
+ {
161
+ id,
162
+ "aria-label": filter.label,
163
+ className: inputClassName,
164
+ value: filter.value,
165
+ disabled: filter.disabled,
166
+ onChange: (event) => filter.onChange(event.target.value),
167
+ children: [
168
+ /* @__PURE__ */ jsx("option", { value: "", children: filter.placeholder ?? `Any ${filter.label.toLowerCase()}` }),
169
+ filter.options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label ?? option.value }, option.value))
170
+ ]
171
+ }
172
+ );
173
+ }
174
+ if (filter.kind === "boolean") {
175
+ return /* @__PURE__ */ jsx("div", { className: "flex h-8 items-center", children: /* @__PURE__ */ jsx(
176
+ "input",
177
+ {
178
+ id,
179
+ type: "checkbox",
180
+ "aria-label": filter.label,
181
+ className: "h-4 w-4 accent-primary disabled:cursor-not-allowed",
182
+ checked: filter.value,
183
+ disabled: filter.disabled,
184
+ onChange: (event) => filter.onChange(event.target.checked)
185
+ }
186
+ ) });
187
+ }
188
+ if (filter.kind === "lookup") {
189
+ const listId = `${id}-options`;
190
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
191
+ /* @__PURE__ */ jsx(
192
+ "input",
193
+ {
194
+ id,
195
+ type: filter.inputType === "number" ? "number" : "text",
196
+ "aria-label": filter.label,
197
+ className: inputClassName,
198
+ placeholder: filter.placeholder ?? "Value",
199
+ value: filter.value,
200
+ list: listId,
201
+ disabled: filter.disabled,
202
+ onChange: (event) => filter.onChange(event.target.value)
203
+ }
204
+ ),
205
+ /* @__PURE__ */ jsx("datalist", { id: listId, children: filter.options.map((option) => /* @__PURE__ */ jsx(
206
+ "option",
207
+ {
208
+ value: option.value,
209
+ label: option.label ?? option.value,
210
+ disabled: option.disabled
211
+ },
212
+ option.value
213
+ )) })
214
+ ] });
215
+ }
216
+ if (filter.kind === "lookup-multi") {
217
+ const listId = `${id}-options`;
218
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
219
+ /* @__PURE__ */ jsx(
220
+ "input",
221
+ {
222
+ id,
223
+ type: "text",
224
+ "aria-label": filter.label,
225
+ className: inputClassName,
226
+ placeholder: filter.placeholder ?? "value-1, value-2",
227
+ value: filter.value.join(", "),
228
+ list: listId,
229
+ disabled: filter.disabled,
230
+ onChange: (event) => filter.onChange(splitCommaValues(event.target.value))
231
+ }
232
+ ),
233
+ /* @__PURE__ */ jsx("datalist", { id: listId, children: filter.options.map((option) => /* @__PURE__ */ jsx(
234
+ "option",
235
+ {
236
+ value: option.value,
237
+ label: option.label ?? option.value,
238
+ disabled: option.disabled
239
+ },
240
+ option.value
241
+ )) })
242
+ ] });
243
+ }
244
+ if (filter.kind === "multi") {
245
+ return /* @__PURE__ */ jsx(MultiParameterInput, { filter, id });
246
+ }
247
+ if (filter.kind === "text") {
248
+ return /* @__PURE__ */ jsx(
249
+ "input",
250
+ {
251
+ id,
252
+ type: "text",
253
+ "aria-label": filter.label,
254
+ className: inputClassName,
255
+ placeholder: filter.placeholder ?? "Value",
256
+ value: filter.value,
257
+ disabled: filter.disabled,
258
+ onChange: (event) => filter.onChange(event.target.value)
259
+ }
260
+ );
261
+ }
262
+ return /* @__PURE__ */ jsx(
263
+ "input",
264
+ {
265
+ id,
266
+ type: "text",
267
+ "aria-label": filter.label,
268
+ className: inputClassName,
269
+ value: JSON.stringify(filter.value),
270
+ disabled: true,
271
+ readOnly: true
272
+ }
273
+ );
274
+ }
275
+ function MultiParameterInput({ filter, id }) {
276
+ const [query, setQuery] = useState("");
277
+ const showOptionFilter = filter.options.length > 7;
278
+ const visibleOptions = useMemo(() => {
279
+ const normalized = query.trim().toLowerCase();
280
+ if (!normalized) return filter.options;
281
+ return filter.options.filter(
282
+ (option) => multiOptionText(option).toLowerCase().includes(normalized)
283
+ );
284
+ }, [filter.options, query]);
285
+ const setMode = (value, mode) => {
286
+ if (filter.disabled) return;
287
+ const next = { ...filter.value };
288
+ if (mode === "include" || mode === "exclude") {
289
+ next[value] = mode;
290
+ } else {
291
+ delete next[value];
292
+ }
293
+ filter.onChange(next);
294
+ };
295
+ return /* @__PURE__ */ jsxs(
296
+ "div",
297
+ {
298
+ id,
299
+ role: "group",
300
+ "aria-label": filter.label,
301
+ className: "rounded-md border border-input bg-background p-2",
302
+ children: [
303
+ showOptionFilter && /* @__PURE__ */ jsxs("label", { className: "mb-2 flex items-center gap-2 rounded-md border border-input bg-background px-2", children: [
304
+ /* @__PURE__ */ jsx(Icon, { name: "codicon:search", className: "shrink-0 text-muted-foreground" }),
305
+ /* @__PURE__ */ jsx(
306
+ "input",
307
+ {
308
+ type: "search",
309
+ "aria-label": `Filter ${filter.label} options`,
310
+ className: "h-8 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground",
311
+ placeholder: `Filter ${filter.label.toLowerCase()}`,
312
+ value: query,
313
+ disabled: filter.disabled,
314
+ onChange: (event) => setQuery(event.target.value)
315
+ }
316
+ )
317
+ ] }),
318
+ /* @__PURE__ */ jsxs("div", { className: "max-h-56 space-y-1 overflow-auto", children: [
319
+ visibleOptions.map((option) => {
320
+ const mode = filter.value[option.value] ?? "neutral";
321
+ return /* @__PURE__ */ jsx(
322
+ FilterPill,
323
+ {
324
+ className: "w-full justify-between",
325
+ label: option.label,
326
+ mode,
327
+ title: option.title ?? multiOptionText(option),
328
+ togglePosition: "right",
329
+ onModeChange: (next) => setMode(option.value, next)
330
+ },
331
+ option.value
332
+ );
333
+ }),
334
+ visibleOptions.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-2 py-3 text-sm text-muted-foreground", children: "No options found" })
335
+ ] })
336
+ ]
337
+ }
338
+ );
339
+ }
340
+ function multiOptionText(option) {
341
+ const label = typeof option.label === "string" ? option.label : "";
342
+ return [option.value, label, option.title ?? ""].filter(Boolean).join(" ");
343
+ }
344
+ function TimeRangeRow({ timeRange }) {
345
+ const fromId = "clicky-param-from";
346
+ const toId = "clicky-param-to";
347
+ const from = timeRange.from ?? "";
348
+ const to = timeRange.to ?? "";
349
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-2 py-2 sm:grid-cols-[minmax(8rem,14rem)_minmax(0,1fr)] sm:items-center", children: [
350
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-muted-foreground", children: "Time range" }),
351
+ /* @__PURE__ */ jsxs("div", { className: "grid min-w-0 grid-cols-1 gap-2 sm:grid-cols-2", children: [
352
+ /* @__PURE__ */ jsxs("label", { className: "min-w-0", children: [
353
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "From" }),
354
+ /* @__PURE__ */ jsx(
355
+ "input",
356
+ {
357
+ id: fromId,
358
+ type: "text",
359
+ "aria-label": "From",
360
+ className: inputClassName,
361
+ placeholder: timeRange.fromPlaceholder ?? "From",
362
+ value: from,
363
+ onChange: (event) => timeRange.onApply(event.target.value, to)
364
+ }
365
+ )
366
+ ] }),
367
+ /* @__PURE__ */ jsxs("label", { className: "min-w-0", children: [
368
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "To" }),
369
+ /* @__PURE__ */ jsx(
370
+ "input",
371
+ {
372
+ id: toId,
373
+ type: "text",
374
+ "aria-label": "To",
375
+ className: inputClassName,
376
+ placeholder: timeRange.toPlaceholder ?? "To",
377
+ value: to,
378
+ onChange: (event) => timeRange.onApply(from, event.target.value)
379
+ }
380
+ )
381
+ ] })
382
+ ] })
383
+ ] });
384
+ }
385
+ function splitCommaValues(value) {
386
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
387
+ }
388
+ const inputClassName = "h-8 w-full min-w-0 rounded-md border border-input bg-background px-2 text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:bg-muted/40 focus-visible:ring-2 focus-visible:ring-ring";
389
+ export {
390
+ FilterForm
391
+ };
392
+ //# sourceMappingURL=FilterForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterForm.js","sources":["../../src/rpc/FilterForm.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState, type FormEvent } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { Button } from \"../components/button\";\nimport type {\n FilterBarFilter,\n FilterBarMultiFilter,\n FilterBarRangeProps,\n} from \"../components/FilterBar\";\nimport { FilterPill, type FilterMode } from \"../data/FilterPill\";\nimport { Icon } from \"../data/Icon\";\nimport { cn } from \"../lib/utils\";\nimport {\n packParameterValues,\n parametersToFormConfig,\n pruneParameterValues,\n buildInitialParameterValues,\n titleCase,\n useDebouncedRecord,\n type ParameterValues,\n} from \"./formMetadata\";\nimport type { OpenAPIParameter } from \"./types\";\nimport type { OperationsApiClient } from \"./useOperations\";\n\nexport type FilterFormProps = {\n client: OperationsApiClient;\n path: string;\n method: string;\n parameters?: OpenAPIParameter[];\n initialValues?: ParameterValues | undefined;\n lockedValues?: ParameterValues | undefined;\n hideLocked?: boolean | undefined;\n enableLookup?: boolean | undefined;\n autoSubmit?: boolean | undefined;\n submitLabel?: string | undefined;\n submittingLabel?: string | undefined;\n emptyMessage?: string | undefined;\n isSubmitting?: boolean | undefined;\n className?: string | undefined;\n onSubmit: (values: ParameterValues) => void | Promise<void>;\n};\n\nexport function FilterForm({\n client,\n path,\n method,\n parameters = [],\n initialValues = {},\n lockedValues = {},\n hideLocked = false,\n enableLookup = method.toUpperCase() === \"GET\",\n autoSubmit = false,\n submitLabel = \"Execute request\",\n submittingLabel = \"Executing…\",\n emptyMessage = \"This operation does not require input.\",\n isSubmitting = false,\n className,\n onSubmit,\n}: FilterFormProps) {\n const resetKey = useMemo(\n () => `${method}:${path}:${JSON.stringify(initialValues)}:${JSON.stringify(lockedValues)}`,\n [initialValues, lockedValues, method, path],\n );\n const [values, setValues] = useState<ParameterValues>(() =>\n buildInitialParameterValues(parameters, method, lockedValues, initialValues),\n );\n const [error, setError] = useState(\"\");\n const debouncedValues = useDebouncedRecord(values, 250);\n const lastAutoSubmitted = useRef<string | null>(null);\n\n const lookupQuery = useQuery({\n queryKey: [\"filter-form-lookup\", method, path, debouncedValues],\n queryFn: async () =>\n (await client.lookupFilters?.(\n path,\n method,\n packParameterValues(debouncedValues, parameters),\n { Accept: \"application/json+clicky\" },\n )) ?? { filters: {} },\n enabled:\n enableLookup && !!client.lookupFilters && parameters.some((param) => param.in === \"query\"),\n staleTime: 30_000,\n retry: 0,\n });\n\n const formConfig = useMemo(\n () =>\n parametersToFormConfig(parameters, values, setValues, {\n lookup: lookupQuery.data,\n lockedValues,\n hideLocked,\n }),\n [hideLocked, lockedValues, lookupQuery.data, parameters, values],\n );\n\n const hasFields = formConfig.filters.length > 0 || formConfig.timeRange != null;\n\n async function handleSubmit(event?: FormEvent) {\n event?.preventDefault();\n\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n const value = lockedValues[param.name] ?? values[param.name] ?? \"\";\n return value.trim() === \"\";\n });\n\n if (missingRequired.length > 0) {\n setError(\n `Missing required fields: ${missingRequired.map((param) => titleCase(param.name)).join(\", \")}`,\n );\n return;\n }\n\n setError(\"\");\n await onSubmit(pruneParameterValues(values));\n }\n\n useEffect(() => {\n setValues(buildInitialParameterValues(parameters, method, lockedValues, initialValues));\n setError(\"\");\n lastAutoSubmitted.current = null;\n }, [resetKey]);\n\n useEffect(() => {\n if (!autoSubmit) {\n return;\n }\n\n const missingRequired = parameters.filter((param) => {\n if (!param.required) return false;\n const value = lockedValues[param.name] ?? debouncedValues[param.name] ?? \"\";\n return value.trim() === \"\";\n });\n if (missingRequired.length > 0) {\n return;\n }\n\n const submittedValues = pruneParameterValues(debouncedValues);\n const signature = JSON.stringify(submittedValues);\n if (lastAutoSubmitted.current === signature) {\n return;\n }\n\n lastAutoSubmitted.current = signature;\n setError(\"\");\n void onSubmit(submittedValues);\n }, [autoSubmit, debouncedValues, lockedValues, onSubmit, parameters]);\n\n return (\n <form className=\"space-y-3\" onSubmit={handleSubmit}>\n {hasFields ? (\n <ParameterGrid\n autoSubmit={autoSubmit}\n filters={formConfig.filters}\n isSubmitting={isSubmitting}\n submitLabel={submitLabel}\n submittingLabel={submittingLabel}\n {...(formConfig.timeRange ? { timeRange: formConfig.timeRange } : {})}\n {...(className ? { className } : {})}\n />\n ) : (\n <div className=\"flex items-center justify-between gap-4\">\n <p className=\"text-sm text-muted-foreground\">{emptyMessage}</p>\n <Button type=\"button\" onClick={handleSubmit} disabled={isSubmitting}>\n {isSubmitting ? submittingLabel : submitLabel}\n </Button>\n </div>\n )}\n\n {error && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive\">\n {error}\n </div>\n )}\n </form>\n );\n}\n\ntype ParameterGridProps = {\n filters: FilterBarFilter[];\n timeRange?: FilterBarRangeProps | undefined;\n autoSubmit: boolean;\n isSubmitting: boolean;\n submitLabel: string;\n submittingLabel: string;\n className?: string | undefined;\n};\n\nfunction ParameterGrid({\n filters,\n timeRange,\n autoSubmit,\n isSubmitting,\n submitLabel,\n submittingLabel,\n className,\n}: ParameterGridProps) {\n return (\n <div className={cn(\"space-y-3\", className)}>\n <div className=\"divide-y divide-border border-y border-border\">\n {filters.map((filter) => (\n <ParameterRow key={filter.key} filter={filter} />\n ))}\n {timeRange && <TimeRangeRow timeRange={timeRange} />}\n </div>\n\n {!autoSubmit && (\n <div className=\"flex justify-end\">\n <Button type=\"submit\" disabled={isSubmitting}>\n {isSubmitting ? submittingLabel : submitLabel}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nfunction ParameterRow({ filter }: { filter: FilterBarFilter }) {\n const id = `clicky-param-${filter.key.replace(/[^a-zA-Z0-9_-]/g, \"-\")}`;\n\n return (\n <div\n title={filter.description}\n className={cn(\n \"grid grid-cols-1 gap-2 py-2 sm:grid-cols-[minmax(8rem,14rem)_minmax(0,1fr)] sm:items-center\",\n filter.disabled && \"opacity-60\",\n )}\n >\n <label htmlFor={id} className=\"text-sm font-medium text-muted-foreground\">\n {filter.label}\n </label>\n <div className=\"min-w-0\">{renderParameterInput(filter, id)}</div>\n </div>\n );\n}\n\nfunction renderParameterInput(filter: FilterBarFilter, id: string) {\n if (filter.kind === \"enum\") {\n return (\n <select\n id={id}\n aria-label={filter.label}\n className={inputClassName}\n value={filter.value}\n disabled={filter.disabled}\n onChange={(event) => filter.onChange(event.target.value)}\n >\n <option value=\"\">{filter.placeholder ?? `Any ${filter.label.toLowerCase()}`}</option>\n {filter.options.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label ?? option.value}\n </option>\n ))}\n </select>\n );\n }\n\n if (filter.kind === \"boolean\") {\n return (\n <div className=\"flex h-8 items-center\">\n <input\n id={id}\n type=\"checkbox\"\n aria-label={filter.label}\n className=\"h-4 w-4 accent-primary disabled:cursor-not-allowed\"\n checked={filter.value}\n disabled={filter.disabled}\n onChange={(event) => filter.onChange(event.target.checked)}\n />\n </div>\n );\n }\n\n if (filter.kind === \"lookup\") {\n const listId = `${id}-options`;\n return (\n <>\n <input\n id={id}\n type={filter.inputType === \"number\" ? \"number\" : \"text\"}\n aria-label={filter.label}\n className={inputClassName}\n placeholder={filter.placeholder ?? \"Value\"}\n value={filter.value}\n list={listId}\n disabled={filter.disabled}\n onChange={(event) => filter.onChange(event.target.value)}\n />\n <datalist id={listId}>\n {filter.options.map((option) => (\n <option\n key={option.value}\n value={option.value}\n label={option.label ?? option.value}\n disabled={option.disabled}\n />\n ))}\n </datalist>\n </>\n );\n }\n\n if (filter.kind === \"lookup-multi\") {\n const listId = `${id}-options`;\n return (\n <>\n <input\n id={id}\n type=\"text\"\n aria-label={filter.label}\n className={inputClassName}\n placeholder={filter.placeholder ?? \"value-1, value-2\"}\n value={filter.value.join(\", \")}\n list={listId}\n disabled={filter.disabled}\n onChange={(event) => filter.onChange(splitCommaValues(event.target.value))}\n />\n <datalist id={listId}>\n {filter.options.map((option) => (\n <option\n key={option.value}\n value={option.value}\n label={option.label ?? option.value}\n disabled={option.disabled}\n />\n ))}\n </datalist>\n </>\n );\n }\n\n if (filter.kind === \"multi\") {\n return <MultiParameterInput filter={filter} id={id} />;\n }\n\n if (filter.kind === \"text\") {\n return (\n <input\n id={id}\n type=\"text\"\n aria-label={filter.label}\n className={inputClassName}\n placeholder={filter.placeholder ?? \"Value\"}\n value={filter.value}\n disabled={filter.disabled}\n onChange={(event) => filter.onChange(event.target.value)}\n />\n );\n }\n\n return (\n <input\n id={id}\n type=\"text\"\n aria-label={filter.label}\n className={inputClassName}\n value={JSON.stringify(filter.value)}\n disabled\n readOnly\n />\n );\n}\n\nfunction MultiParameterInput({ filter, id }: { filter: FilterBarMultiFilter; id: string }) {\n const [query, setQuery] = useState(\"\");\n const showOptionFilter = filter.options.length > 7;\n const visibleOptions = useMemo(() => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return filter.options;\n return filter.options.filter((option) =>\n multiOptionText(option).toLowerCase().includes(normalized),\n );\n }, [filter.options, query]);\n\n const setMode = (value: string, mode: FilterMode) => {\n if (filter.disabled) return;\n const next = { ...filter.value };\n if (mode === \"include\" || mode === \"exclude\") {\n next[value] = mode;\n } else {\n delete next[value];\n }\n filter.onChange(next);\n };\n\n return (\n <div\n id={id}\n role=\"group\"\n aria-label={filter.label}\n className=\"rounded-md border border-input bg-background p-2\"\n >\n {showOptionFilter && (\n <label className=\"mb-2 flex items-center gap-2 rounded-md border border-input bg-background px-2\">\n <Icon name=\"codicon:search\" className=\"shrink-0 text-muted-foreground\" />\n <input\n type=\"search\"\n aria-label={`Filter ${filter.label} options`}\n className=\"h-8 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground\"\n placeholder={`Filter ${filter.label.toLowerCase()}`}\n value={query}\n disabled={filter.disabled}\n onChange={(event) => setQuery(event.target.value)}\n />\n </label>\n )}\n\n <div className=\"max-h-56 space-y-1 overflow-auto\">\n {visibleOptions.map((option) => {\n const mode: FilterMode = filter.value[option.value] ?? \"neutral\";\n return (\n <FilterPill\n key={option.value}\n className=\"w-full justify-between\"\n label={option.label}\n mode={mode}\n title={option.title ?? multiOptionText(option)}\n togglePosition=\"right\"\n onModeChange={(next) => setMode(option.value, next)}\n />\n );\n })}\n {visibleOptions.length === 0 && (\n <div className=\"px-2 py-3 text-sm text-muted-foreground\">No options found</div>\n )}\n </div>\n </div>\n );\n}\n\nfunction multiOptionText(option: FilterBarMultiFilter[\"options\"][number]) {\n const label = typeof option.label === \"string\" ? option.label : \"\";\n return [option.value, label, option.title ?? \"\"].filter(Boolean).join(\" \");\n}\n\nfunction TimeRangeRow({ timeRange }: { timeRange: FilterBarRangeProps }) {\n const fromId = \"clicky-param-from\";\n const toId = \"clicky-param-to\";\n const from = timeRange.from ?? \"\";\n const to = timeRange.to ?? \"\";\n\n return (\n <div className=\"grid grid-cols-1 gap-2 py-2 sm:grid-cols-[minmax(8rem,14rem)_minmax(0,1fr)] sm:items-center\">\n <div className=\"text-sm font-medium text-muted-foreground\">Time range</div>\n <div className=\"grid min-w-0 grid-cols-1 gap-2 sm:grid-cols-2\">\n <label className=\"min-w-0\">\n <span className=\"sr-only\">From</span>\n <input\n id={fromId}\n type=\"text\"\n aria-label=\"From\"\n className={inputClassName}\n placeholder={timeRange.fromPlaceholder ?? \"From\"}\n value={from}\n onChange={(event) => timeRange.onApply(event.target.value, to)}\n />\n </label>\n <label className=\"min-w-0\">\n <span className=\"sr-only\">To</span>\n <input\n id={toId}\n type=\"text\"\n aria-label=\"To\"\n className={inputClassName}\n placeholder={timeRange.toPlaceholder ?? \"To\"}\n value={to}\n onChange={(event) => timeRange.onApply(from, event.target.value)}\n />\n </label>\n </div>\n </div>\n );\n}\n\nfunction splitCommaValues(value: string) {\n return value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nconst inputClassName =\n \"h-8 w-full min-w-0 rounded-md border border-input bg-background px-2 text-sm text-foreground outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:bg-muted/40 focus-visible:ring-2 focus-visible:ring-ring\";\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type InlineErrorProps = {
2
+ title: string;
3
+ error: unknown;
4
+ className?: string;
5
+ };
6
+ export declare function InlineError({ title, error, className }: InlineErrorProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=InlineError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InlineError.d.ts","sourceRoot":"","sources":["../../src/rpc/InlineError.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AASF,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAsCxE"}
@@ -0,0 +1,54 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Icon } from "../data/Icon.js";
3
+ import { cn } from "../lib/utils.js";
4
+ function InlineError({ title, error, className }) {
5
+ const message = error instanceof Error ? error.message : String(error ?? "");
6
+ const details = getErrorDetails(error);
7
+ const hasDetails = Boolean(details.responseBody || details.status || details.url);
8
+ return /* @__PURE__ */ jsxs("div", { className: cn("rounded-xl border border-dashed border-red-300 p-6 text-sm", className), children: [
9
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
10
+ /* @__PURE__ */ jsx("div", { className: "font-medium text-red-600", children: title }),
11
+ message && /* @__PURE__ */ jsx("div", { className: "mt-1 text-muted-foreground", children: message })
12
+ ] }),
13
+ hasDetails && /* @__PURE__ */ jsxs("details", { className: "group mt-3", children: [
14
+ /* @__PURE__ */ jsxs("summary", { className: "flex cursor-pointer items-center justify-center gap-1 text-xs text-muted-foreground hover:text-foreground", children: [
15
+ /* @__PURE__ */ jsx(
16
+ Icon,
17
+ {
18
+ name: "codicon:chevron-right",
19
+ className: "transition-transform group-open:rotate-90"
20
+ }
21
+ ),
22
+ "More details"
23
+ ] }),
24
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 space-y-2 text-left font-mono text-xs", children: [
25
+ (details.method || details.url || details.status) && /* @__PURE__ */ jsxs("div", { className: "text-muted-foreground", children: [
26
+ details.method && /* @__PURE__ */ jsxs("span", { children: [
27
+ details.method,
28
+ " "
29
+ ] }),
30
+ details.url,
31
+ details.status != null && /* @__PURE__ */ jsxs("span", { children: [
32
+ " - ",
33
+ details.status
34
+ ] })
35
+ ] }),
36
+ details.responseBody && /* @__PURE__ */ jsx("pre", { className: "max-h-64 overflow-auto rounded-md bg-muted p-2 text-xs", children: details.responseBody })
37
+ ] })
38
+ ] })
39
+ ] });
40
+ }
41
+ function getErrorDetails(error) {
42
+ if (error == null || typeof error !== "object") return {};
43
+ const record = error;
44
+ const details = {};
45
+ if (typeof record.method === "string") details.method = record.method;
46
+ if (typeof record.url === "string") details.url = record.url;
47
+ if (typeof record.status === "number") details.status = record.status;
48
+ if (typeof record.responseBody === "string") details.responseBody = record.responseBody;
49
+ return details;
50
+ }
51
+ export {
52
+ InlineError
53
+ };
54
+ //# sourceMappingURL=InlineError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InlineError.js","sources":["../../src/rpc/InlineError.tsx"],"sourcesContent":["import { Icon } from \"../data/Icon\";\nimport { cn } from \"../lib/utils\";\n\nexport type InlineErrorProps = {\n title: string;\n error: unknown;\n className?: string;\n};\n\ntype ErrorDetails = {\n method?: string;\n url?: string;\n status?: number;\n responseBody?: string;\n};\n\nexport function InlineError({ title, error, className }: InlineErrorProps) {\n const message = error instanceof Error ? error.message : String(error ?? \"\");\n const details = getErrorDetails(error);\n const hasDetails = Boolean(details.responseBody || details.status || details.url);\n\n return (\n <div className={cn(\"rounded-xl border border-dashed border-red-300 p-6 text-sm\", className)}>\n <div className=\"text-center\">\n <div className=\"font-medium text-red-600\">{title}</div>\n {message && <div className=\"mt-1 text-muted-foreground\">{message}</div>}\n </div>\n {hasDetails && (\n <details className=\"group mt-3\">\n <summary className=\"flex cursor-pointer items-center justify-center gap-1 text-xs text-muted-foreground hover:text-foreground\">\n <Icon\n name=\"codicon:chevron-right\"\n className=\"transition-transform group-open:rotate-90\"\n />\n More details\n </summary>\n <div className=\"mt-2 space-y-2 text-left font-mono text-xs\">\n {(details.method || details.url || details.status) && (\n <div className=\"text-muted-foreground\">\n {details.method && <span>{details.method} </span>}\n {details.url}\n {details.status != null && <span> - {details.status}</span>}\n </div>\n )}\n {details.responseBody && (\n <pre className=\"max-h-64 overflow-auto rounded-md bg-muted p-2 text-xs\">\n {details.responseBody}\n </pre>\n )}\n </div>\n </details>\n )}\n </div>\n );\n}\n\nfunction getErrorDetails(error: unknown): ErrorDetails {\n if (error == null || typeof error !== \"object\") return {};\n const record = error as Record<string, unknown>;\n const details: ErrorDetails = {};\n if (typeof record.method === \"string\") details.method = record.method;\n if (typeof record.url === \"string\") details.url = record.url;\n if (typeof record.status === \"number\") details.status = record.status;\n if (typeof record.responseBody === \"string\") details.responseBody = record.responseBody;\n return details;\n}\n"],"names":[],"mappings":";;;AAgBO,SAAS,YAAY,EAAE,OAAO,OAAO,aAA+B;AACzE,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,SAAS,EAAE;AAC3E,QAAM,UAAU,gBAAgB,KAAK;AACrC,QAAM,aAAa,QAAQ,QAAQ,gBAAgB,QAAQ,UAAU,QAAQ,GAAG;AAEhF,8BACG,OAAA,EAAI,WAAW,GAAG,8DAA8D,SAAS,GACxF,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,4BAA4B,UAAA,OAAM;AAAA,MAChD,WAAW,oBAAC,OAAA,EAAI,WAAU,8BAA8B,UAAA,QAAA,CAAQ;AAAA,IAAA,GACnE;AAAA,IACC,cACC,qBAAC,WAAA,EAAQ,WAAU,cACjB,UAAA;AAAA,MAAA,qBAAC,WAAA,EAAQ,WAAU,6GACjB,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QACV;AAAA,MAAA,GAEJ;AAAA,MACA,qBAAC,OAAA,EAAI,WAAU,8CACX,UAAA;AAAA,SAAA,QAAQ,UAAU,QAAQ,OAAO,QAAQ,WACzC,qBAAC,OAAA,EAAI,WAAU,yBACZ,UAAA;AAAA,UAAA,QAAQ,+BAAW,QAAA,EAAM,UAAA;AAAA,YAAA,QAAQ;AAAA,YAAO;AAAA,UAAA,GAAC;AAAA,UACzC,QAAQ;AAAA,UACR,QAAQ,UAAU,QAAQ,qBAAC,QAAA,EAAK,UAAA;AAAA,YAAA;AAAA,YAAI,QAAQ;AAAA,UAAA,EAAA,CAAO;AAAA,QAAA,GACtD;AAAA,QAED,QAAQ,gBACP,oBAAC,SAAI,WAAU,0DACZ,kBAAQ,aAAA,CACX;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AAEA,SAAS,gBAAgB,OAA8B;AACrD,MAAI,SAAS,QAAQ,OAAO,UAAU,iBAAiB,CAAA;AACvD,QAAM,SAAS;AACf,QAAM,UAAwB,CAAA;AAC9B,MAAI,OAAO,OAAO,WAAW,SAAU,SAAQ,SAAS,OAAO;AAC/D,MAAI,OAAO,OAAO,QAAQ,SAAU,SAAQ,MAAM,OAAO;AACzD,MAAI,OAAO,OAAO,WAAW,SAAU,SAAQ,SAAS,OAAO;AAC/D,MAAI,OAAO,OAAO,iBAAiB,SAAU,SAAQ,eAAe,OAAO;AAC3E,SAAO;AACT;"}
@@ -0,0 +1,12 @@
1
+ import { ResolvedOperation } from './types';
2
+ import { OperationsApiClient } from './useOperations';
3
+ export type OperationActionDialogProps = {
4
+ operation: ResolvedOperation;
5
+ client: OperationsApiClient;
6
+ initialValues: Record<string, string>;
7
+ label: string;
8
+ defaultAccept?: string;
9
+ onNavigateAction?: (href: string) => void;
10
+ };
11
+ export declare function OperationActionDialog({ operation, client, initialValues, label, defaultAccept, onNavigateAction, }: OperationActionDialogProps): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=OperationActionDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OperationActionDialog.d.ts","sourceRoot":"","sources":["../../src/rpc/OperationActionDialog.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAqB,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,MAAM,EACN,aAAa,EACb,KAAK,EACL,aAAyC,EACzC,gBAAgB,GACjB,EAAE,0BAA0B,2CAuD5B"}
@@ -0,0 +1,105 @@
1
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Button } from "../components/button.js";
4
+ import { Icon } from "../data/Icon.js";
5
+ import { Modal } from "../overlay/Modal.js";
6
+ import { CommandForm } from "./CommandForm.js";
7
+ import { CommandOutput } from "./CommandOutput.js";
8
+ import { InlineError } from "./InlineError.js";
9
+ function OperationActionDialog({
10
+ operation,
11
+ client,
12
+ initialValues,
13
+ label,
14
+ defaultAccept = "application/clicky+json",
15
+ onNavigateAction
16
+ }) {
17
+ const [open, setOpen] = useState(false);
18
+ const [isExecuting, setIsExecuting] = useState(false);
19
+ const [response, setResponse] = useState(null);
20
+ const [error, setError] = useState(null);
21
+ async function handleExecute(params, headers) {
22
+ if (onNavigateAction) {
23
+ const href = hrefForOperationAction(operation.path, params);
24
+ if (!href) return;
25
+ const separator = href.includes("?") ? "&" : "?";
26
+ onNavigateAction(`${href}${separator}autoRun=1`);
27
+ return;
28
+ }
29
+ setIsExecuting(true);
30
+ setError(null);
31
+ setResponse(null);
32
+ try {
33
+ const result = await client.executeCommand(operation.path, operation.method, params, headers);
34
+ setResponse(result);
35
+ } catch (err) {
36
+ setError(err);
37
+ } finally {
38
+ setIsExecuting(false);
39
+ }
40
+ }
41
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
42
+ /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setOpen(true), children: [
43
+ /* @__PURE__ */ jsx(Icon, { name: "codicon:play" }),
44
+ label
45
+ ] }),
46
+ /* @__PURE__ */ jsx(Modal, { open, onClose: () => setOpen(false), title: label, size: "lg", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
47
+ /* @__PURE__ */ jsx(
48
+ CommandForm,
49
+ {
50
+ parameters: operation.operation.parameters ?? [],
51
+ onExecute: handleExecute,
52
+ isPending: isExecuting,
53
+ method: operation.method,
54
+ path: operation.path,
55
+ accept: defaultAccept,
56
+ initialValues
57
+ }
58
+ ),
59
+ error ? /* @__PURE__ */ jsx(InlineError, { title: `Failed to execute ${operation.path}`, error }) : response ? /* @__PURE__ */ jsx(CommandOutput, { response }) : null
60
+ ] }) })
61
+ ] });
62
+ }
63
+ function hrefForOperationAction(path, params) {
64
+ const nextParams = { ...params };
65
+ const args = parseArgsParam(params.args);
66
+ let route = apiPathToRoutePath(path);
67
+ for (const [index, name] of pathParamNames(path).entries()) {
68
+ const value = nextParams[name] || args[index];
69
+ if (!value) return void 0;
70
+ route = route.replace(`:${name}`, encodeURIComponent(value));
71
+ delete nextParams[name];
72
+ if (!nextParams[name] && value === args[index]) {
73
+ delete nextParams.args;
74
+ }
75
+ }
76
+ const search = new URLSearchParams();
77
+ for (const [key, value] of Object.entries(nextParams)) {
78
+ if (value && key !== "autoRun") search.set(key, value);
79
+ }
80
+ const query = search.toString();
81
+ return query ? `${route}?${query}` : route;
82
+ }
83
+ function apiPathToRoutePath(path) {
84
+ const cliPath = path.trim().replace(/^\/api\/v1\/?/, "").replace(/^\/+/, "").replace(/\/+$/, "");
85
+ if (!cliPath) return "/";
86
+ return `/${cliPath.replace(/\{([^}]+)\}/g, ":$1")}`;
87
+ }
88
+ function pathParamNames(path) {
89
+ return [...path.matchAll(/\{([^}]+)\}/g)].map((match) => match[1]).filter((name) => Boolean(name));
90
+ }
91
+ function parseArgsParam(value) {
92
+ if (!value) return [];
93
+ const trimmed = value.trim();
94
+ if (!trimmed || trimmed === "[]" || trimmed.toLowerCase() === "null") return [];
95
+ try {
96
+ const parsed = JSON.parse(trimmed);
97
+ if (Array.isArray(parsed)) return parsed.map(String).filter(Boolean);
98
+ } catch {
99
+ }
100
+ return trimmed.split(",").map((part) => part.trim()).filter(Boolean);
101
+ }
102
+ export {
103
+ OperationActionDialog
104
+ };
105
+ //# sourceMappingURL=OperationActionDialog.js.map