@perses-dev/plugin-system 0.55.0-beta.1 → 0.55.0-beta.11

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 (577) hide show
  1. package/dist/components/Annotations/AnnotationEditorForm/AnnotationEditorForm.d.ts +3 -3
  2. package/dist/components/Annotations/AnnotationEditorForm/AnnotationEditorForm.d.ts.map +1 -1
  3. package/dist/components/Annotations/AnnotationEditorForm/AnnotationEditorForm.js +11 -11
  4. package/dist/components/Annotations/AnnotationEditorForm/AnnotationEditorForm.js.map +1 -1
  5. package/dist/components/Annotations/AnnotationEditorForm/AnnotationPreview.d.ts +3 -3
  6. package/dist/components/Annotations/AnnotationEditorForm/AnnotationPreview.d.ts.map +1 -1
  7. package/dist/components/Annotations/AnnotationEditorForm/AnnotationPreview.js +6 -6
  8. package/dist/components/Annotations/AnnotationEditorForm/AnnotationPreview.js.map +1 -1
  9. package/dist/components/Annotations/AnnotationEditorForm/index.js +1 -1
  10. package/dist/components/Annotations/AnnotationEditorForm/index.js.map +1 -1
  11. package/dist/components/Annotations/index.js +2 -2
  12. package/dist/components/Annotations/index.js.map +1 -1
  13. package/dist/components/CalculationSelector/CalculationSelector.d.ts +2 -2
  14. package/dist/components/CalculationSelector/CalculationSelector.d.ts.map +1 -1
  15. package/dist/components/CalculationSelector/CalculationSelector.js +2 -2
  16. package/dist/components/CalculationSelector/CalculationSelector.js.map +1 -1
  17. package/dist/components/CalculationSelector/index.js +1 -1
  18. package/dist/components/CalculationSelector/index.js.map +1 -1
  19. package/dist/components/DatasourceEditorForm/DatasourceEditorForm.d.ts +3 -2
  20. package/dist/components/DatasourceEditorForm/DatasourceEditorForm.d.ts.map +1 -1
  21. package/dist/components/DatasourceEditorForm/DatasourceEditorForm.js +10 -9
  22. package/dist/components/DatasourceEditorForm/DatasourceEditorForm.js.map +1 -1
  23. package/dist/components/DatasourceEditorForm/index.js +1 -1
  24. package/dist/components/DatasourceEditorForm/index.js.map +1 -1
  25. package/dist/components/DatasourceSelect/DatasourceSelect.d.ts +4 -4
  26. package/dist/components/DatasourceSelect/DatasourceSelect.d.ts.map +1 -1
  27. package/dist/components/DatasourceSelect/DatasourceSelect.js +7 -7
  28. package/dist/components/DatasourceSelect/DatasourceSelect.js.map +1 -1
  29. package/dist/components/DatasourceSelect/index.js +1 -1
  30. package/dist/components/DatasourceSelect/index.js.map +1 -1
  31. package/dist/components/DatasourceTestConnectionButton/DatasourceTestConnectionButton.d.ts +8 -0
  32. package/dist/components/DatasourceTestConnectionButton/DatasourceTestConnectionButton.d.ts.map +1 -0
  33. package/dist/components/DatasourceTestConnectionButton/DatasourceTestConnectionButton.js +45 -0
  34. package/dist/components/DatasourceTestConnectionButton/DatasourceTestConnectionButton.js.map +1 -0
  35. package/dist/components/DatasourceTestConnectionButton/index.d.ts +2 -0
  36. package/dist/components/DatasourceTestConnectionButton/index.d.ts.map +1 -0
  37. package/dist/{cjs/model/alerts-queries.js → components/DatasourceTestConnectionButton/index.js} +3 -4
  38. package/dist/components/DatasourceTestConnectionButton/index.js.map +1 -0
  39. package/dist/components/HTTPSettingsEditor/HTTPHeaderPolicyEditor.d.ts +10 -0
  40. package/dist/components/HTTPSettingsEditor/HTTPHeaderPolicyEditor.d.ts.map +1 -0
  41. package/dist/components/HTTPSettingsEditor/HTTPHeaderPolicyEditor.js +99 -0
  42. package/dist/components/HTTPSettingsEditor/HTTPHeaderPolicyEditor.js.map +1 -0
  43. package/dist/components/HTTPSettingsEditor/HTTPSettingsEditor.d.ts +4 -2
  44. package/dist/components/HTTPSettingsEditor/HTTPSettingsEditor.d.ts.map +1 -1
  45. package/dist/components/HTTPSettingsEditor/HTTPSettingsEditor.js +91 -41
  46. package/dist/components/HTTPSettingsEditor/HTTPSettingsEditor.js.map +1 -1
  47. package/dist/components/HTTPSettingsEditor/index.js +1 -1
  48. package/dist/components/HTTPSettingsEditor/index.js.map +1 -1
  49. package/dist/components/ItemSelectionActionsOptionsEditor/ItemSelectionActionsOptionsEditor.d.ts +1 -1
  50. package/dist/components/ItemSelectionActionsOptionsEditor/ItemSelectionActionsOptionsEditor.d.ts.map +1 -1
  51. package/dist/components/ItemSelectionActionsOptionsEditor/ItemSelectionActionsOptionsEditor.js +28 -28
  52. package/dist/components/ItemSelectionActionsOptionsEditor/ItemSelectionActionsOptionsEditor.js.map +1 -1
  53. package/dist/components/ItemSelectionActionsOptionsEditor/index.js +1 -1
  54. package/dist/components/ItemSelectionActionsOptionsEditor/index.js.map +1 -1
  55. package/dist/components/LayoutEditor/LayoutEditor.d.ts +16 -0
  56. package/dist/components/LayoutEditor/LayoutEditor.d.ts.map +1 -0
  57. package/dist/components/LayoutEditor/LayoutEditor.js +115 -0
  58. package/dist/components/LayoutEditor/LayoutEditor.js.map +1 -0
  59. package/dist/components/LayoutEditor/RepeatLayoutPreview.d.ts +7 -0
  60. package/dist/components/LayoutEditor/RepeatLayoutPreview.d.ts.map +1 -0
  61. package/dist/components/LayoutEditor/RepeatLayoutPreview.js +92 -0
  62. package/dist/components/LayoutEditor/RepeatLayoutPreview.js.map +1 -0
  63. package/dist/components/LayoutEditor/RepeatVariableEditor.d.ts +18 -0
  64. package/dist/components/LayoutEditor/RepeatVariableEditor.d.ts.map +1 -0
  65. package/dist/components/LayoutEditor/RepeatVariableEditor.js +168 -0
  66. package/dist/components/LayoutEditor/RepeatVariableEditor.js.map +1 -0
  67. package/dist/components/LayoutEditor/index.d.ts +4 -0
  68. package/dist/components/LayoutEditor/index.d.ts.map +1 -0
  69. package/dist/{cjs/model/explore.js → components/LayoutEditor/index.js} +5 -4
  70. package/dist/components/LayoutEditor/index.js.map +1 -0
  71. package/dist/components/LegendOptionsEditor/LegendOptionsEditor.d.ts +2 -2
  72. package/dist/components/LegendOptionsEditor/LegendOptionsEditor.d.ts.map +1 -1
  73. package/dist/components/LegendOptionsEditor/LegendOptionsEditor.js +5 -5
  74. package/dist/components/LegendOptionsEditor/LegendOptionsEditor.js.map +1 -1
  75. package/dist/components/LegendOptionsEditor/index.js +1 -1
  76. package/dist/components/LegendOptionsEditor/index.js.map +1 -1
  77. package/dist/components/LinksEditor/LinksEditor.d.ts +3 -3
  78. package/dist/components/LinksEditor/LinksEditor.d.ts.map +1 -1
  79. package/dist/components/LinksEditor/LinksEditor.js +6 -6
  80. package/dist/components/LinksEditor/LinksEditor.js.map +1 -1
  81. package/dist/components/LinksEditor/index.js +1 -1
  82. package/dist/components/LinksEditor/index.js.map +1 -1
  83. package/dist/components/MetricLabelInput/MetricLabelInput.d.ts +1 -1
  84. package/dist/components/MetricLabelInput/MetricLabelInput.d.ts.map +1 -1
  85. package/dist/components/MetricLabelInput/MetricLabelInput.js +2 -2
  86. package/dist/components/MetricLabelInput/MetricLabelInput.js.map +1 -1
  87. package/dist/components/MetricLabelInput/index.js +1 -1
  88. package/dist/components/MetricLabelInput/index.js.map +1 -1
  89. package/dist/components/MultiQueryEditor/MultiQueryEditor.d.ts +3 -4
  90. package/dist/components/MultiQueryEditor/MultiQueryEditor.d.ts.map +1 -1
  91. package/dist/components/MultiQueryEditor/MultiQueryEditor.js +27 -9
  92. package/dist/components/MultiQueryEditor/MultiQueryEditor.js.map +1 -1
  93. package/dist/components/MultiQueryEditor/QueryEditorContainer.d.ts +3 -4
  94. package/dist/components/MultiQueryEditor/QueryEditorContainer.d.ts.map +1 -1
  95. package/dist/components/MultiQueryEditor/QueryEditorContainer.js +14 -14
  96. package/dist/components/MultiQueryEditor/QueryEditorContainer.js.map +1 -1
  97. package/dist/components/MultiQueryEditor/index.js +2 -2
  98. package/dist/components/MultiQueryEditor/index.js.map +1 -1
  99. package/dist/components/MultiQueryEditor/utils.d.ts +1 -1
  100. package/dist/components/MultiQueryEditor/utils.d.ts.map +1 -1
  101. package/dist/components/MultiQueryEditor/utils.js.map +1 -1
  102. package/dist/components/OptionsEditorRadios/OptionsEditorRadios.d.ts +1 -1
  103. package/dist/components/OptionsEditorRadios/OptionsEditorRadios.d.ts.map +1 -1
  104. package/dist/components/OptionsEditorRadios/OptionsEditorRadios.js +4 -4
  105. package/dist/components/OptionsEditorRadios/OptionsEditorRadios.js.map +1 -1
  106. package/dist/components/OptionsEditorRadios/index.js +1 -1
  107. package/dist/components/OptionsEditorRadios/index.js.map +1 -1
  108. package/dist/components/OptionsEditorTabPanel/OptionsEditorTabPanel.d.ts +1 -1
  109. package/dist/components/OptionsEditorTabPanel/OptionsEditorTabPanel.d.ts.map +1 -1
  110. package/dist/components/OptionsEditorTabPanel/OptionsEditorTabPanel.js +1 -1
  111. package/dist/components/OptionsEditorTabPanel/OptionsEditorTabPanel.js.map +1 -1
  112. package/dist/components/OptionsEditorTabPanel/index.js +1 -1
  113. package/dist/components/OptionsEditorTabPanel/index.js.map +1 -1
  114. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.d.ts +1 -1
  115. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.d.ts.map +1 -1
  116. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.js +4 -4
  117. package/dist/components/OptionsEditorTabs/OptionsEditorTabs.js.map +1 -1
  118. package/dist/components/OptionsEditorTabs/index.js +1 -1
  119. package/dist/components/OptionsEditorTabs/index.js.map +1 -1
  120. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.d.ts +2 -2
  121. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.d.ts.map +1 -1
  122. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.js +9 -9
  123. package/dist/components/PanelSpecEditor/PanelAnnotationsEditor.js.map +1 -1
  124. package/dist/components/PanelSpecEditor/PanelSpecEditor.d.ts +8 -5
  125. package/dist/components/PanelSpecEditor/PanelSpecEditor.d.ts.map +1 -1
  126. package/dist/components/PanelSpecEditor/PanelSpecEditor.js +27 -12
  127. package/dist/components/PanelSpecEditor/PanelSpecEditor.js.map +1 -1
  128. package/dist/components/PanelSpecEditor/index.js +1 -1
  129. package/dist/components/PanelSpecEditor/index.js.map +1 -1
  130. package/dist/components/PluginEditor/PluginEditor.d.ts +2 -2
  131. package/dist/components/PluginEditor/PluginEditor.d.ts.map +1 -1
  132. package/dist/components/PluginEditor/PluginEditor.js +10 -9
  133. package/dist/components/PluginEditor/PluginEditor.js.map +1 -1
  134. package/dist/components/PluginEditor/index.js +2 -2
  135. package/dist/components/PluginEditor/index.js.map +1 -1
  136. package/dist/components/PluginEditor/plugin-editor-api.d.ts +10 -3
  137. package/dist/components/PluginEditor/plugin-editor-api.d.ts.map +1 -1
  138. package/dist/components/PluginEditor/plugin-editor-api.js +10 -5
  139. package/dist/components/PluginEditor/plugin-editor-api.js.map +1 -1
  140. package/dist/components/PluginKindSelect/PluginKindSelect.d.ts +17 -4
  141. package/dist/components/PluginKindSelect/PluginKindSelect.d.ts.map +1 -1
  142. package/dist/components/PluginKindSelect/PluginKindSelect.js +191 -27
  143. package/dist/components/PluginKindSelect/PluginKindSelect.js.map +1 -1
  144. package/dist/components/PluginKindSelect/index.js +1 -1
  145. package/dist/components/PluginKindSelect/index.js.map +1 -1
  146. package/dist/components/PluginRegistry/PluginRegistry.d.ts +2 -2
  147. package/dist/components/PluginRegistry/PluginRegistry.d.ts.map +1 -1
  148. package/dist/components/PluginRegistry/PluginRegistry.js +71 -8
  149. package/dist/components/PluginRegistry/PluginRegistry.js.map +1 -1
  150. package/dist/components/PluginRegistry/getPluginSearchHelper.d.ts +2 -2
  151. package/dist/components/PluginRegistry/getPluginSearchHelper.d.ts.map +1 -1
  152. package/dist/components/PluginRegistry/getPluginSearchHelper.js +2 -2
  153. package/dist/components/PluginRegistry/getPluginSearchHelper.js.map +1 -1
  154. package/dist/components/PluginRegistry/index.js +1 -1
  155. package/dist/components/PluginRegistry/index.js.map +1 -1
  156. package/dist/components/PluginRegistry/plugin-indexes.d.ts +3 -1
  157. package/dist/components/PluginRegistry/plugin-indexes.d.ts.map +1 -1
  158. package/dist/components/PluginRegistry/plugin-indexes.js +9 -4
  159. package/dist/components/PluginRegistry/plugin-indexes.js.map +1 -1
  160. package/dist/components/PluginSpecEditor/DatasourceSpecEditor.d.ts +10 -0
  161. package/dist/components/PluginSpecEditor/DatasourceSpecEditor.d.ts.map +1 -0
  162. package/dist/components/PluginSpecEditor/DatasourceSpecEditor.js +62 -0
  163. package/dist/components/PluginSpecEditor/DatasourceSpecEditor.js.map +1 -0
  164. package/dist/components/PluginSpecEditor/PluginSpecEditor.d.ts +5 -4
  165. package/dist/components/PluginSpecEditor/PluginSpecEditor.d.ts.map +1 -1
  166. package/dist/components/PluginSpecEditor/PluginSpecEditor.js +24 -6
  167. package/dist/components/PluginSpecEditor/PluginSpecEditor.js.map +1 -1
  168. package/dist/components/PluginSpecEditor/index.js +1 -1
  169. package/dist/components/PluginSpecEditor/index.js.map +1 -1
  170. package/dist/components/SelectionOptionsEditor/SelectionOptionsEditor.d.ts +1 -1
  171. package/dist/components/SelectionOptionsEditor/SelectionOptionsEditor.d.ts.map +1 -1
  172. package/dist/components/SelectionOptionsEditor/SelectionOptionsEditor.js +3 -3
  173. package/dist/components/SelectionOptionsEditor/SelectionOptionsEditor.js.map +1 -1
  174. package/dist/components/SelectionOptionsEditor/index.js +1 -1
  175. package/dist/components/SelectionOptionsEditor/index.js.map +1 -1
  176. package/dist/components/TimeRangeControls/TimeRangeControls.d.ts +4 -4
  177. package/dist/components/TimeRangeControls/TimeRangeControls.d.ts.map +1 -1
  178. package/dist/components/TimeRangeControls/TimeRangeControls.js +18 -55
  179. package/dist/components/TimeRangeControls/TimeRangeControls.js.map +1 -1
  180. package/dist/components/TimeRangeControls/index.js +1 -1
  181. package/dist/components/TimeRangeControls/index.js.map +1 -1
  182. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.d.ts +3 -3
  183. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.d.ts.map +1 -1
  184. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js +11 -11
  185. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js.map +1 -1
  186. package/dist/components/Variables/VariableEditorForm/VariablePreview.d.ts +2 -2
  187. package/dist/components/Variables/VariableEditorForm/VariablePreview.d.ts.map +1 -1
  188. package/dist/components/Variables/VariableEditorForm/VariablePreview.js +8 -7
  189. package/dist/components/Variables/VariableEditorForm/VariablePreview.js.map +1 -1
  190. package/dist/components/Variables/VariableEditorForm/index.js +3 -3
  191. package/dist/components/Variables/VariableEditorForm/index.js.map +1 -1
  192. package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.d.ts +2 -2
  193. package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.d.ts.map +1 -1
  194. package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.js +6 -6
  195. package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.js.map +1 -1
  196. package/dist/components/Variables/index.js +2 -2
  197. package/dist/components/Variables/index.js.map +1 -1
  198. package/dist/components/Variables/variable-model.d.ts +8 -8
  199. package/dist/components/Variables/variable-model.d.ts.map +1 -1
  200. package/dist/components/Variables/variable-model.js +10 -5
  201. package/dist/components/Variables/variable-model.js.map +1 -1
  202. package/dist/components/index.d.ts +2 -0
  203. package/dist/components/index.d.ts.map +1 -1
  204. package/dist/components/index.js +21 -19
  205. package/dist/components/index.js.map +1 -1
  206. package/dist/constants/index.d.ts +1 -0
  207. package/dist/constants/index.d.ts.map +1 -1
  208. package/dist/constants/index.js +2 -1
  209. package/dist/constants/index.js.map +1 -1
  210. package/dist/constants/repeat.d.ts +3 -0
  211. package/dist/constants/repeat.d.ts.map +1 -0
  212. package/dist/{cjs/model/datasource.js → constants/repeat.js} +4 -4
  213. package/dist/constants/repeat.js.map +1 -0
  214. package/dist/constants/user-interface-text.d.ts.map +1 -1
  215. package/dist/context/ValidationProvider.d.ts +9 -9
  216. package/dist/context/ValidationProvider.d.ts.map +1 -1
  217. package/dist/context/ValidationProvider.js +6 -6
  218. package/dist/context/ValidationProvider.js.map +1 -1
  219. package/dist/context/index.js +1 -1
  220. package/dist/context/index.js.map +1 -1
  221. package/dist/index.js +9 -9
  222. package/dist/index.js.map +1 -1
  223. package/dist/model/alerts-queries.d.ts +4 -4
  224. package/dist/model/alerts-queries.d.ts.map +1 -1
  225. package/dist/model/alerts-queries.js.map +1 -1
  226. package/dist/model/annotations.d.ts +3 -3
  227. package/dist/model/annotations.d.ts.map +1 -1
  228. package/dist/model/annotations.js.map +1 -1
  229. package/dist/model/calculations.d.ts +1 -1
  230. package/dist/model/calculations.d.ts.map +1 -1
  231. package/dist/model/calculations.js.map +1 -1
  232. package/dist/model/datasource.d.ts +10 -3
  233. package/dist/model/datasource.d.ts.map +1 -1
  234. package/dist/model/datasource.js +1 -1
  235. package/dist/model/datasource.js.map +1 -1
  236. package/dist/model/explore.d.ts +2 -3
  237. package/dist/model/explore.d.ts.map +1 -1
  238. package/dist/model/explore.js.map +1 -1
  239. package/dist/model/index.d.ts +1 -0
  240. package/dist/model/index.d.ts.map +1 -1
  241. package/dist/model/index.js +17 -16
  242. package/dist/model/index.js.map +1 -1
  243. package/dist/model/json-queries.d.ts +29 -0
  244. package/dist/model/json-queries.d.ts.map +1 -0
  245. package/dist/{cjs/model/annotations.js → model/json-queries.js} +5 -4
  246. package/dist/model/json-queries.js.map +1 -0
  247. package/dist/model/legend.d.ts +3 -3
  248. package/dist/model/legend.d.ts.map +1 -1
  249. package/dist/model/legend.js +2 -2
  250. package/dist/model/legend.js.map +1 -1
  251. package/dist/model/log-queries.d.ts +3 -3
  252. package/dist/model/log-queries.d.ts.map +1 -1
  253. package/dist/model/log-queries.js.map +1 -1
  254. package/dist/model/panels.d.ts +13 -4
  255. package/dist/model/panels.d.ts.map +1 -1
  256. package/dist/model/panels.js.map +1 -1
  257. package/dist/model/plugin-base.d.ts +3 -3
  258. package/dist/model/plugin-base.d.ts.map +1 -1
  259. package/dist/model/plugin-base.js.map +1 -1
  260. package/dist/model/plugin-loading.d.ts +1 -1
  261. package/dist/model/plugin-loading.d.ts.map +1 -1
  262. package/dist/model/plugin-loading.js +1 -1
  263. package/dist/model/plugin-loading.js.map +1 -1
  264. package/dist/model/plugins.d.ts +26 -13
  265. package/dist/model/plugins.d.ts.map +1 -1
  266. package/dist/model/plugins.js.map +1 -1
  267. package/dist/model/profile-queries.d.ts +4 -4
  268. package/dist/model/profile-queries.d.ts.map +1 -1
  269. package/dist/model/profile-queries.js.map +1 -1
  270. package/dist/model/silences-queries.d.ts +4 -4
  271. package/dist/model/silences-queries.d.ts.map +1 -1
  272. package/dist/model/silences-queries.js.map +1 -1
  273. package/dist/model/time-series-queries.d.ts +4 -4
  274. package/dist/model/time-series-queries.d.ts.map +1 -1
  275. package/dist/model/time-series-queries.js.map +1 -1
  276. package/dist/model/trace-queries.d.ts +4 -4
  277. package/dist/model/trace-queries.d.ts.map +1 -1
  278. package/dist/model/trace-queries.js.map +1 -1
  279. package/dist/model/variables.d.ts +7 -3
  280. package/dist/model/variables.d.ts.map +1 -1
  281. package/dist/model/variables.js +1 -3
  282. package/dist/model/variables.js.map +1 -1
  283. package/dist/remote/PluginLoaderComponent.d.ts +1 -2
  284. package/dist/remote/PluginLoaderComponent.d.ts.map +1 -1
  285. package/dist/remote/PluginLoaderComponent.js +2 -2
  286. package/dist/remote/PluginLoaderComponent.js.map +1 -1
  287. package/dist/remote/PluginRuntime.d.ts +11 -2
  288. package/dist/remote/PluginRuntime.d.ts.map +1 -1
  289. package/dist/remote/PluginRuntime.js +84 -79
  290. package/dist/remote/PluginRuntime.js.map +1 -1
  291. package/dist/remote/index.d.ts +1 -0
  292. package/dist/remote/index.d.ts.map +1 -1
  293. package/dist/remote/index.js +3 -2
  294. package/dist/remote/index.js.map +1 -1
  295. package/dist/remote/remotePluginLoader.d.ts +2 -2
  296. package/dist/remote/remotePluginLoader.d.ts.map +1 -1
  297. package/dist/remote/remotePluginLoader.js +3 -3
  298. package/dist/remote/remotePluginLoader.js.map +1 -1
  299. package/dist/runtime/DataQueriesProvider/DataQueriesProvider.d.ts +3 -3
  300. package/dist/runtime/DataQueriesProvider/DataQueriesProvider.d.ts.map +1 -1
  301. package/dist/runtime/DataQueriesProvider/DataQueriesProvider.js +20 -12
  302. package/dist/runtime/DataQueriesProvider/DataQueriesProvider.js.map +1 -1
  303. package/dist/runtime/DataQueriesProvider/index.js +2 -2
  304. package/dist/runtime/DataQueriesProvider/index.js.map +1 -1
  305. package/dist/runtime/DataQueriesProvider/model.d.ts +3 -3
  306. package/dist/runtime/DataQueriesProvider/model.d.ts.map +1 -1
  307. package/dist/runtime/DataQueriesProvider/model.js.map +1 -1
  308. package/dist/runtime/RouterProvider.d.ts +2 -1
  309. package/dist/runtime/RouterProvider.d.ts.map +1 -1
  310. package/dist/runtime/RouterProvider.js +3 -3
  311. package/dist/runtime/RouterProvider.js.map +1 -1
  312. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.d.ts +3 -2
  313. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.d.ts.map +1 -1
  314. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.js +22 -8
  315. package/dist/runtime/TimeRangeProvider/TimeRangeProvider.js.map +1 -1
  316. package/dist/runtime/TimeRangeProvider/TimeRangeProviders.d.ts +3 -2
  317. package/dist/runtime/TimeRangeProvider/TimeRangeProviders.d.ts.map +1 -1
  318. package/dist/runtime/TimeRangeProvider/TimeRangeProviders.js +5 -5
  319. package/dist/runtime/TimeRangeProvider/TimeRangeProviders.js.map +1 -1
  320. package/dist/runtime/TimeRangeProvider/TimeRangeSettingsProvider.d.ts +13 -2
  321. package/dist/runtime/TimeRangeProvider/TimeRangeSettingsProvider.d.ts.map +1 -1
  322. package/dist/runtime/TimeRangeProvider/TimeRangeSettingsProvider.js +65 -4
  323. package/dist/runtime/TimeRangeProvider/TimeRangeSettingsProvider.js.map +1 -1
  324. package/dist/runtime/TimeRangeProvider/index.js +4 -4
  325. package/dist/runtime/TimeRangeProvider/index.js.map +1 -1
  326. package/dist/runtime/TimeRangeProvider/query-params.d.ts +3 -3
  327. package/dist/runtime/TimeRangeProvider/query-params.d.ts.map +1 -1
  328. package/dist/runtime/TimeRangeProvider/query-params.js +4 -4
  329. package/dist/runtime/TimeRangeProvider/query-params.js.map +1 -1
  330. package/dist/runtime/TimeRangeProvider/refresh-interval.d.ts +1 -1
  331. package/dist/runtime/TimeRangeProvider/refresh-interval.d.ts.map +1 -1
  332. package/dist/runtime/TimeRangeProvider/refresh-interval.js +2 -2
  333. package/dist/runtime/TimeRangeProvider/refresh-interval.js.map +1 -1
  334. package/dist/runtime/UsageMetricsProvider.d.ts +3 -3
  335. package/dist/runtime/UsageMetricsProvider.d.ts.map +1 -1
  336. package/dist/runtime/UsageMetricsProvider.js +3 -3
  337. package/dist/runtime/UsageMetricsProvider.js.map +1 -1
  338. package/dist/runtime/alerts-queries.d.ts +2 -2
  339. package/dist/runtime/alerts-queries.d.ts.map +1 -1
  340. package/dist/runtime/alerts-queries.js +11 -7
  341. package/dist/runtime/alerts-queries.js.map +1 -1
  342. package/dist/runtime/annotations.d.ts +2 -2
  343. package/dist/runtime/annotations.d.ts.map +1 -1
  344. package/dist/runtime/annotations.js +16 -9
  345. package/dist/runtime/annotations.js.map +1 -1
  346. package/dist/runtime/builtin-variables.d.ts +2 -3
  347. package/dist/runtime/builtin-variables.d.ts.map +1 -1
  348. package/dist/runtime/builtin-variables.js +1 -1
  349. package/dist/runtime/builtin-variables.js.map +1 -1
  350. package/dist/runtime/datasources.d.ts +2 -3
  351. package/dist/runtime/datasources.d.ts.map +1 -1
  352. package/dist/runtime/datasources.js +2 -2
  353. package/dist/runtime/datasources.js.map +1 -1
  354. package/dist/runtime/index.d.ts +1 -0
  355. package/dist/runtime/index.d.ts.map +1 -1
  356. package/dist/runtime/index.js +16 -15
  357. package/dist/runtime/index.js.map +1 -1
  358. package/dist/runtime/item-actions.d.ts +3 -3
  359. package/dist/runtime/item-actions.d.ts.map +1 -1
  360. package/dist/runtime/item-actions.js +2 -2
  361. package/dist/runtime/item-actions.js.map +1 -1
  362. package/dist/runtime/json-queries.d.ts +11 -0
  363. package/dist/runtime/json-queries.d.ts.map +1 -0
  364. package/dist/runtime/json-queries.js +58 -0
  365. package/dist/runtime/json-queries.js.map +1 -0
  366. package/dist/runtime/log-queries.d.ts +3 -3
  367. package/dist/runtime/log-queries.d.ts.map +1 -1
  368. package/dist/runtime/log-queries.js +8 -6
  369. package/dist/runtime/log-queries.js.map +1 -1
  370. package/dist/runtime/plugin-registry.d.ts +24 -11
  371. package/dist/runtime/plugin-registry.d.ts.map +1 -1
  372. package/dist/runtime/plugin-registry.js +54 -18
  373. package/dist/runtime/plugin-registry.js.map +1 -1
  374. package/dist/runtime/profile-queries.d.ts +2 -2
  375. package/dist/runtime/profile-queries.d.ts.map +1 -1
  376. package/dist/runtime/profile-queries.js +7 -5
  377. package/dist/runtime/profile-queries.js.map +1 -1
  378. package/dist/runtime/silences-queries.d.ts +2 -2
  379. package/dist/runtime/silences-queries.d.ts.map +1 -1
  380. package/dist/runtime/silences-queries.js +11 -7
  381. package/dist/runtime/silences-queries.js.map +1 -1
  382. package/dist/runtime/time-series-queries.d.ts +3 -3
  383. package/dist/runtime/time-series-queries.d.ts.map +1 -1
  384. package/dist/runtime/time-series-queries.js +16 -9
  385. package/dist/runtime/time-series-queries.js.map +1 -1
  386. package/dist/runtime/trace-queries.d.ts +2 -2
  387. package/dist/runtime/trace-queries.d.ts.map +1 -1
  388. package/dist/runtime/trace-queries.js +12 -8
  389. package/dist/runtime/trace-queries.js.map +1 -1
  390. package/dist/runtime/utils.d.ts +1 -1
  391. package/dist/runtime/utils.d.ts.map +1 -1
  392. package/dist/runtime/utils.js.map +1 -1
  393. package/dist/runtime/variables.d.ts +7 -2
  394. package/dist/runtime/variables.d.ts.map +1 -1
  395. package/dist/runtime/variables.js +20 -4
  396. package/dist/runtime/variables.js.map +1 -1
  397. package/dist/schema/index.js +1 -1
  398. package/dist/schema/index.js.map +1 -1
  399. package/dist/schema/panel.d.ts +4 -4
  400. package/dist/schema/panel.d.ts.map +1 -1
  401. package/dist/schema/panel.js +18 -4
  402. package/dist/schema/panel.js.map +1 -1
  403. package/dist/test/index.js +2 -2
  404. package/dist/test/index.js.map +1 -1
  405. package/dist/test/mock-data.d.ts +14 -13
  406. package/dist/test/mock-data.d.ts.map +1 -1
  407. package/dist/test/mock-data.js +6 -0
  408. package/dist/test/mock-data.js.map +1 -1
  409. package/dist/test/render-hook.d.ts +2 -2
  410. package/dist/test/render-hook.d.ts.map +1 -1
  411. package/dist/test/render-hook.js +2 -2
  412. package/dist/test/render-hook.js.map +1 -1
  413. package/dist/test/render.d.ts +3 -3
  414. package/dist/test/render.d.ts.map +1 -1
  415. package/dist/test/render.js +3 -3
  416. package/dist/test/render.js.map +1 -1
  417. package/dist/test/setup-tests.d.ts +1 -1
  418. package/dist/test/setup-tests.d.ts.map +1 -1
  419. package/dist/test/setup-tests.js +3 -2
  420. package/dist/test/setup-tests.js.map +1 -1
  421. package/dist/test/test-plugins/bert/index.d.ts +3 -3
  422. package/dist/test/test-plugins/bert/index.d.ts.map +1 -1
  423. package/dist/test/test-plugins/bert/index.js.map +1 -1
  424. package/dist/test/test-plugins/ernie/index.d.ts +7 -1
  425. package/dist/test/test-plugins/ernie/index.d.ts.map +1 -1
  426. package/dist/test/test-plugins/ernie/index.js +58 -1
  427. package/dist/test/test-plugins/ernie/index.js.map +1 -1
  428. package/dist/test/test-plugins/index.d.ts +1 -1
  429. package/dist/test/test-plugins/index.d.ts.map +1 -1
  430. package/dist/test/test-plugins/index.js +5 -5
  431. package/dist/test/test-plugins/index.js.map +1 -1
  432. package/dist/test/utils.d.ts +2 -2
  433. package/dist/test/utils.d.ts.map +1 -1
  434. package/dist/test/utils.js +5 -5
  435. package/dist/test/utils.js.map +1 -1
  436. package/dist/test-utils/index.js +1 -1
  437. package/dist/test-utils/index.js.map +1 -1
  438. package/dist/test-utils/mock-plugin-registry.d.ts +2 -2
  439. package/dist/test-utils/mock-plugin-registry.d.ts.map +1 -1
  440. package/dist/test-utils/mock-plugin-registry.js +1 -1
  441. package/dist/test-utils/mock-plugin-registry.js.map +1 -1
  442. package/dist/utils/csv-export.d.ts.map +1 -1
  443. package/dist/utils/csv-export.js +2 -2
  444. package/dist/utils/csv-export.js.map +1 -1
  445. package/dist/utils/event.js +1 -1
  446. package/dist/utils/index.d.ts +1 -0
  447. package/dist/utils/index.d.ts.map +1 -1
  448. package/dist/utils/index.js +4 -3
  449. package/dist/utils/index.js.map +1 -1
  450. package/dist/utils/plugin-versions.d.ts +18 -0
  451. package/dist/utils/plugin-versions.d.ts.map +1 -0
  452. package/dist/utils/plugin-versions.js +52 -0
  453. package/dist/utils/plugin-versions.js.map +1 -0
  454. package/dist/utils/variables.js +1 -1
  455. package/package.json +18 -17
  456. package/dist/cjs/components/Annotations/AnnotationEditorForm/AnnotationEditorForm.js +0 -283
  457. package/dist/cjs/components/Annotations/AnnotationEditorForm/AnnotationPreview.js +0 -197
  458. package/dist/cjs/components/Annotations/AnnotationEditorForm/index.js +0 -30
  459. package/dist/cjs/components/Annotations/constants.js +0 -23
  460. package/dist/cjs/components/Annotations/index.js +0 -31
  461. package/dist/cjs/components/CalculationSelector/CalculationSelector.js +0 -49
  462. package/dist/cjs/components/CalculationSelector/index.js +0 -30
  463. package/dist/cjs/components/DatasourceEditorForm/DatasourceEditorForm.js +0 -270
  464. package/dist/cjs/components/DatasourceEditorForm/index.js +0 -30
  465. package/dist/cjs/components/DatasourceSelect/DatasourceSelect.js +0 -266
  466. package/dist/cjs/components/DatasourceSelect/index.js +0 -30
  467. package/dist/cjs/components/HTTPSettingsEditor/HTTPSettingsEditor.js +0 -568
  468. package/dist/cjs/components/HTTPSettingsEditor/index.js +0 -30
  469. package/dist/cjs/components/ItemSelectionActionsOptionsEditor/ItemSelectionActionsOptionsEditor.js +0 -1175
  470. package/dist/cjs/components/ItemSelectionActionsOptionsEditor/index.js +0 -30
  471. package/dist/cjs/components/LegendOptionsEditor/LegendOptionsEditor.js +0 -211
  472. package/dist/cjs/components/LegendOptionsEditor/index.js +0 -30
  473. package/dist/cjs/components/LinksEditor/LinksEditor.js +0 -162
  474. package/dist/cjs/components/LinksEditor/index.js +0 -30
  475. package/dist/cjs/components/MetricLabelInput/MetricLabelInput.js +0 -41
  476. package/dist/cjs/components/MetricLabelInput/index.js +0 -30
  477. package/dist/cjs/components/MultiQueryEditor/MultiQueryEditor.js +0 -159
  478. package/dist/cjs/components/MultiQueryEditor/QueryEditorContainer.js +0 -250
  479. package/dist/cjs/components/MultiQueryEditor/index.js +0 -31
  480. package/dist/cjs/components/MultiQueryEditor/utils.js +0 -36
  481. package/dist/cjs/components/OptionsEditorRadios/OptionsEditorRadios.js +0 -69
  482. package/dist/cjs/components/OptionsEditorRadios/index.js +0 -30
  483. package/dist/cjs/components/OptionsEditorTabPanel/OptionsEditorTabPanel.js +0 -39
  484. package/dist/cjs/components/OptionsEditorTabPanel/index.js +0 -30
  485. package/dist/cjs/components/OptionsEditorTabs/OptionsEditorTabs.js +0 -61
  486. package/dist/cjs/components/OptionsEditorTabs/index.js +0 -30
  487. package/dist/cjs/components/PanelSpecEditor/PanelAnnotationsEditor.js +0 -246
  488. package/dist/cjs/components/PanelSpecEditor/PanelSpecEditor.js +0 -132
  489. package/dist/cjs/components/PanelSpecEditor/index.js +0 -30
  490. package/dist/cjs/components/PluginEditor/PluginEditor.js +0 -98
  491. package/dist/cjs/components/PluginEditor/index.js +0 -31
  492. package/dist/cjs/components/PluginEditor/plugin-editor-api.js +0 -136
  493. package/dist/cjs/components/PluginKindSelect/PluginKindSelect.js +0 -109
  494. package/dist/cjs/components/PluginKindSelect/index.js +0 -30
  495. package/dist/cjs/components/PluginRegistry/PluginRegistry.js +0 -86
  496. package/dist/cjs/components/PluginRegistry/getPluginSearchHelper.js +0 -92
  497. package/dist/cjs/components/PluginRegistry/index.js +0 -30
  498. package/dist/cjs/components/PluginRegistry/plugin-indexes.js +0 -88
  499. package/dist/cjs/components/PluginSpecEditor/PluginSpecEditor.js +0 -55
  500. package/dist/cjs/components/PluginSpecEditor/index.js +0 -30
  501. package/dist/cjs/components/SelectionOptionsEditor/SelectionOptionsEditor.js +0 -43
  502. package/dist/cjs/components/SelectionOptionsEditor/index.js +0 -30
  503. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.js +0 -236
  504. package/dist/cjs/components/TimeRangeControls/index.js +0 -30
  505. package/dist/cjs/components/Variables/VariableEditorForm/VariableEditorForm.js +0 -613
  506. package/dist/cjs/components/Variables/VariableEditorForm/VariablePreview.js +0 -193
  507. package/dist/cjs/components/Variables/VariableEditorForm/index.js +0 -32
  508. package/dist/cjs/components/Variables/VariableEditorForm/variable-editor-form-model.js +0 -143
  509. package/dist/cjs/components/Variables/index.js +0 -31
  510. package/dist/cjs/components/Variables/variable-model.js +0 -211
  511. package/dist/cjs/components/index.js +0 -48
  512. package/dist/cjs/constants/index.js +0 -30
  513. package/dist/cjs/constants/user-interface-text.js +0 -32
  514. package/dist/cjs/context/ValidationProvider.js +0 -77
  515. package/dist/cjs/context/index.js +0 -30
  516. package/dist/cjs/index.js +0 -38
  517. package/dist/cjs/model/calculations.js +0 -178
  518. package/dist/cjs/model/index.js +0 -45
  519. package/dist/cjs/model/legend.js +0 -111
  520. package/dist/cjs/model/log-queries.js +0 -16
  521. package/dist/cjs/model/log-volume-utils.js +0 -124
  522. package/dist/cjs/model/panels.js +0 -16
  523. package/dist/cjs/model/plugin-base.js +0 -16
  524. package/dist/cjs/model/plugin-loading.js +0 -56
  525. package/dist/cjs/model/plugins.js +0 -26
  526. package/dist/cjs/model/profile-queries.js +0 -16
  527. package/dist/cjs/model/silences-queries.js +0 -16
  528. package/dist/cjs/model/time-series-queries.js +0 -26
  529. package/dist/cjs/model/trace-queries.js +0 -16
  530. package/dist/cjs/model/variables.js +0 -16
  531. package/dist/cjs/remote/PersesPlugin.types.js +0 -16
  532. package/dist/cjs/remote/PluginLoaderComponent.js +0 -87
  533. package/dist/cjs/remote/PluginRuntime.js +0 -331
  534. package/dist/cjs/remote/index.js +0 -31
  535. package/dist/cjs/remote/remotePluginLoader.js +0 -101
  536. package/dist/cjs/runtime/DataQueriesProvider/DataQueriesProvider.js +0 -154
  537. package/dist/cjs/runtime/DataQueriesProvider/index.js +0 -31
  538. package/dist/cjs/runtime/DataQueriesProvider/model.js +0 -34
  539. package/dist/cjs/runtime/RouterProvider.js +0 -114
  540. package/dist/cjs/runtime/TimeRangeProvider/TimeRangeProvider.js +0 -201
  541. package/dist/cjs/runtime/TimeRangeProvider/TimeRangeProviders.js +0 -66
  542. package/dist/cjs/runtime/TimeRangeProvider/TimeRangeSettingsProvider.js +0 -113
  543. package/dist/cjs/runtime/TimeRangeProvider/index.js +0 -33
  544. package/dist/cjs/runtime/TimeRangeProvider/query-params.js +0 -250
  545. package/dist/cjs/runtime/TimeRangeProvider/refresh-interval.js +0 -30
  546. package/dist/cjs/runtime/UsageMetricsProvider.js +0 -102
  547. package/dist/cjs/runtime/alerts-queries.js +0 -101
  548. package/dist/cjs/runtime/annotations.js +0 -148
  549. package/dist/cjs/runtime/builtin-variables.js +0 -81
  550. package/dist/cjs/runtime/datasources.js +0 -80
  551. package/dist/cjs/runtime/index.js +0 -44
  552. package/dist/cjs/runtime/item-actions.js +0 -302
  553. package/dist/cjs/runtime/log-queries.js +0 -76
  554. package/dist/cjs/runtime/plugin-registry.js +0 -135
  555. package/dist/cjs/runtime/profile-queries.js +0 -73
  556. package/dist/cjs/runtime/silences-queries.js +0 -101
  557. package/dist/cjs/runtime/time-series-queries.js +0 -165
  558. package/dist/cjs/runtime/trace-queries.js +0 -106
  559. package/dist/cjs/runtime/utils.js +0 -39
  560. package/dist/cjs/runtime/variables.js +0 -160
  561. package/dist/cjs/schema/index.js +0 -30
  562. package/dist/cjs/schema/panel.js +0 -42
  563. package/dist/cjs/test/index.js +0 -31
  564. package/dist/cjs/test/mock-data.js +0 -357
  565. package/dist/cjs/test/render-hook.js +0 -31
  566. package/dist/cjs/test/render.js +0 -31
  567. package/dist/cjs/test/setup-tests.js +0 -20
  568. package/dist/cjs/test/test-plugins/bert/index.js +0 -99
  569. package/dist/cjs/test/test-plugins/ernie/index.js +0 -92
  570. package/dist/cjs/test/test-plugins/index.js +0 -81
  571. package/dist/cjs/test/utils.js +0 -58
  572. package/dist/cjs/test-utils/index.js +0 -30
  573. package/dist/cjs/test-utils/mock-plugin-registry.js +0 -81
  574. package/dist/cjs/utils/csv-export.js +0 -248
  575. package/dist/cjs/utils/event.js +0 -30
  576. package/dist/cjs/utils/index.js +0 -32
  577. package/dist/cjs/utils/variables.js +0 -44
@@ -10,10 +10,10 @@
10
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
- import { useState, useRef, useEffect } from 'react';
14
- import { produce } from 'immer';
15
- import { usePlugin, usePluginRegistry } from '../../runtime';
16
- import { useEvent } from '../../utils';
13
+ import { produce } from "immer";
14
+ import { useState, useRef, useEffect } from "react";
15
+ import { usePlugin, usePluginRegistry } from "../../runtime/index.js";
16
+ import { useEvent } from "../../utils/index.js";
17
17
  /**
18
18
  * Returns the state/handlers that power the `PluginEditor` component. Useful for custom components that want to provide
19
19
  * a different UI, but want the same behavior of changing `kind` and `spec` together on plugin kind changes. Also
@@ -63,7 +63,12 @@ import { useEvent } from '../../utils';
63
63
  value.selection,
64
64
  defaultPluginKind
65
65
  ]);
66
- const { data: plugin, isFetching, error } = usePlugin(pendingSelection?.type, pendingSelection?.kind || '');
66
+ // Load the pending plugin honoring the pinned version/registry, so the initial options come from the exact
67
+ // implementation the definition will use rather than from the latest one.
68
+ const { data: plugin, isFetching, error } = usePlugin(pendingSelection?.type, pendingSelection?.kind || '', {
69
+ version: pendingSelection?.metadata?.version,
70
+ registry: pendingSelection?.metadata?.registry
71
+ });
67
72
  useEffect(()=>{
68
73
  // Nothing to do if no new plugin kind is pending
69
74
  if (!pendingSelection) return;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/PluginEditor/plugin-editor-api.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { BoxProps } from '@mui/material';\nimport { UnknownSpec } from '@perses-dev/spec';\nimport { useState, useRef, useEffect } from 'react';\nimport { produce } from 'immer';\nimport { PanelPlugin, PluginType } from '../../model';\nimport { PluginKindSelectProps } from '../PluginKindSelect';\nimport { PluginSpecEditorProps } from '../PluginSpecEditor';\nimport { usePlugin, usePluginRegistry } from '../../runtime';\nimport { useEvent } from '../../utils';\n\nexport interface PluginEditorSelection {\n type: PluginType;\n kind: string;\n}\n\nexport interface PluginEditorValue {\n selection: PluginEditorSelection;\n spec: UnknownSpec;\n}\n\n// Props on MUI Box that we don't want people to pass because we're either redefining them or providing them in\n// this component\ntype OmittedMuiProps = 'children' | 'value' | 'onChange';\n\nexport interface PluginEditorProps extends Omit<BoxProps, OmittedMuiProps> {\n pluginTypes: PluginType[];\n pluginKindLabel: string;\n value: PluginEditorValue;\n isReadonly?: boolean;\n withRunQueryButton?: boolean;\n filteredQueryPlugins?: string[];\n onChange: (next: PluginEditorValue) => void;\n onRunQuery?: () => void;\n}\n\nexport interface PluginEditorRef {\n flushChanges?: () => void;\n}\n\ntype PreviousSpecState = Record<string, Record<string, UnknownSpec>>;\ntype HideQueryEditorState = Record<string, boolean>;\n\n/**\n * Props needed by the usePluginEditor hook.\n */\nexport type UsePluginEditorProps = Pick<PluginEditorProps, 'pluginTypes' | 'value' | 'onChange'> & {\n onHideQueryEditorChange?: (isHidden: boolean) => void;\n};\n\n/**\n * Returns the state/handlers that power the `PluginEditor` component. Useful for custom components that want to provide\n * a different UI, but want the same behavior of changing `kind` and `spec` together on plugin kind changes. Also\n * remembers previous `spec` values that it's seen, allowing and restores those values if a user switches the plugin\n * kind back.\n */\nexport function usePluginEditor(props: UsePluginEditorProps): {\n pendingSelection?: PluginEditorSelection;\n isLoading: boolean;\n error: Error | null;\n onSelectionChange: (s: PluginEditorSelection) => void;\n onSpecChange: (next: UnknownSpec) => void;\n rememberCurrentSpecState: () => void;\n} {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const { pluginTypes, value, onHideQueryEditorChange = (): void => {} } = props; // setting onHideQueryEditorChange to empty function here because useEvent requires a function\n\n // Keep a stable reference, so we don't run the effect below when we don't need to\n const onChange = useEvent(props.onChange);\n const onHideQuery = useEvent(onHideQueryEditorChange);\n\n // The previous spec state for PluginType and kind and a helper function for remembering current values\n const prevSpecState = useRef<PreviousSpecState>({\n [value.selection.type]: { [value.selection.kind]: value.spec },\n });\n const rememberCurrentSpecState = useEvent(() => {\n let byPluginType = prevSpecState.current[value.selection.type];\n if (byPluginType === undefined) {\n byPluginType = {};\n prevSpecState.current[value.selection.type] = byPluginType;\n }\n byPluginType[value.selection.kind] = value.spec;\n });\n\n // The previous hide query state for each panel kind\n const hideQueryState = useRef<HideQueryEditorState>({\n [value.selection.kind]: false,\n });\n\n const { defaultPluginKinds } = usePluginRegistry();\n const defaultPluginType = pluginTypes[0];\n const defaultPluginKind = defaultPluginType ? defaultPluginKinds?.[defaultPluginType] : undefined;\n const defaultPluginSelection =\n defaultPluginType && defaultPluginKind\n ? {\n type: defaultPluginType,\n kind: defaultPluginKind,\n }\n : undefined;\n const initPendingSelection = !value.selection && defaultPluginSelection ? defaultPluginSelection : undefined;\n\n // When kind changes and we haven't loaded that plugin before, we will need to enter a \"pending\" state so that we\n // can generate proper initial spec values that match the new plugin kind\n const [pendingSelection, setPendingSelection] = useState<PluginEditorSelection | undefined>(initPendingSelection);\n\n // Take a default kind in case user write explicitly an empty kind in the initial value\n useEffect(() => {\n if (value.selection.kind === '') {\n value.selection.kind = defaultPluginKind || '';\n }\n }, [value.selection, defaultPluginKind]);\n\n const { data: plugin, isFetching, error } = usePlugin(pendingSelection?.type, pendingSelection?.kind || '');\n\n useEffect(() => {\n // Nothing to do if no new plugin kind is pending\n if (!pendingSelection) return;\n\n // Can't get spec value until we have a plugin\n if (plugin === undefined || isFetching) return;\n\n // Fire an onChange to change to the pending kind with initial values from the plugin\n rememberCurrentSpecState();\n onChange({\n selection: pendingSelection,\n spec: plugin.createInitialOptions ? plugin.createInitialOptions() : {},\n });\n\n if (pendingSelection.type === 'Panel') {\n const panelPlugin = plugin as PanelPlugin;\n hideQueryState.current[pendingSelection.kind] = !!panelPlugin.hideQueryEditor;\n if (!!panelPlugin.hideQueryEditor !== hideQueryState.current[value.selection.kind]) {\n onHideQuery(!!panelPlugin.hideQueryEditor);\n }\n }\n setPendingSelection(undefined);\n }, [\n pendingSelection,\n plugin,\n isFetching,\n rememberCurrentSpecState,\n onChange,\n onHideQuery,\n hideQueryState,\n value.selection,\n ]);\n\n /**\n * When the user tries to change the plugin kind, make sure we have the correct spec for that plugin kind before we\n * make the switch.\n */\n const onSelectionChange: PluginKindSelectProps['onChange'] = (nextSelection) => {\n // If we already have state for this plugin type/kind from a previous selection, just use it\n const previousState = prevSpecState.current[nextSelection.type]?.[nextSelection.kind];\n if (previousState !== undefined) {\n rememberCurrentSpecState();\n onChange({\n selection: nextSelection,\n spec: previousState,\n });\n } else {\n // Otherwise, kick off the async loading process\n setPendingSelection(nextSelection);\n }\n\n if (\n nextSelection.type === 'Panel' &&\n hideQueryState.current[nextSelection.kind] !== undefined &&\n hideQueryState.current[value.selection.kind] !== hideQueryState.current[nextSelection.kind]\n ) {\n onHideQuery(!!hideQueryState.current[nextSelection.kind]);\n }\n };\n\n /**\n * Spec changes are independent and always just set the spec state.\n */\n const onSpecChange: PluginSpecEditorProps['onChange'] = (next) => {\n onChange(\n produce(value, (draft) => {\n draft.spec = next;\n })\n );\n };\n\n return {\n pendingSelection,\n isLoading: isFetching,\n error,\n onSelectionChange,\n onSpecChange,\n rememberCurrentSpecState,\n };\n}\n"],"names":["useState","useRef","useEffect","produce","usePlugin","usePluginRegistry","useEvent","usePluginEditor","props","pluginTypes","value","onHideQueryEditorChange","onChange","onHideQuery","prevSpecState","selection","type","kind","spec","rememberCurrentSpecState","byPluginType","current","undefined","hideQueryState","defaultPluginKinds","defaultPluginType","defaultPluginKind","defaultPluginSelection","initPendingSelection","pendingSelection","setPendingSelection","data","plugin","isFetching","error","createInitialOptions","panelPlugin","hideQueryEditor","onSelectionChange","nextSelection","previousState","onSpecChange","next","draft","isLoading"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/PluginEditor/plugin-editor-api.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { BoxProps } from '@mui/material';\nimport type { DatasourceSpec, PluginDefinitionMetadata, UnknownSpec } from '@perses-dev/spec';\nimport { produce } from 'immer';\nimport { useState, useRef, useEffect } from 'react';\n\nimport type { PanelPlugin, PluginType } from '../../model';\nimport { usePlugin, usePluginRegistry } from '../../runtime';\nimport { useEvent } from '../../utils';\nimport type { PluginKindSelectProps } from '../PluginKindSelect';\nimport type { PluginSpecEditorProps } from '../PluginSpecEditor';\n\nexport interface PluginEditorSelection {\n type: PluginType;\n kind: string;\n /**\n * Optional plugin definition metadata (version and/or registry), matching the `metadata` field of a spec\n * `Definition`. Only set when the user explicitly picks a specific version/registry of a plugin that has several of\n * them available. When omitted, the latest available version is used.\n */\n metadata?: PluginDefinitionMetadata;\n}\n\nexport interface PluginEditorValue {\n selection: PluginEditorSelection;\n spec: UnknownSpec;\n}\n\n// Props on MUI Box that we don't want people to pass because we're either redefining them or providing them in\n// this component\ntype OmittedMuiProps = 'children' | 'value' | 'onChange';\n\nexport interface PluginEditorProps extends Omit<BoxProps, OmittedMuiProps> {\n pluginTypes: PluginType[];\n pluginKindLabel: string;\n value: PluginEditorValue;\n isReadonly?: boolean;\n withRunQueryButton?: boolean;\n filteredQueryPlugins?: string[];\n onChange: (next: PluginEditorValue) => void;\n onRunQuery?: () => void;\n testConnection?: (spec: DatasourceSpec, healthCheckPath: string) => Promise<void>;\n}\n\nexport interface PluginEditorRef {\n flushChanges?: () => void;\n}\n\ntype PreviousSpecState = Record<string, Record<string, UnknownSpec>>;\ntype HideQueryEditorState = Record<string, boolean>;\n\n/**\n * Props needed by the usePluginEditor hook.\n */\nexport type UsePluginEditorProps = Pick<PluginEditorProps, 'pluginTypes' | 'value' | 'onChange'> & {\n onHideQueryEditorChange?: (isHidden: boolean) => void;\n};\n\n/**\n * Returns the state/handlers that power the `PluginEditor` component. Useful for custom components that want to provide\n * a different UI, but want the same behavior of changing `kind` and `spec` together on plugin kind changes. Also\n * remembers previous `spec` values that it's seen, allowing and restores those values if a user switches the plugin\n * kind back.\n */\nexport function usePluginEditor(props: UsePluginEditorProps): {\n pendingSelection?: PluginEditorSelection;\n isLoading: boolean;\n error: Error | null;\n onSelectionChange: (s: PluginEditorSelection) => void;\n onSpecChange: (next: UnknownSpec) => void;\n rememberCurrentSpecState: () => void;\n} {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const { pluginTypes, value, onHideQueryEditorChange = (): void => {} } = props; // setting onHideQueryEditorChange to empty function here because useEvent requires a function\n\n // Keep a stable reference, so we don't run the effect below when we don't need to\n const onChange = useEvent(props.onChange);\n const onHideQuery = useEvent(onHideQueryEditorChange);\n\n // The previous spec state for PluginType and kind and a helper function for remembering current values\n const prevSpecState = useRef<PreviousSpecState>({\n [value.selection.type]: { [value.selection.kind]: value.spec },\n });\n const rememberCurrentSpecState = useEvent(() => {\n let byPluginType = prevSpecState.current[value.selection.type];\n if (byPluginType === undefined) {\n byPluginType = {};\n prevSpecState.current[value.selection.type] = byPluginType;\n }\n byPluginType[value.selection.kind] = value.spec;\n });\n\n // The previous hide query state for each panel kind\n const hideQueryState = useRef<HideQueryEditorState>({\n [value.selection.kind]: false,\n });\n\n const { defaultPluginKinds } = usePluginRegistry();\n const defaultPluginType = pluginTypes[0];\n const defaultPluginKind = defaultPluginType ? defaultPluginKinds?.[defaultPluginType] : undefined;\n const defaultPluginSelection =\n defaultPluginType && defaultPluginKind\n ? {\n type: defaultPluginType,\n kind: defaultPluginKind,\n }\n : undefined;\n const initPendingSelection = !value.selection && defaultPluginSelection ? defaultPluginSelection : undefined;\n\n // When kind changes and we haven't loaded that plugin before, we will need to enter a \"pending\" state so that we\n // can generate proper initial spec values that match the new plugin kind\n const [pendingSelection, setPendingSelection] = useState<PluginEditorSelection | undefined>(initPendingSelection);\n\n // Take a default kind in case user write explicitly an empty kind in the initial value\n useEffect(() => {\n if (value.selection.kind === '') {\n value.selection.kind = defaultPluginKind || '';\n }\n }, [value.selection, defaultPluginKind]);\n\n // Load the pending plugin honoring the pinned version/registry, so the initial options come from the exact\n // implementation the definition will use rather than from the latest one.\n const {\n data: plugin,\n isFetching,\n error,\n } = usePlugin(pendingSelection?.type, pendingSelection?.kind || '', {\n version: pendingSelection?.metadata?.version,\n registry: pendingSelection?.metadata?.registry,\n });\n\n useEffect(() => {\n // Nothing to do if no new plugin kind is pending\n if (!pendingSelection) return;\n\n // Can't get spec value until we have a plugin\n if (plugin === undefined || isFetching) return;\n\n // Fire an onChange to change to the pending kind with initial values from the plugin\n rememberCurrentSpecState();\n onChange({\n selection: pendingSelection,\n spec: plugin.createInitialOptions ? plugin.createInitialOptions() : {},\n });\n\n if (pendingSelection.type === 'Panel') {\n const panelPlugin = plugin as PanelPlugin;\n hideQueryState.current[pendingSelection.kind] = !!panelPlugin.hideQueryEditor;\n if (!!panelPlugin.hideQueryEditor !== hideQueryState.current[value.selection.kind]) {\n onHideQuery(!!panelPlugin.hideQueryEditor);\n }\n }\n setPendingSelection(undefined);\n }, [\n pendingSelection,\n plugin,\n isFetching,\n rememberCurrentSpecState,\n onChange,\n onHideQuery,\n hideQueryState,\n value.selection,\n ]);\n\n /**\n * When the user tries to change the plugin kind, make sure we have the correct spec for that plugin kind before we\n * make the switch.\n */\n const onSelectionChange: PluginKindSelectProps['onChange'] = (nextSelection) => {\n // If we already have state for this plugin type/kind from a previous selection, just use it\n const previousState = prevSpecState.current[nextSelection.type]?.[nextSelection.kind];\n if (previousState !== undefined) {\n rememberCurrentSpecState();\n onChange({\n selection: nextSelection,\n spec: previousState,\n });\n } else {\n // Otherwise, kick off the async loading process\n setPendingSelection(nextSelection);\n }\n\n if (\n nextSelection.type === 'Panel' &&\n hideQueryState.current[nextSelection.kind] !== undefined &&\n hideQueryState.current[value.selection.kind] !== hideQueryState.current[nextSelection.kind]\n ) {\n onHideQuery(!!hideQueryState.current[nextSelection.kind]);\n }\n };\n\n /**\n * Spec changes are independent and always just set the spec state.\n */\n const onSpecChange: PluginSpecEditorProps['onChange'] = (next) => {\n onChange(\n produce(value, (draft) => {\n draft.spec = next;\n }),\n );\n };\n\n return {\n pendingSelection,\n isLoading: isFetching,\n error,\n onSelectionChange,\n onSpecChange,\n rememberCurrentSpecState,\n };\n}\n"],"names":["produce","useState","useRef","useEffect","usePlugin","usePluginRegistry","useEvent","usePluginEditor","props","pluginTypes","value","onHideQueryEditorChange","onChange","onHideQuery","prevSpecState","selection","type","kind","spec","rememberCurrentSpecState","byPluginType","current","undefined","hideQueryState","defaultPluginKinds","defaultPluginType","defaultPluginKind","defaultPluginSelection","initPendingSelection","pendingSelection","setPendingSelection","data","plugin","isFetching","error","version","metadata","registry","createInitialOptions","panelPlugin","hideQueryEditor","onSelectionChange","nextSelection","previousState","onSpecChange","next","draft","isLoading"],"mappings":"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"}
@@ -1,12 +1,25 @@
1
- /// <reference types="react" />
2
- import { TextFieldProps } from '@mui/material';
3
- import { PluginType } from '../../model';
4
- import { PluginEditorSelection } from '../PluginEditor';
1
+ import type { TextFieldProps } from '@mui/material';
2
+ import type { PluginType } from '../../model';
3
+ import type { PluginEditorSelection } from '../PluginEditor';
5
4
  export interface PluginKindSelectProps extends Omit<TextFieldProps, 'value' | 'onChange' | 'children'> {
6
5
  filteredQueryPlugins?: string[];
7
6
  pluginTypes: PluginType[];
8
7
  value?: PluginEditorSelection;
9
8
  onChange?: (s: PluginEditorSelection) => void;
9
+ /**
10
+ * When true, a plugin that has more than one version available is listed with a `<display name> - Latest` option and
11
+ * once per version, labeled `<display name> - <version>`. Selecting a specific version sets `metadata.version` on the
12
+ * selection so it can be persisted on the definition, while selecting Latest leaves the version unpinned. A plugin
13
+ * with a single available version is listed without a version, so it keeps resolving to the latest one. Defaults to
14
+ * false.
15
+ */
16
+ enableVersionSelection?: boolean;
17
+ /**
18
+ * When true, a plugin that is available in more than one registry is listed once per registry, labeled
19
+ * `<display name> (<registry>)`. Selecting such an option sets `metadata.registry` on the selection. A plugin
20
+ * available in a single registry is listed without it. Defaults to false.
21
+ */
22
+ enableRegistrySelection?: boolean;
10
23
  }
11
24
  /**
12
25
  * Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific
@@ -1 +1 @@
1
- {"version":3,"file":"PluginKindSelect.d.ts","sourceRoot":"","sources":["../../../src/components/PluginKindSelect/PluginKindSelect.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAuB,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IACpG,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,wHAyD3B,CAAC"}
1
+ {"version":3,"file":"PluginKindSelect.d.ts","sourceRoot":"","sources":["../../../src/components/PluginKindSelect/PluginKindSelect.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,OAAO,KAAK,EAA4B,UAAU,EAAE,MAAM,aAAa,CAAC;AAGxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IACpG,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAsFD;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,wHAkH3B,CAAC"}
@@ -1,4 +1,3 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
1
  // Copyright The Perses Authors
3
2
  // Licensed under the Apache License, Version 2.0 (the "License");
4
3
  // you may not use this file except in compliance with the License.
@@ -11,9 +10,90 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
11
  // See the License for the specific language governing permissions and
13
12
  // limitations under the License.
14
- import { MenuItem, TextField } from '@mui/material';
15
- import { forwardRef, useCallback, useMemo } from 'react';
16
- import { useListPluginMetadata } from '../../runtime';
13
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
+ import { MenuItem, TextField } from "@mui/material";
15
+ import { forwardRef, useCallback, useMemo } from "react";
16
+ import { useListPluginMetadata } from "../../runtime/index.js";
17
+ import { comparePluginVersions } from "../../utils/index.js";
18
+ function getVariant(metadata) {
19
+ return {
20
+ version: metadata.metadata?.version ?? metadata.module?.version,
21
+ registry: metadata.metadata?.registry ?? metadata.module?.registry
22
+ };
23
+ }
24
+ function getVariantKey(variant) {
25
+ return `${variant.version ?? ''}:${variant.registry ?? ''}`;
26
+ }
27
+ /**
28
+ * Build the selectable entries of a plugin kind. A version (resp. registry) is only part of the entries when the caller
29
+ * enabled its selection *and* the plugin is actually installed in more than one version (resp. registry): there is
30
+ * nothing to pick otherwise, and leaving it out keeps the definition floating on the latest version.
31
+ */ function getGroupOptions(group, enableVersionSelection, enableRegistrySelection) {
32
+ const showVersion = enableVersionSelection && group.hasMultipleVersions;
33
+ const showRegistry = enableRegistrySelection && group.hasMultipleRegistries;
34
+ if (!showVersion && !showRegistry) {
35
+ const selection = {
36
+ type: group.type,
37
+ kind: group.kind
38
+ };
39
+ return [
40
+ {
41
+ selection,
42
+ label: group.displayName,
43
+ value: selectionToOptionValue(selection)
44
+ }
45
+ ];
46
+ }
47
+ const options = [];
48
+ const seen = new Set();
49
+ if (showVersion) {
50
+ const selection = {
51
+ type: group.type,
52
+ kind: group.kind
53
+ };
54
+ options.push({
55
+ selection,
56
+ label: `${group.displayName} - Latest`,
57
+ value: selectionToOptionValue(selection)
58
+ });
59
+ seen.add(getVariantKey({}));
60
+ }
61
+ for (const variant of group.variants){
62
+ const version = showVersion ? variant.version : undefined;
63
+ const registry = showRegistry ? variant.registry : undefined;
64
+ const metadata = {
65
+ ...version ? {
66
+ version
67
+ } : {},
68
+ ...registry ? {
69
+ registry
70
+ } : {}
71
+ };
72
+ // Variants that only differ on a field we don't display collapse into a single entry.
73
+ const key = getVariantKey({
74
+ version,
75
+ registry
76
+ });
77
+ if (seen.has(key)) {
78
+ continue;
79
+ }
80
+ seen.add(key);
81
+ const selection = {
82
+ type: group.type,
83
+ kind: group.kind,
84
+ ...version || registry ? {
85
+ metadata
86
+ } : {}
87
+ };
88
+ const label = `${group.displayName}${version ? ` - ${version}` : ''}${registry ? ` (${registry})` : ''}`;
89
+ options.push({
90
+ selection,
91
+ label,
92
+ value: selectionToOptionValue(selection)
93
+ });
94
+ }
95
+ return options;
96
+ }
17
97
  /**
18
98
  * Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific
19
99
  * plugin types. (e.g. "Show a list of all the Panel plugins", or "Show a list of all the Variable plugins", or "Show
@@ -21,19 +101,78 @@ import { useListPluginMetadata } from '../../runtime';
21
101
  * The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know
22
102
  * when the user changes the plugin type (it fires at start for the default value.)
23
103
  */ export const PluginKindSelect = /*#__PURE__*/ forwardRef((props, ref)=>{
24
- const { pluginTypes, value: propValue, onChange, filteredQueryPlugins, ...others } = props;
104
+ const { pluginTypes, value: propValue, onChange, filteredQueryPlugins, enableVersionSelection = false, enableRegistrySelection = false, ...others } = props;
25
105
  const { data, isLoading } = useListPluginMetadata(pluginTypes);
26
106
  const sortedData = useMemo(()=>{
27
- if (filteredQueryPlugins?.length) {
28
- return data?.filter((i)=>filteredQueryPlugins.includes(i.spec.name))?.sort((a, b)=>a.spec.display.name.localeCompare(b.spec.display.name));
29
- }
30
- return data?.sort((a, b)=>a.spec.display.name.localeCompare(b.spec.display.name));
107
+ const filtered = filteredQueryPlugins?.length ? data?.filter((i)=>filteredQueryPlugins.includes(i.spec.name)) : data;
108
+ return filtered?.toSorted((a, b)=>a.spec.display.name.localeCompare(b.spec.display.name));
31
109
  }, [
32
110
  data,
33
111
  filteredQueryPlugins
34
112
  ]);
113
+ // Group the metadata by plugin kind, collecting all the variants each one is installed under (newest version first).
114
+ const kindGroups = useMemo(()=>{
115
+ const groups = new Map();
116
+ for (const metadata of sortedData ?? []){
117
+ const key = `${metadata.kind}:${metadata.spec.name}`;
118
+ let group = groups.get(key);
119
+ if (group === undefined) {
120
+ group = {
121
+ type: metadata.kind,
122
+ kind: metadata.spec.name,
123
+ displayName: metadata.spec.display.name,
124
+ variants: [],
125
+ hasMultipleVersions: false,
126
+ hasMultipleRegistries: false
127
+ };
128
+ groups.set(key, group);
129
+ }
130
+ const variant = getVariant(metadata);
131
+ if (!group.variants.some((existing)=>getVariantKey(existing) === getVariantKey(variant))) {
132
+ group.variants.push(variant);
133
+ }
134
+ }
135
+ for (const group of groups.values()){
136
+ group.variants = group.variants.toSorted((a, b)=>comparePluginVersions(b.version ?? '', a.version ?? ''));
137
+ group.hasMultipleVersions = new Set(group.variants.map((v)=>v.version ?? '')).size > 1;
138
+ group.hasMultipleRegistries = new Set(group.variants.map((v)=>v.registry ?? '')).size > 1;
139
+ }
140
+ return [
141
+ ...groups.values()
142
+ ];
143
+ }, [
144
+ sortedData
145
+ ]);
146
+ const options = useMemo(()=>kindGroups.flatMap((group)=>getGroupOptions(group, enableVersionSelection, enableRegistrySelection)), [
147
+ kindGroups,
148
+ enableVersionSelection,
149
+ enableRegistrySelection
150
+ ]);
151
+ const labelsByValue = useMemo(()=>new Map(options.map((option)=>[
152
+ option.value,
153
+ option.label
154
+ ])), [
155
+ options
156
+ ]);
35
157
  // Pass an empty value while options are still loading so MUI doesn't complain about us using an "out of range" value
36
- const value = !propValue || isLoading ? '' : selectionToOptionValue(propValue);
158
+ const value = useMemo(()=>{
159
+ if (!propValue || isLoading) {
160
+ return '';
161
+ }
162
+ const optionValue = selectionToOptionValue(propValue);
163
+ if (labelsByValue.has(optionValue)) {
164
+ return optionValue;
165
+ }
166
+ // The definition is not pinned (or is pinned to something we don't list): fall back to the first entry of that
167
+ // plugin kind, which is the one that will actually be used, so the Select has a matching value.
168
+ const fallback = options.find((option)=>option.selection.type === propValue.type && option.selection.kind === propValue.kind);
169
+ return fallback?.value ?? optionValue;
170
+ }, [
171
+ propValue,
172
+ isLoading,
173
+ labelsByValue,
174
+ options
175
+ ]);
37
176
  const handleChange = (event)=>{
38
177
  onChange?.(optionValueToSelection(event.target.value));
39
178
  };
@@ -41,10 +180,16 @@ import { useListPluginMetadata } from '../../runtime';
41
180
  if (selected === '') {
42
181
  return '';
43
182
  }
44
- const selectedValue = optionValueToSelection(selected);
45
- return sortedData?.find((v)=>v.kind === selectedValue.type && v.spec.name === selectedValue.kind)?.spec.display.name;
183
+ const optionValue = selected;
184
+ const label = labelsByValue.get(optionValue);
185
+ if (label !== undefined) {
186
+ return label;
187
+ }
188
+ const selectedValue = optionValueToSelection(optionValue);
189
+ return kindGroups.find((group)=>group.type === selectedValue.type && group.kind === selectedValue.kind)?.displayName;
46
190
  }, [
47
- sortedData
191
+ labelsByValue,
192
+ kindGroups
48
193
  ]);
49
194
  // TODO: Does this need a loading indicator of some kind?
50
195
  return /*#__PURE__*/ _jsxs(TextField, {
@@ -63,14 +208,11 @@ import { useListPluginMetadata } from '../../runtime';
63
208
  value: "",
64
209
  children: "Loading..."
65
210
  }),
66
- sortedData?.map((metadata)=>/*#__PURE__*/ _jsx(MenuItem, {
211
+ options.map((option)=>/*#__PURE__*/ _jsx(MenuItem, {
67
212
  "data-testid": "option",
68
- value: selectionToOptionValue({
69
- type: metadata.kind,
70
- kind: metadata.spec.name
71
- }),
72
- children: metadata.spec.display.name
73
- }, metadata.kind + metadata.spec.name))
213
+ value: option.value,
214
+ children: option.label
215
+ }, option.value))
74
216
  ]
75
217
  });
76
218
  });
@@ -78,29 +220,51 @@ PluginKindSelect.displayName = 'PluginKindSelect';
78
220
  // Delimiter used to stringify/parse option values
79
221
  const OPTION_VALUE_DELIMITER = '_____';
80
222
  /**
81
- * Given a PluginEditorSelection,
82
- * returns a string value like `{type}_____{kind}` that can be used as a Select input value.
223
+ * Given a PluginEditorSelection, returns a string value like `{type}_____{kind}` that can be used as a Select input
224
+ * value. A pinned version and/or registry is appended as `{type}_____{kind}_____{version}_____{registry}`, with empty
225
+ * segments for the parts that are not pinned.
83
226
  * @param selector
84
227
  */ function selectionToOptionValue(selector) {
85
- return [
228
+ const { version, registry } = selector.metadata ?? {};
229
+ const parts = [
86
230
  selector.type,
87
231
  selector.kind
88
- ].join(OPTION_VALUE_DELIMITER);
232
+ ];
233
+ if (version || registry) {
234
+ parts.push(version ?? '');
235
+ }
236
+ if (registry) {
237
+ parts.push(registry);
238
+ }
239
+ return parts.join(OPTION_VALUE_DELIMITER);
89
240
  }
90
241
  /**
91
- * Given an option value name like `{type}_____{kind}`,
92
- * returns a PluginEditorSelection to be used by the query data model.
242
+ * Given an option value name like `{type}_____{kind}` or `{type}_____{kind}_____{version}_____{registry}`, returns a
243
+ * PluginEditorSelection to be used by the query data model.
93
244
  * @param optionValue
94
245
  */ function optionValueToSelection(optionValue) {
95
246
  const words = optionValue.split(OPTION_VALUE_DELIMITER);
96
247
  const type = words[0];
97
248
  const kind = words[1];
249
+ const version = words[2];
250
+ const registry = words[3];
98
251
  if (type === undefined || kind === undefined) {
99
252
  throw new Error('Invalid optionValue string');
100
253
  }
254
+ const metadata = {
255
+ ...version ? {
256
+ version
257
+ } : {},
258
+ ...registry ? {
259
+ registry
260
+ } : {}
261
+ };
101
262
  return {
102
263
  type,
103
- kind
264
+ kind,
265
+ ...version || registry ? {
266
+ metadata
267
+ } : {}
104
268
  };
105
269
  }
106
270
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/PluginKindSelect/PluginKindSelect.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { MenuItem, TextField, TextFieldProps } from '@mui/material';\nimport { forwardRef, ReactElement, useCallback, useMemo } from 'react';\nimport { PluginType } from '../../model';\nimport { useListPluginMetadata } from '../../runtime';\nimport { PluginEditorSelection } from '../PluginEditor';\n\nexport interface PluginKindSelectProps extends Omit<TextFieldProps, 'value' | 'onChange' | 'children'> {\n filteredQueryPlugins?: string[];\n pluginTypes: PluginType[];\n value?: PluginEditorSelection;\n onChange?: (s: PluginEditorSelection) => void;\n}\n\n/**\n * Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific\n * plugin types. (e.g. \"Show a list of all the Panel plugins\", or \"Show a list of all the Variable plugins\", or \"Show\n * a list of all the TimeSeriesQuery, TraceQuery, ProfileQuery, and LogQuery plugins\").\n * The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know\n * when the user changes the plugin type (it fires at start for the default value.)\n */\nexport const PluginKindSelect = forwardRef((props: PluginKindSelectProps, ref): ReactElement => {\n const { pluginTypes, value: propValue, onChange, filteredQueryPlugins, ...others } = props;\n const { data, isLoading } = useListPluginMetadata(pluginTypes);\n\n const sortedData = useMemo(() => {\n if (filteredQueryPlugins?.length) {\n return data\n ?.filter((i) => filteredQueryPlugins.includes(i.spec.name))\n ?.sort((a, b) => a.spec.display.name.localeCompare(b.spec.display.name));\n }\n\n return data?.sort((a, b) => a.spec.display.name.localeCompare(b.spec.display.name));\n }, [data, filteredQueryPlugins]);\n\n // Pass an empty value while options are still loading so MUI doesn't complain about us using an \"out of range\" value\n const value = !propValue || isLoading ? '' : selectionToOptionValue(propValue);\n\n const handleChange = (event: { target: { value: string } }): void => {\n onChange?.(optionValueToSelection(event.target.value));\n };\n\n const renderValue = useCallback(\n (selected: unknown) => {\n if (selected === '') {\n return '';\n }\n const selectedValue = optionValueToSelection(selected as string);\n return sortedData?.find((v) => v.kind === selectedValue.type && v.spec.name === selectedValue.kind)?.spec.display\n .name;\n },\n [sortedData]\n );\n\n // TODO: Does this need a loading indicator of some kind?\n return (\n <TextField\n select\n inputRef={ref}\n {...others}\n value={value}\n aria-label={value}\n onChange={handleChange}\n SelectProps={{ renderValue }}\n data-testid=\"plugin-kind-select\"\n >\n {isLoading && <MenuItem value=\"\">Loading...</MenuItem>}\n {sortedData?.map((metadata) => (\n <MenuItem\n data-testid=\"option\"\n key={metadata.kind + metadata.spec.name}\n value={selectionToOptionValue({ type: metadata.kind, kind: metadata.spec.name })}\n >\n {metadata.spec.display.name}\n </MenuItem>\n ))}\n </TextField>\n );\n});\nPluginKindSelect.displayName = 'PluginKindSelect';\n\n// Delimiter used to stringify/parse option values\nconst OPTION_VALUE_DELIMITER = '_____';\n\n/**\n * Given a PluginEditorSelection,\n * returns a string value like `{type}_____{kind}` that can be used as a Select input value.\n * @param selector\n */\nfunction selectionToOptionValue(selector: PluginEditorSelection): string {\n return [selector.type, selector.kind].join(OPTION_VALUE_DELIMITER);\n}\n\n/**\n * Given an option value name like `{type}_____{kind}`,\n * returns a PluginEditorSelection to be used by the query data model.\n * @param optionValue\n */\nfunction optionValueToSelection(optionValue: string): PluginEditorSelection {\n const words = optionValue.split(OPTION_VALUE_DELIMITER);\n const type = words[0] as PluginType | undefined;\n const kind = words[1];\n if (type === undefined || kind === undefined) {\n throw new Error('Invalid optionValue string');\n }\n return {\n type,\n kind,\n };\n}\n"],"names":["MenuItem","TextField","forwardRef","useCallback","useMemo","useListPluginMetadata","PluginKindSelect","props","ref","pluginTypes","value","propValue","onChange","filteredQueryPlugins","others","data","isLoading","sortedData","length","filter","i","includes","spec","name","sort","a","b","display","localeCompare","selectionToOptionValue","handleChange","event","optionValueToSelection","target","renderValue","selected","selectedValue","find","v","kind","type","select","inputRef","aria-label","SelectProps","data-testid","map","metadata","displayName","OPTION_VALUE_DELIMITER","selector","join","optionValue","words","split","undefined","Error"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/PluginKindSelect/PluginKindSelect.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport type { TextFieldProps } from '@mui/material';\nimport { MenuItem, TextField } from '@mui/material';\nimport type { PluginDefinitionMetadata } from '@perses-dev/spec';\nimport type { ReactElement } from 'react';\nimport { forwardRef, useCallback, useMemo } from 'react';\n\nimport type { PluginMetadataWithModule, PluginType } from '../../model';\nimport { useListPluginMetadata } from '../../runtime';\nimport { comparePluginVersions } from '../../utils';\nimport type { PluginEditorSelection } from '../PluginEditor';\n\nexport interface PluginKindSelectProps extends Omit<TextFieldProps, 'value' | 'onChange' | 'children'> {\n filteredQueryPlugins?: string[];\n pluginTypes: PluginType[];\n value?: PluginEditorSelection;\n onChange?: (s: PluginEditorSelection) => void;\n /**\n * When true, a plugin that has more than one version available is listed with a `<display name> - Latest` option and\n * once per version, labeled `<display name> - <version>`. Selecting a specific version sets `metadata.version` on the\n * selection so it can be persisted on the definition, while selecting Latest leaves the version unpinned. A plugin\n * with a single available version is listed without a version, so it keeps resolving to the latest one. Defaults to\n * false.\n */\n enableVersionSelection?: boolean;\n /**\n * When true, a plugin that is available in more than one registry is listed once per registry, labeled\n * `<display name> (<registry>)`. Selecting such an option sets `metadata.registry` on the selection. A plugin\n * available in a single registry is listed without it. Defaults to false.\n */\n enableRegistrySelection?: boolean;\n}\n\n/** A plugin kind grouped with all of the variants it is installed under. */\ninterface PluginKindGroup {\n type: PluginType;\n kind: string;\n displayName: string;\n /** Available variants, sorted from the newest version to the oldest. */\n variants: PluginDefinitionMetadata[];\n hasMultipleVersions: boolean;\n hasMultipleRegistries: boolean;\n}\n\n/** A selectable entry of the select input. */\ninterface PluginKindOption {\n selection: PluginEditorSelection;\n label: string;\n /** Stringified `selection`, used as the MUI Select option value. */\n value: string;\n}\n\nfunction getVariant(metadata: PluginMetadataWithModule): PluginDefinitionMetadata {\n return {\n version: metadata.metadata?.version ?? metadata.module?.version,\n registry: metadata.metadata?.registry ?? metadata.module?.registry,\n };\n}\n\nfunction getVariantKey(variant: PluginDefinitionMetadata): string {\n return `${variant.version ?? ''}:${variant.registry ?? ''}`;\n}\n\n/**\n * Build the selectable entries of a plugin kind. A version (resp. registry) is only part of the entries when the caller\n * enabled its selection *and* the plugin is actually installed in more than one version (resp. registry): there is\n * nothing to pick otherwise, and leaving it out keeps the definition floating on the latest version.\n */\nfunction getGroupOptions(\n group: PluginKindGroup,\n enableVersionSelection: boolean,\n enableRegistrySelection: boolean,\n): PluginKindOption[] {\n const showVersion = enableVersionSelection && group.hasMultipleVersions;\n const showRegistry = enableRegistrySelection && group.hasMultipleRegistries;\n\n if (!showVersion && !showRegistry) {\n const selection: PluginEditorSelection = { type: group.type, kind: group.kind };\n return [{ selection, label: group.displayName, value: selectionToOptionValue(selection) }];\n }\n\n const options: PluginKindOption[] = [];\n const seen = new Set<string>();\n if (showVersion) {\n const selection: PluginEditorSelection = { type: group.type, kind: group.kind };\n options.push({\n selection,\n label: `${group.displayName} - Latest`,\n value: selectionToOptionValue(selection),\n });\n seen.add(getVariantKey({}));\n }\n for (const variant of group.variants) {\n const version = showVersion ? variant.version : undefined;\n const registry = showRegistry ? variant.registry : undefined;\n const metadata: PluginDefinitionMetadata = {\n ...(version ? { version } : {}),\n ...(registry ? { registry } : {}),\n };\n // Variants that only differ on a field we don't display collapse into a single entry.\n const key = getVariantKey({ version, registry });\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n\n const selection: PluginEditorSelection = {\n type: group.type,\n kind: group.kind,\n ...(version || registry ? { metadata } : {}),\n };\n const label = `${group.displayName}${version ? ` - ${version}` : ''}${registry ? ` (${registry})` : ''}`;\n options.push({ selection, label, value: selectionToOptionValue(selection) });\n }\n return options;\n}\n\n/**\n * Displays a MUI Select input for selecting a plugin's kind from a list of all the available plugins of some specific\n * plugin types. (e.g. \"Show a list of all the Panel plugins\", or \"Show a list of all the Variable plugins\", or \"Show\n * a list of all the TimeSeriesQuery, TraceQuery, ProfileQuery, and LogQuery plugins\").\n * The value of the select is the kind of the plugin, but you can also listen to the `onPluginTypeChange` event to know\n * when the user changes the plugin type (it fires at start for the default value.)\n */\nexport const PluginKindSelect = forwardRef((props: PluginKindSelectProps, ref): ReactElement => {\n const {\n pluginTypes,\n value: propValue,\n onChange,\n filteredQueryPlugins,\n enableVersionSelection = false,\n enableRegistrySelection = false,\n ...others\n } = props;\n const { data, isLoading } = useListPluginMetadata(pluginTypes);\n\n const sortedData = useMemo(() => {\n const filtered = filteredQueryPlugins?.length\n ? data?.filter((i) => filteredQueryPlugins.includes(i.spec.name))\n : data;\n return filtered?.toSorted((a, b) => a.spec.display.name.localeCompare(b.spec.display.name));\n }, [data, filteredQueryPlugins]);\n\n // Group the metadata by plugin kind, collecting all the variants each one is installed under (newest version first).\n const kindGroups = useMemo<PluginKindGroup[]>(() => {\n const groups = new Map<string, PluginKindGroup>();\n for (const metadata of sortedData ?? []) {\n const key = `${metadata.kind}:${metadata.spec.name}`;\n let group = groups.get(key);\n if (group === undefined) {\n group = {\n type: metadata.kind,\n kind: metadata.spec.name,\n displayName: metadata.spec.display.name,\n variants: [],\n hasMultipleVersions: false,\n hasMultipleRegistries: false,\n };\n groups.set(key, group);\n }\n const variant = getVariant(metadata);\n if (!group.variants.some((existing) => getVariantKey(existing) === getVariantKey(variant))) {\n group.variants.push(variant);\n }\n }\n for (const group of groups.values()) {\n group.variants = group.variants.toSorted((a, b) => comparePluginVersions(b.version ?? '', a.version ?? ''));\n group.hasMultipleVersions = new Set(group.variants.map((v) => v.version ?? '')).size > 1;\n group.hasMultipleRegistries = new Set(group.variants.map((v) => v.registry ?? '')).size > 1;\n }\n return [...groups.values()];\n }, [sortedData]);\n\n const options = useMemo(\n () => kindGroups.flatMap((group) => getGroupOptions(group, enableVersionSelection, enableRegistrySelection)),\n [kindGroups, enableVersionSelection, enableRegistrySelection],\n );\n\n const labelsByValue = useMemo(() => new Map(options.map((option) => [option.value, option.label])), [options]);\n\n // Pass an empty value while options are still loading so MUI doesn't complain about us using an \"out of range\" value\n const value = useMemo(() => {\n if (!propValue || isLoading) {\n return '';\n }\n const optionValue = selectionToOptionValue(propValue);\n if (labelsByValue.has(optionValue)) {\n return optionValue;\n }\n // The definition is not pinned (or is pinned to something we don't list): fall back to the first entry of that\n // plugin kind, which is the one that will actually be used, so the Select has a matching value.\n const fallback = options.find(\n (option) => option.selection.type === propValue.type && option.selection.kind === propValue.kind,\n );\n return fallback?.value ?? optionValue;\n }, [propValue, isLoading, labelsByValue, options]);\n\n const handleChange = (event: { target: { value: string } }): void => {\n onChange?.(optionValueToSelection(event.target.value));\n };\n\n const renderValue = useCallback(\n (selected: unknown) => {\n if (selected === '') {\n return '';\n }\n const optionValue = selected as string;\n const label = labelsByValue.get(optionValue);\n if (label !== undefined) {\n return label;\n }\n const selectedValue = optionValueToSelection(optionValue);\n return kindGroups.find((group) => group.type === selectedValue.type && group.kind === selectedValue.kind)\n ?.displayName;\n },\n [labelsByValue, kindGroups],\n );\n\n // TODO: Does this need a loading indicator of some kind?\n return (\n <TextField\n select\n inputRef={ref}\n {...others}\n value={value}\n aria-label={value}\n onChange={handleChange}\n SelectProps={{ renderValue }}\n data-testid=\"plugin-kind-select\"\n >\n {isLoading && <MenuItem value=\"\">Loading...</MenuItem>}\n {options.map((option) => (\n <MenuItem data-testid=\"option\" key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n );\n});\nPluginKindSelect.displayName = 'PluginKindSelect';\n\n// Delimiter used to stringify/parse option values\nconst OPTION_VALUE_DELIMITER = '_____';\n\n/**\n * Given a PluginEditorSelection, returns a string value like `{type}_____{kind}` that can be used as a Select input\n * value. A pinned version and/or registry is appended as `{type}_____{kind}_____{version}_____{registry}`, with empty\n * segments for the parts that are not pinned.\n * @param selector\n */\nfunction selectionToOptionValue(selector: PluginEditorSelection): string {\n const { version, registry } = selector.metadata ?? {};\n const parts = [selector.type, selector.kind];\n if (version || registry) {\n parts.push(version ?? '');\n }\n if (registry) {\n parts.push(registry);\n }\n return parts.join(OPTION_VALUE_DELIMITER);\n}\n\n/**\n * Given an option value name like `{type}_____{kind}` or `{type}_____{kind}_____{version}_____{registry}`, returns a\n * PluginEditorSelection to be used by the query data model.\n * @param optionValue\n */\nfunction optionValueToSelection(optionValue: string): PluginEditorSelection {\n const words = optionValue.split(OPTION_VALUE_DELIMITER);\n const type = words[0] as PluginType | undefined;\n const kind = words[1];\n const version = words[2];\n const registry = words[3];\n if (type === undefined || kind === undefined) {\n throw new Error('Invalid optionValue string');\n }\n const metadata: PluginDefinitionMetadata = {\n ...(version ? { version } : {}),\n ...(registry ? { registry } : {}),\n };\n return {\n type,\n kind,\n ...(version || registry ? { metadata } : {}),\n };\n}\n"],"names":["MenuItem","TextField","forwardRef","useCallback","useMemo","useListPluginMetadata","comparePluginVersions","getVariant","metadata","version","module","registry","getVariantKey","variant","getGroupOptions","group","enableVersionSelection","enableRegistrySelection","showVersion","hasMultipleVersions","showRegistry","hasMultipleRegistries","selection","type","kind","label","displayName","value","selectionToOptionValue","options","seen","Set","push","add","variants","undefined","key","has","PluginKindSelect","props","ref","pluginTypes","propValue","onChange","filteredQueryPlugins","others","data","isLoading","sortedData","filtered","length","filter","i","includes","spec","name","toSorted","a","b","display","localeCompare","kindGroups","groups","Map","get","set","some","existing","values","map","v","size","flatMap","labelsByValue","option","optionValue","fallback","find","handleChange","event","optionValueToSelection","target","renderValue","selected","selectedValue","select","inputRef","aria-label","SelectProps","data-testid","OPTION_VALUE_DELIMITER","selector","parts","join","words","split","Error"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,QAAQ,EAAEC,SAAS,QAAQ,gBAAgB;AAGpD,SAASC,UAAU,EAAEC,WAAW,EAAEC,OAAO,QAAQ,QAAQ;AAGzD,SAASC,qBAAqB,QAAQ,yBAAgB;AACtD,SAASC,qBAAqB,QAAQ,uBAAc;AA2CpD,SAASC,WAAWC,QAAkC;IACpD,OAAO;QACLC,SAASD,SAASA,QAAQ,EAAEC,WAAWD,SAASE,MAAM,EAAED;QACxDE,UAAUH,SAASA,QAAQ,EAAEG,YAAYH,SAASE,MAAM,EAAEC;IAC5D;AACF;AAEA,SAASC,cAAcC,OAAiC;IACtD,OAAO,GAAGA,QAAQJ,OAAO,IAAI,GAAG,CAAC,EAAEI,QAAQF,QAAQ,IAAI,IAAI;AAC7D;AAEA;;;;CAIC,GACD,SAASG,gBACPC,KAAsB,EACtBC,sBAA+B,EAC/BC,uBAAgC;IAEhC,MAAMC,cAAcF,0BAA0BD,MAAMI,mBAAmB;IACvE,MAAMC,eAAeH,2BAA2BF,MAAMM,qBAAqB;IAE3E,IAAI,CAACH,eAAe,CAACE,cAAc;QACjC,MAAME,YAAmC;YAAEC,MAAMR,MAAMQ,IAAI;YAAEC,MAAMT,MAAMS,IAAI;QAAC;QAC9E,OAAO;YAAC;gBAAEF;gBAAWG,OAAOV,MAAMW,WAAW;gBAAEC,OAAOC,uBAAuBN;YAAW;SAAE;IAC5F;IAEA,MAAMO,UAA8B,EAAE;IACtC,MAAMC,OAAO,IAAIC;IACjB,IAAIb,aAAa;QACf,MAAMI,YAAmC;YAAEC,MAAMR,MAAMQ,IAAI;YAAEC,MAAMT,MAAMS,IAAI;QAAC;QAC9EK,QAAQG,IAAI,CAAC;YACXV;YACAG,OAAO,GAAGV,MAAMW,WAAW,CAAC,SAAS,CAAC;YACtCC,OAAOC,uBAAuBN;QAChC;QACAQ,KAAKG,GAAG,CAACrB,cAAc,CAAC;IAC1B;IACA,KAAK,MAAMC,WAAWE,MAAMmB,QAAQ,CAAE;QACpC,MAAMzB,UAAUS,cAAcL,QAAQJ,OAAO,GAAG0B;QAChD,MAAMxB,WAAWS,eAAeP,QAAQF,QAAQ,GAAGwB;QACnD,MAAM3B,WAAqC;YACzC,GAAIC,UAAU;gBAAEA;YAAQ,IAAI,CAAC,CAAC;YAC9B,GAAIE,WAAW;gBAAEA;YAAS,IAAI,CAAC,CAAC;QAClC;QACA,sFAAsF;QACtF,MAAMyB,MAAMxB,cAAc;YAAEH;YAASE;QAAS;QAC9C,IAAImB,KAAKO,GAAG,CAACD,MAAM;YACjB;QACF;QACAN,KAAKG,GAAG,CAACG;QAET,MAAMd,YAAmC;YACvCC,MAAMR,MAAMQ,IAAI;YAChBC,MAAMT,MAAMS,IAAI;YAChB,GAAIf,WAAWE,WAAW;gBAAEH;YAAS,IAAI,CAAC,CAAC;QAC7C;QACA,MAAMiB,QAAQ,GAAGV,MAAMW,WAAW,GAAGjB,UAAU,CAAC,GAAG,EAAEA,SAAS,GAAG,KAAKE,WAAW,CAAC,EAAE,EAAEA,SAAS,CAAC,CAAC,GAAG,IAAI;QACxGkB,QAAQG,IAAI,CAAC;YAAEV;YAAWG;YAAOE,OAAOC,uBAAuBN;QAAW;IAC5E;IACA,OAAOO;AACT;AAEA;;;;;;CAMC,GACD,OAAO,MAAMS,iCAAmBpC,WAAW,CAACqC,OAA8BC;IACxE,MAAM,EACJC,WAAW,EACXd,OAAOe,SAAS,EAChBC,QAAQ,EACRC,oBAAoB,EACpB5B,yBAAyB,KAAK,EAC9BC,0BAA0B,KAAK,EAC/B,GAAG4B,QACJ,GAAGN;IACJ,MAAM,EAAEO,IAAI,EAAEC,SAAS,EAAE,GAAG1C,sBAAsBoC;IAElD,MAAMO,aAAa5C,QAAQ;QACzB,MAAM6C,WAAWL,sBAAsBM,SACnCJ,MAAMK,OAAO,CAACC,IAAMR,qBAAqBS,QAAQ,CAACD,EAAEE,IAAI,CAACC,IAAI,KAC7DT;QACJ,OAAOG,UAAUO,SAAS,CAACC,GAAGC,IAAMD,EAAEH,IAAI,CAACK,OAAO,CAACJ,IAAI,CAACK,aAAa,CAACF,EAAEJ,IAAI,CAACK,OAAO,CAACJ,IAAI;IAC3F,GAAG;QAACT;QAAMF;KAAqB;IAE/B,qHAAqH;IACrH,MAAMiB,aAAazD,QAA2B;QAC5C,MAAM0D,SAAS,IAAIC;QACnB,KAAK,MAAMvD,YAAYwC,cAAc,EAAE,CAAE;YACvC,MAAMZ,MAAM,GAAG5B,SAASgB,IAAI,CAAC,CAAC,EAAEhB,SAAS8C,IAAI,CAACC,IAAI,EAAE;YACpD,IAAIxC,QAAQ+C,OAAOE,GAAG,CAAC5B;YACvB,IAAIrB,UAAUoB,WAAW;gBACvBpB,QAAQ;oBACNQ,MAAMf,SAASgB,IAAI;oBACnBA,MAAMhB,SAAS8C,IAAI,CAACC,IAAI;oBACxB7B,aAAalB,SAAS8C,IAAI,CAACK,OAAO,CAACJ,IAAI;oBACvCrB,UAAU,EAAE;oBACZf,qBAAqB;oBACrBE,uBAAuB;gBACzB;gBACAyC,OAAOG,GAAG,CAAC7B,KAAKrB;YAClB;YACA,MAAMF,UAAUN,WAAWC;YAC3B,IAAI,CAACO,MAAMmB,QAAQ,CAACgC,IAAI,CAAC,CAACC,WAAavD,cAAcuD,cAAcvD,cAAcC,WAAW;gBAC1FE,MAAMmB,QAAQ,CAACF,IAAI,CAACnB;YACtB;QACF;QACA,KAAK,MAAME,SAAS+C,OAAOM,MAAM,GAAI;YACnCrD,MAAMmB,QAAQ,GAAGnB,MAAMmB,QAAQ,CAACsB,QAAQ,CAAC,CAACC,GAAGC,IAAMpD,sBAAsBoD,EAAEjD,OAAO,IAAI,IAAIgD,EAAEhD,OAAO,IAAI;YACvGM,MAAMI,mBAAmB,GAAG,IAAIY,IAAIhB,MAAMmB,QAAQ,CAACmC,GAAG,CAAC,CAACC,IAAMA,EAAE7D,OAAO,IAAI,KAAK8D,IAAI,GAAG;YACvFxD,MAAMM,qBAAqB,GAAG,IAAIU,IAAIhB,MAAMmB,QAAQ,CAACmC,GAAG,CAAC,CAACC,IAAMA,EAAE3D,QAAQ,IAAI,KAAK4D,IAAI,GAAG;QAC5F;QACA,OAAO;eAAIT,OAAOM,MAAM;SAAG;IAC7B,GAAG;QAACpB;KAAW;IAEf,MAAMnB,UAAUzB,QACd,IAAMyD,WAAWW,OAAO,CAAC,CAACzD,QAAUD,gBAAgBC,OAAOC,wBAAwBC,2BACnF;QAAC4C;QAAY7C;QAAwBC;KAAwB;IAG/D,MAAMwD,gBAAgBrE,QAAQ,IAAM,IAAI2D,IAAIlC,QAAQwC,GAAG,CAAC,CAACK,SAAW;gBAACA,OAAO/C,KAAK;gBAAE+C,OAAOjD,KAAK;aAAC,IAAI;QAACI;KAAQ;IAE7G,qHAAqH;IACrH,MAAMF,QAAQvB,QAAQ;QACpB,IAAI,CAACsC,aAAaK,WAAW;YAC3B,OAAO;QACT;QACA,MAAM4B,cAAc/C,uBAAuBc;QAC3C,IAAI+B,cAAcpC,GAAG,CAACsC,cAAc;YAClC,OAAOA;QACT;QACA,+GAA+G;QAC/G,gGAAgG;QAChG,MAAMC,WAAW/C,QAAQgD,IAAI,CAC3B,CAACH,SAAWA,OAAOpD,SAAS,CAACC,IAAI,KAAKmB,UAAUnB,IAAI,IAAImD,OAAOpD,SAAS,CAACE,IAAI,KAAKkB,UAAUlB,IAAI;QAElG,OAAOoD,UAAUjD,SAASgD;IAC5B,GAAG;QAACjC;QAAWK;QAAW0B;QAAe5C;KAAQ;IAEjD,MAAMiD,eAAe,CAACC;QACpBpC,WAAWqC,uBAAuBD,MAAME,MAAM,CAACtD,KAAK;IACtD;IAEA,MAAMuD,cAAc/E,YAClB,CAACgF;QACC,IAAIA,aAAa,IAAI;YACnB,OAAO;QACT;QACA,MAAMR,cAAcQ;QACpB,MAAM1D,QAAQgD,cAAcT,GAAG,CAACW;QAChC,IAAIlD,UAAUU,WAAW;YACvB,OAAOV;QACT;QACA,MAAM2D,gBAAgBJ,uBAAuBL;QAC7C,OAAOd,WAAWgB,IAAI,CAAC,CAAC9D,QAAUA,MAAMQ,IAAI,KAAK6D,cAAc7D,IAAI,IAAIR,MAAMS,IAAI,KAAK4D,cAAc5D,IAAI,GACpGE;IACN,GACA;QAAC+C;QAAeZ;KAAW;IAG7B,yDAAyD;IACzD,qBACE,MAAC5D;QACCoF,MAAM;QACNC,UAAU9C;QACT,GAAGK,MAAM;QACVlB,OAAOA;QACP4D,cAAY5D;QACZgB,UAAUmC;QACVU,aAAa;YAAEN;QAAY;QAC3BO,eAAY;;YAEX1C,2BAAa,KAAC/C;gBAAS2B,OAAM;0BAAG;;YAChCE,QAAQwC,GAAG,CAAC,CAACK,uBACZ,KAAC1E;oBAASyF,eAAY;oBAA4B9D,OAAO+C,OAAO/C,KAAK;8BAClE+C,OAAOjD,KAAK;mBADqBiD,OAAO/C,KAAK;;;AAMxD,GAAG;AACHW,iBAAiBZ,WAAW,GAAG;AAE/B,kDAAkD;AAClD,MAAMgE,yBAAyB;AAE/B;;;;;CAKC,GACD,SAAS9D,uBAAuB+D,QAA+B;IAC7D,MAAM,EAAElF,OAAO,EAAEE,QAAQ,EAAE,GAAGgF,SAASnF,QAAQ,IAAI,CAAC;IACpD,MAAMoF,QAAQ;QAACD,SAASpE,IAAI;QAAEoE,SAASnE,IAAI;KAAC;IAC5C,IAAIf,WAAWE,UAAU;QACvBiF,MAAM5D,IAAI,CAACvB,WAAW;IACxB;IACA,IAAIE,UAAU;QACZiF,MAAM5D,IAAI,CAACrB;IACb;IACA,OAAOiF,MAAMC,IAAI,CAACH;AACpB;AAEA;;;;CAIC,GACD,SAASV,uBAAuBL,WAAmB;IACjD,MAAMmB,QAAQnB,YAAYoB,KAAK,CAACL;IAChC,MAAMnE,OAAOuE,KAAK,CAAC,EAAE;IACrB,MAAMtE,OAAOsE,KAAK,CAAC,EAAE;IACrB,MAAMrF,UAAUqF,KAAK,CAAC,EAAE;IACxB,MAAMnF,WAAWmF,KAAK,CAAC,EAAE;IACzB,IAAIvE,SAASY,aAAaX,SAASW,WAAW;QAC5C,MAAM,IAAI6D,MAAM;IAClB;IACA,MAAMxF,WAAqC;QACzC,GAAIC,UAAU;YAAEA;QAAQ,IAAI,CAAC,CAAC;QAC9B,GAAIE,WAAW;YAAEA;QAAS,IAAI,CAAC,CAAC;IAClC;IACA,OAAO;QACLY;QACAC;QACA,GAAIf,WAAWE,WAAW;YAAEH;QAAS,IAAI,CAAC,CAAC;IAC7C;AACF"}
@@ -10,6 +10,6 @@
10
10
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
- export * from './PluginKindSelect';
13
+ export * from "./PluginKindSelect.js";
14
14
 
15
15
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/PluginKindSelect/index.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from './PluginKindSelect';\n"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,qBAAqB"}
1
+ {"version":3,"sources":["../../../src/components/PluginKindSelect/index.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nexport * from './PluginKindSelect';\n"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,cAAc,wBAAqB"}
@@ -1,5 +1,5 @@
1
- import { ReactNode, ReactElement } from 'react';
2
- import { PluginLoader, DefaultPluginKinds } from '../../model';
1
+ import type { ReactNode, ReactElement } from 'react';
2
+ import type { PluginLoader, DefaultPluginKinds } from '../../model';
3
3
  export interface PluginRegistryProps {
4
4
  pluginLoader: PluginLoader;
5
5
  defaultPluginKinds?: DefaultPluginKinds;
@@ -1 +1 @@
1
- {"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAgC,SAAS,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC9E,OAAO,EAKL,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CAoEvE"}
1
+ {"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/components/PluginRegistry/PluginRegistry.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,EAKV,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA2CD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CA4FvE"}
@@ -11,11 +11,46 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
- import { useRef, useCallback, useMemo } from 'react';
15
- import { PluginRegistryContext } from '../../runtime';
16
- import { useEvent } from '../../utils';
17
- import { usePluginIndexes } from './plugin-indexes';
18
- import { resolvePluginKeys } from './getPluginSearchHelper';
14
+ import { useRef, useCallback, useMemo } from "react";
15
+ import { PluginRegistryContext } from "../../runtime/index.js";
16
+ import { comparePluginVersions, useEvent } from "../../utils/index.js";
17
+ import { resolvePluginKeys } from "./getPluginSearchHelper.js";
18
+ import { usePluginIndexes } from "./plugin-indexes.js";
19
+ /**
20
+ * Returns the indexed key of a plugin served by a local dev server for the given plugin type and kind, if any.
21
+ * Keys are `${kind}:${name}:${registry}:${version}`, so we match on the `kind:name:` prefix.
22
+ */ function findDevPluginKey(devPluginKeys, kind, name) {
23
+ const prefix = `${kind}:${name}:`;
24
+ for (const key of devPluginKeys){
25
+ if (key.startsWith(prefix)) {
26
+ return key;
27
+ }
28
+ }
29
+ return undefined;
30
+ }
31
+ /**
32
+ * Returns the indexed keys (`${kind}:${name}:${registry}:${version}`) matching *every* field supplied in the query.
33
+ * `kind` and `name` are always compared; `registry` and `version` are only compared when they are set, so a
34
+ * version-only pin matches whatever registry the plugin happens to be installed under, and a registry-only pin never
35
+ * leaks into another registry. Results are ordered from the newest version to the oldest.
36
+ */ function findMatchingPluginKeys(allKeys, query) {
37
+ const { kind, name, registry, version } = query;
38
+ const prefix = `${kind}:${name}:`;
39
+ const matches = [];
40
+ for (const key of allKeys){
41
+ if (!key.startsWith(prefix)) continue;
42
+ const parts = key.split(':');
43
+ if (parts.length !== 4) continue;
44
+ const [, , keyRegistry, keyVersion] = parts;
45
+ if (registry !== undefined && keyRegistry !== registry) continue;
46
+ if (version !== undefined && keyVersion !== version) continue;
47
+ matches.push({
48
+ key,
49
+ version: keyVersion ?? ''
50
+ });
51
+ }
52
+ return matches.toSorted((a, b)=>comparePluginVersions(b.version, a.version)).map((match)=>match.key);
53
+ }
19
54
  /**
20
55
  * PluginRegistryContext provider that keeps track of all available plugins and provides an API for getting them or
21
56
  * querying the metadata about them.
@@ -38,8 +73,26 @@ import { resolvePluginKeys } from './getPluginSearchHelper';
38
73
  });
39
74
  const getPlugin = useCallback(async (compoundKeyObj)=>{
40
75
  const pluginIndexes = await getPluginIndexes();
41
- const { kind, name } = compoundKeyObj;
42
- const candidateKeys = resolvePluginKeys(pluginIndexes.pluginResourcesByNameKindRegistryVersion.keys(), compoundKeyObj);
76
+ const { kind, name, version, registry } = compoundKeyObj;
77
+ const allKeys = pluginIndexes.pluginResourcesByNameKindRegistryVersion.keys();
78
+ let candidateKeys;
79
+ if (version || registry) {
80
+ // A pin is an exact constraint: only the plugins matching every supplied field are acceptable, and we never
81
+ // silently fall back to another version or another registry.
82
+ candidateKeys = findMatchingPluginKeys(allKeys, compoundKeyObj);
83
+ } else {
84
+ candidateKeys = resolvePluginKeys(allKeys, compoundKeyObj);
85
+ // Nothing pinned: a plugin served by a local dev server (`percli plugin start`) wins over installed archives,
86
+ // whatever their versions. Otherwise a dev plugin whose package version is lower than an installed archive would
87
+ // never be used, which defeats the purpose of running it in dev.
88
+ const devKey = findDevPluginKey(pluginIndexes.devPluginKeys, kind, name);
89
+ if (devKey) {
90
+ candidateKeys = [
91
+ devKey,
92
+ ...candidateKeys.filter((key)=>key !== devKey)
93
+ ];
94
+ }
95
+ }
43
96
  for (const resourceKey of candidateKeys){
44
97
  const resource = pluginIndexes.pluginResourcesByNameKindRegistryVersion.get(resourceKey);
45
98
  if (!resource) continue;
@@ -51,13 +104,23 @@ import { resolvePluginKeys } from './getPluginSearchHelper';
51
104
  const versionlessPlugin = pluginModule?.[name];
52
105
  if (versionlessPlugin) return versionlessPlugin;
53
106
  }
54
- throw new Error(`A ${name} plugin for kind '${kind}' is not installed`);
107
+ const pins = [
108
+ version ? `version '${version}'` : undefined,
109
+ registry ? `registry '${registry}'` : undefined
110
+ ].filter((pin)=>pin !== undefined);
111
+ throw new Error(pins.length > 0 ? `A ${name} plugin for kind '${kind}' with ${pins.join(' and ')} is not installed` : `A ${name} plugin for kind '${kind}' is not installed`);
55
112
  }, [
56
113
  getPluginIndexes,
57
114
  loadPluginModule
58
115
  ]);
59
116
  const listPluginMetadata = useCallback(async (pluginTypes)=>{
60
117
  const pluginIndexes = await getPluginIndexes();
118
+ if (pluginTypes === undefined) {
119
+ // No filter: return the metadata of every installed plugin, whatever its type.
120
+ return [
121
+ ...pluginIndexes.pluginMetadataByKind.values()
122
+ ].flat();
123
+ }
61
124
  return pluginTypes.flatMap((type)=>pluginIndexes.pluginMetadataByKind.get(type) ?? []);
62
125
  }, [
63
126
  getPluginIndexes