@perses-dev/dashboards 0.53.1 → 0.54.0-beta.0

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 (290) hide show
  1. package/dist/cjs/components/DashboardLinks/DashboardLinksEditor.js +366 -0
  2. package/dist/cjs/components/DashboardLinks/EditDashboardLinksButton.js +81 -0
  3. package/dist/cjs/components/DashboardLinks/index.js +31 -0
  4. package/dist/cjs/components/DashboardShortcuts/index.js +23 -0
  5. package/dist/cjs/components/DashboardShortcuts/useDashboardShortcuts.js +373 -0
  6. package/dist/cjs/components/DashboardToolbar/DashboardToolbar.js +16 -1
  7. package/dist/cjs/components/Datasources/EditDatasourcesButton.js +1 -7
  8. package/dist/cjs/components/GridLayout/GridItemContent.js +19 -6
  9. package/dist/cjs/components/{Panel/PanelLinks.js → LinksDisplay/LinksDisplay.js} +59 -10
  10. package/dist/cjs/components/LinksDisplay/index.js +30 -0
  11. package/dist/cjs/components/Panel/PanelActions.js +38 -23
  12. package/dist/cjs/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js +4 -4
  13. package/dist/cjs/components/SaveDashboardButton/SaveDashboardButton.js +3 -61
  14. package/dist/cjs/components/Variables/ListVariableListBox.js +6 -6
  15. package/dist/cjs/components/Variables/Variable.js +3 -3
  16. package/dist/cjs/components/index.js +2 -0
  17. package/dist/cjs/constants/user-interface-text.js +1 -0
  18. package/dist/cjs/context/DashboardProvider/DashboardProvider.js +5 -1
  19. package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +16 -0
  20. package/dist/cjs/context/DashboardProvider/index.js +7 -0
  21. package/dist/cjs/context/DashboardProvider/links-slice.js +32 -0
  22. package/dist/cjs/context/DashboardProvider/panel-group-slice.js +2 -2
  23. package/dist/cjs/context/DashboardProvider/use-save-dashboard.js +104 -0
  24. package/dist/cjs/context/DatasourceStoreProvider.js +3 -9
  25. package/dist/cjs/context/VariableProvider/VariableProvider.js +7 -6
  26. package/dist/cjs/context/VariableProvider/hydrationUtils.js +3 -3
  27. package/dist/cjs/context/useDashboard.js +7 -4
  28. package/dist/cjs/index.js +2 -0
  29. package/dist/cjs/keyboard-shortcuts/PanelFocusProvider.js +157 -0
  30. package/dist/cjs/keyboard-shortcuts/default-shortcuts/dashboard.js +75 -0
  31. package/dist/cjs/keyboard-shortcuts/default-shortcuts/global.js +121 -0
  32. package/dist/cjs/keyboard-shortcuts/default-shortcuts/index.js +33 -0
  33. package/dist/cjs/keyboard-shortcuts/default-shortcuts/panel.js +90 -0
  34. package/dist/cjs/keyboard-shortcuts/default-shortcuts/time-range.js +142 -0
  35. package/dist/cjs/keyboard-shortcuts/events.js +93 -0
  36. package/dist/cjs/keyboard-shortcuts/index.js +89 -0
  37. package/dist/cjs/keyboard-shortcuts/types.js +42 -0
  38. package/dist/cjs/keyboard-shortcuts/utils.js +76 -0
  39. package/dist/cjs/model/DashboardResource.js +16 -0
  40. package/dist/cjs/model/index.js +30 -0
  41. package/dist/cjs/test/render.js +18 -3
  42. package/dist/cjs/views/ViewDashboard/DashboardApp.js +17 -2
  43. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +2 -1
  44. package/dist/components/Dashboard/Dashboard.d.ts.map +1 -1
  45. package/dist/components/Dashboard/Dashboard.js.map +1 -1
  46. package/dist/components/DashboardLinks/DashboardLinksEditor.d.ts +9 -0
  47. package/dist/components/DashboardLinks/DashboardLinksEditor.d.ts.map +1 -0
  48. package/dist/components/DashboardLinks/DashboardLinksEditor.js +353 -0
  49. package/dist/components/DashboardLinks/DashboardLinksEditor.js.map +1 -0
  50. package/dist/components/DashboardLinks/EditDashboardLinksButton.d.ts +18 -0
  51. package/dist/components/DashboardLinks/EditDashboardLinksButton.d.ts.map +1 -0
  52. package/dist/components/DashboardLinks/EditDashboardLinksButton.js +68 -0
  53. package/dist/components/DashboardLinks/EditDashboardLinksButton.js.map +1 -0
  54. package/dist/components/DashboardLinks/index.d.ts +3 -0
  55. package/dist/components/DashboardLinks/index.d.ts.map +1 -0
  56. package/dist/components/DashboardLinks/index.js +16 -0
  57. package/dist/components/DashboardLinks/index.js.map +1 -0
  58. package/dist/components/DashboardShortcuts/index.d.ts +3 -0
  59. package/dist/components/DashboardShortcuts/index.d.ts.map +1 -0
  60. package/dist/components/DashboardShortcuts/index.js +15 -0
  61. package/dist/components/DashboardShortcuts/index.js.map +1 -0
  62. package/dist/components/DashboardShortcuts/useDashboardShortcuts.d.ts +12 -0
  63. package/dist/components/DashboardShortcuts/useDashboardShortcuts.d.ts.map +1 -0
  64. package/dist/components/DashboardShortcuts/useDashboardShortcuts.js +365 -0
  65. package/dist/components/DashboardShortcuts/useDashboardShortcuts.js.map +1 -0
  66. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts +1 -0
  67. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
  68. package/dist/components/DashboardToolbar/DashboardToolbar.js +17 -2
  69. package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
  70. package/dist/components/Datasources/DatasourceEditor.d.ts +1 -1
  71. package/dist/components/Datasources/DatasourceEditor.d.ts.map +1 -1
  72. package/dist/components/Datasources/DatasourceEditor.js.map +1 -1
  73. package/dist/components/Datasources/EditDatasourcesButton.d.ts.map +1 -1
  74. package/dist/components/Datasources/EditDatasourcesButton.js +1 -7
  75. package/dist/components/Datasources/EditDatasourcesButton.js.map +1 -1
  76. package/dist/components/DownloadButton/serializeDashboard.d.ts +2 -2
  77. package/dist/components/DownloadButton/serializeDashboard.d.ts.map +1 -1
  78. package/dist/components/DownloadButton/serializeDashboard.js.map +1 -1
  79. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  80. package/dist/components/GridLayout/GridItemContent.js +21 -8
  81. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  82. package/dist/components/GridLayout/GridLayout.d.ts +1 -1
  83. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  84. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  85. package/dist/components/GridLayout/GridTitle.d.ts +1 -1
  86. package/dist/components/GridLayout/GridTitle.js.map +1 -1
  87. package/dist/components/GridLayout/Row.d.ts +2 -1
  88. package/dist/components/GridLayout/Row.d.ts.map +1 -1
  89. package/dist/components/GridLayout/Row.js.map +1 -1
  90. package/dist/components/LeaveDialog/LeaveDialog.d.ts +3 -3
  91. package/dist/components/LeaveDialog/LeaveDialog.d.ts.map +1 -1
  92. package/dist/components/LeaveDialog/LeaveDialog.js.map +1 -1
  93. package/dist/components/LinksDisplay/LinksDisplay.d.ts +10 -0
  94. package/dist/components/LinksDisplay/LinksDisplay.d.ts.map +1 -0
  95. package/dist/components/{Panel/PanelLinks.js → LinksDisplay/LinksDisplay.js} +59 -10
  96. package/dist/components/LinksDisplay/LinksDisplay.js.map +1 -0
  97. package/dist/components/LinksDisplay/index.d.ts +2 -0
  98. package/dist/components/LinksDisplay/index.d.ts.map +1 -0
  99. package/dist/components/LinksDisplay/index.js +15 -0
  100. package/dist/components/LinksDisplay/index.js.map +1 -0
  101. package/dist/components/Panel/Panel.d.ts +2 -1
  102. package/dist/components/Panel/Panel.d.ts.map +1 -1
  103. package/dist/components/Panel/Panel.js.map +1 -1
  104. package/dist/components/Panel/PanelActions.d.ts +1 -1
  105. package/dist/components/Panel/PanelActions.d.ts.map +1 -1
  106. package/dist/components/Panel/PanelActions.js +39 -24
  107. package/dist/components/Panel/PanelActions.js.map +1 -1
  108. package/dist/components/Panel/PanelContent.d.ts +1 -1
  109. package/dist/components/Panel/PanelContent.js.map +1 -1
  110. package/dist/components/Panel/PanelHeader.d.ts +1 -1
  111. package/dist/components/Panel/PanelHeader.js.map +1 -1
  112. package/dist/components/Panel/PanelPluginLoader.d.ts +1 -1
  113. package/dist/components/Panel/PanelPluginLoader.js.map +1 -1
  114. package/dist/components/PanelDrawer/PanelDrawer.js.map +1 -1
  115. package/dist/components/PanelDrawer/PanelEditorForm.d.ts +2 -1
  116. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  117. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  118. package/dist/components/PanelDrawer/PanelPreview.d.ts +1 -1
  119. package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
  120. package/dist/components/PanelDrawer/PanelQueriesSharedControls.d.ts +1 -1
  121. package/dist/components/PanelDrawer/PanelQueriesSharedControls.js.map +1 -1
  122. package/dist/components/PanelDrawer/usePanelEditor.d.ts +1 -1
  123. package/dist/components/PanelDrawer/usePanelEditor.js.map +1 -1
  124. package/dist/components/QuerySummaryTable/QuerySummaryTable.js.map +1 -1
  125. package/dist/components/QueryViewerDialog/QueryViewerDialog.d.ts +1 -1
  126. package/dist/components/QueryViewerDialog/QueryViewerDialog.js.map +1 -1
  127. package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js +1 -1
  128. package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js.map +1 -1
  129. package/dist/components/SaveDashboardButton/SaveDashboardButton.d.ts.map +1 -1
  130. package/dist/components/SaveDashboardButton/SaveDashboardButton.js +4 -62
  131. package/dist/components/SaveDashboardButton/SaveDashboardButton.js.map +1 -1
  132. package/dist/components/Variables/BuiltinVariableAccordions.d.ts +1 -1
  133. package/dist/components/Variables/BuiltinVariableAccordions.js.map +1 -1
  134. package/dist/components/Variables/EditVariablesButton.d.ts.map +1 -1
  135. package/dist/components/Variables/EditVariablesButton.js.map +1 -1
  136. package/dist/components/Variables/ListVariableListBox.js +1 -1
  137. package/dist/components/Variables/ListVariableListBox.js.map +1 -1
  138. package/dist/components/Variables/Variable.d.ts +1 -1
  139. package/dist/components/Variables/Variable.js +1 -1
  140. package/dist/components/Variables/Variable.js.map +1 -1
  141. package/dist/components/Variables/VariableEditor.d.ts +2 -1
  142. package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
  143. package/dist/components/Variables/VariableEditor.js.map +1 -1
  144. package/dist/components/Variables/VariableList.d.ts +1 -1
  145. package/dist/components/Variables/VariableList.d.ts.map +1 -1
  146. package/dist/components/Variables/VariableList.js.map +1 -1
  147. package/dist/components/index.d.ts +2 -0
  148. package/dist/components/index.d.ts.map +1 -1
  149. package/dist/components/index.js +2 -0
  150. package/dist/components/index.js.map +1 -1
  151. package/dist/constants/user-interface-text.d.ts +1 -0
  152. package/dist/constants/user-interface-text.d.ts.map +1 -1
  153. package/dist/constants/user-interface-text.js +1 -0
  154. package/dist/constants/user-interface-text.js.map +1 -1
  155. package/dist/context/DashboardProvider/DashboardProvider.d.ts +8 -6
  156. package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
  157. package/dist/context/DashboardProvider/DashboardProvider.js +5 -1
  158. package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
  159. package/dist/context/DashboardProvider/common.d.ts +3 -2
  160. package/dist/context/DashboardProvider/common.d.ts.map +1 -1
  161. package/dist/context/DashboardProvider/common.js.map +1 -1
  162. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +15 -2
  163. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  164. package/dist/context/DashboardProvider/dashboard-provider-api.js +14 -0
  165. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  166. package/dist/context/DashboardProvider/delete-panel-group-slice.d.ts +1 -1
  167. package/dist/context/DashboardProvider/delete-panel-group-slice.js.map +1 -1
  168. package/dist/context/DashboardProvider/delete-panel-slice.js.map +1 -1
  169. package/dist/context/DashboardProvider/duplicate-panel-slice.js.map +1 -1
  170. package/dist/context/DashboardProvider/index.d.ts +2 -0
  171. package/dist/context/DashboardProvider/index.d.ts.map +1 -1
  172. package/dist/context/DashboardProvider/index.js +1 -0
  173. package/dist/context/DashboardProvider/index.js.map +1 -1
  174. package/dist/context/DashboardProvider/links-slice.d.ts +19 -0
  175. package/dist/context/DashboardProvider/links-slice.d.ts.map +1 -0
  176. package/dist/context/DashboardProvider/links-slice.js +27 -0
  177. package/dist/context/DashboardProvider/links-slice.js.map +1 -0
  178. package/dist/context/DashboardProvider/panel-editor-slice.d.ts +2 -1
  179. package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -1
  180. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  181. package/dist/context/DashboardProvider/panel-group-editor-slice.d.ts +1 -1
  182. package/dist/context/DashboardProvider/panel-group-editor-slice.js.map +1 -1
  183. package/dist/context/DashboardProvider/panel-group-slice.d.ts +2 -1
  184. package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
  185. package/dist/context/DashboardProvider/panel-group-slice.js +1 -1
  186. package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
  187. package/dist/context/DashboardProvider/panel-slice.d.ts +1 -1
  188. package/dist/context/DashboardProvider/panel-slice.js.map +1 -1
  189. package/dist/context/DashboardProvider/use-save-dashboard.d.ts +25 -0
  190. package/dist/context/DashboardProvider/use-save-dashboard.d.ts.map +1 -0
  191. package/dist/context/DashboardProvider/use-save-dashboard.js +105 -0
  192. package/dist/context/DashboardProvider/use-save-dashboard.js.map +1 -0
  193. package/dist/context/DashboardProvider/view-panel-slice.d.ts.map +1 -1
  194. package/dist/context/DashboardProvider/view-panel-slice.js.map +1 -1
  195. package/dist/context/DatasourceStoreProvider.d.ts +4 -2
  196. package/dist/context/DatasourceStoreProvider.d.ts.map +1 -1
  197. package/dist/context/DatasourceStoreProvider.js +3 -9
  198. package/dist/context/DatasourceStoreProvider.js.map +1 -1
  199. package/dist/context/VariableProvider/VariableProvider.d.ts +2 -1
  200. package/dist/context/VariableProvider/VariableProvider.d.ts.map +1 -1
  201. package/dist/context/VariableProvider/VariableProvider.js +2 -1
  202. package/dist/context/VariableProvider/VariableProvider.js.map +1 -1
  203. package/dist/context/VariableProvider/hydrationUtils.d.ts +2 -1
  204. package/dist/context/VariableProvider/hydrationUtils.d.ts.map +1 -1
  205. package/dist/context/VariableProvider/hydrationUtils.js +1 -1
  206. package/dist/context/VariableProvider/hydrationUtils.js.map +1 -1
  207. package/dist/context/VariableProvider/query-params.d.ts +1 -1
  208. package/dist/context/VariableProvider/query-params.js.map +1 -1
  209. package/dist/context/VariableProvider/utils.d.ts +2 -1
  210. package/dist/context/VariableProvider/utils.d.ts.map +1 -1
  211. package/dist/context/VariableProvider/utils.js.map +1 -1
  212. package/dist/context/useDashboard.d.ts +11 -3
  213. package/dist/context/useDashboard.d.ts.map +1 -1
  214. package/dist/context/useDashboard.js +6 -3
  215. package/dist/context/useDashboard.js.map +1 -1
  216. package/dist/index.d.ts +2 -0
  217. package/dist/index.d.ts.map +1 -1
  218. package/dist/index.js +2 -0
  219. package/dist/index.js.map +1 -1
  220. package/dist/keyboard-shortcuts/PanelFocusProvider.d.ts +12 -0
  221. package/dist/keyboard-shortcuts/PanelFocusProvider.d.ts.map +1 -0
  222. package/dist/keyboard-shortcuts/PanelFocusProvider.js +97 -0
  223. package/dist/keyboard-shortcuts/PanelFocusProvider.js.map +1 -0
  224. package/dist/keyboard-shortcuts/default-shortcuts/dashboard.d.ts +6 -0
  225. package/dist/keyboard-shortcuts/default-shortcuts/dashboard.d.ts.map +1 -0
  226. package/dist/keyboard-shortcuts/default-shortcuts/dashboard.js +53 -0
  227. package/dist/keyboard-shortcuts/default-shortcuts/dashboard.js.map +1 -0
  228. package/dist/keyboard-shortcuts/default-shortcuts/global.d.ts +9 -0
  229. package/dist/keyboard-shortcuts/default-shortcuts/global.d.ts.map +1 -0
  230. package/dist/keyboard-shortcuts/default-shortcuts/global.js +90 -0
  231. package/dist/keyboard-shortcuts/default-shortcuts/global.js.map +1 -0
  232. package/dist/keyboard-shortcuts/default-shortcuts/index.d.ts +5 -0
  233. package/dist/keyboard-shortcuts/default-shortcuts/index.d.ts.map +1 -0
  234. package/dist/keyboard-shortcuts/default-shortcuts/index.js +18 -0
  235. package/dist/keyboard-shortcuts/default-shortcuts/index.js.map +1 -0
  236. package/dist/keyboard-shortcuts/default-shortcuts/panel.d.ts +7 -0
  237. package/dist/keyboard-shortcuts/default-shortcuts/panel.d.ts.map +1 -0
  238. package/dist/keyboard-shortcuts/default-shortcuts/panel.js +65 -0
  239. package/dist/keyboard-shortcuts/default-shortcuts/panel.js.map +1 -0
  240. package/dist/keyboard-shortcuts/default-shortcuts/time-range.d.ts +10 -0
  241. package/dist/keyboard-shortcuts/default-shortcuts/time-range.d.ts.map +1 -0
  242. package/dist/keyboard-shortcuts/default-shortcuts/time-range.js +108 -0
  243. package/dist/keyboard-shortcuts/default-shortcuts/time-range.js.map +1 -0
  244. package/dist/keyboard-shortcuts/events.d.ts +18 -0
  245. package/dist/keyboard-shortcuts/events.d.ts.map +1 -0
  246. package/dist/keyboard-shortcuts/events.js +35 -0
  247. package/dist/keyboard-shortcuts/events.js.map +1 -0
  248. package/dist/keyboard-shortcuts/index.d.ts +9 -0
  249. package/dist/keyboard-shortcuts/index.d.ts.map +1 -0
  250. package/dist/keyboard-shortcuts/index.js +21 -0
  251. package/dist/keyboard-shortcuts/index.js.map +1 -0
  252. package/dist/keyboard-shortcuts/types.d.ts +37 -0
  253. package/dist/keyboard-shortcuts/types.d.ts.map +1 -0
  254. package/dist/keyboard-shortcuts/types.js +26 -0
  255. package/dist/keyboard-shortcuts/types.js.map +1 -0
  256. package/dist/keyboard-shortcuts/utils.d.ts +12 -0
  257. package/dist/keyboard-shortcuts/utils.d.ts.map +1 -0
  258. package/dist/keyboard-shortcuts/utils.js +51 -0
  259. package/dist/keyboard-shortcuts/utils.js.map +1 -0
  260. package/dist/model/DashboardResource.d.ts +15 -0
  261. package/dist/model/DashboardResource.d.ts.map +1 -0
  262. package/dist/model/DashboardResource.js +18 -0
  263. package/dist/model/DashboardResource.js.map +1 -0
  264. package/dist/model/index.d.ts +2 -0
  265. package/dist/model/index.d.ts.map +1 -0
  266. package/dist/model/index.js +15 -0
  267. package/dist/model/index.js.map +1 -0
  268. package/dist/test/dashboard-provider.d.ts +1 -1
  269. package/dist/test/dashboard-provider.d.ts.map +1 -1
  270. package/dist/test/dashboard-provider.js.map +1 -1
  271. package/dist/test/datasource-provider.js.map +1 -1
  272. package/dist/test/plugin-registry.js.map +1 -1
  273. package/dist/test/render.d.ts.map +1 -1
  274. package/dist/test/render.js +18 -3
  275. package/dist/test/render.js.map +1 -1
  276. package/dist/test/testDashboard.d.ts +11 -2
  277. package/dist/test/testDashboard.d.ts.map +1 -1
  278. package/dist/test/testDashboard.js.map +1 -1
  279. package/dist/utils/panelUtils.js.map +1 -1
  280. package/dist/views/ViewDashboard/DashboardApp.d.ts +5 -3
  281. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  282. package/dist/views/ViewDashboard/DashboardApp.js +18 -3
  283. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  284. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  285. package/dist/views/ViewDashboard/ViewDashboard.js +3 -2
  286. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  287. package/package.json +5 -3
  288. package/dist/components/Panel/PanelLinks.d.ts +0 -6
  289. package/dist/components/Panel/PanelLinks.d.ts.map +0 -1
  290. package/dist/components/Panel/PanelLinks.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/LinksDisplay/LinksDisplay.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 { IconButton, Link as LinkComponent, Menu, MenuItem, Theme, Chip, capitalize, Stack } from '@mui/material';\nimport LaunchIcon from 'mdi-material-ui/Launch';\nimport { Link } from '@perses-dev/spec';\nimport { MouseEvent, ReactElement, useState } from 'react';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { useReplaceVariablesInString } from '@perses-dev/plugin-system';\n\ntype LinksVariant = 'dashboard' | 'panel';\n\ninterface LinksProps {\n links: Link[];\n variant: LinksVariant;\n}\n\nexport function LinksDisplay({ links, variant }: LinksProps): ReactElement | null {\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n const isMenuOpened = Boolean(anchorEl);\n const handleOpenMenu = (event: MouseEvent<HTMLButtonElement>): void => {\n setAnchorEl(event.currentTarget);\n };\n\n const handleClose = (): void => {\n setAnchorEl(null);\n };\n\n if (links.length === 0) {\n return null;\n }\n\n // Panel variant: single link shows as icon button\n if (variant === 'panel' && links.length === 1 && links[0]) {\n return <LinkButton link={links[0]} />;\n }\n\n // Dashboard variant: 1-3 links show as chips\n // Max character limit for the name and url to prevent overflow\n // in the dashboard title area, but if either the name or url is too long,\n // we will fall back to showing the links in a dropdown menu\n if (variant === 'dashboard' && links.length <= 3) {\n const canRenderAsChips = links.every((link) => {\n if (link.name) {\n return link.name.length < 30;\n }\n\n if (link.url) {\n return link.url.length < 70;\n }\n\n return false;\n });\n\n if (canRenderAsChips) {\n return (\n <Stack direction=\"row\" spacing={1}>\n {links.map((link: Link) => (\n <LinkChip key={link.url} link={link} />\n ))}\n </Stack>\n );\n }\n }\n\n // Default: show dropdown menu for multiple links\n return (\n <>\n <InfoTooltip description={`${links.length} links`} enterDelay={100}>\n <IconButton\n aria-label={`${capitalize(variant)}-links`}\n id={`${variant}-links-button`}\n size=\"small\"\n onClick={handleOpenMenu}\n sx={(theme) => ({ borderRadius: theme.shape.borderRadius, padding: '4px' })}\n >\n <LaunchIcon\n aria-describedby=\"links-icon\"\n fontSize=\"inherit\"\n sx={{ color: (theme: Theme) => theme.palette.text.secondary }}\n />\n </IconButton>\n </InfoTooltip>\n\n <Menu\n anchorEl={anchorEl}\n open={isMenuOpened}\n onClose={handleClose}\n MenuListProps={{\n 'aria-labelledby': `${variant}-links-button`,\n }}\n >\n {links.map((link: Link) => (\n <LinkMenuItem key={link.url} link={link} />\n ))}\n </Menu>\n </>\n );\n}\n\nfunction LinkChip({ link }: { link: Link }): ReactElement {\n const { url, name, tooltip, targetBlank } = useLink(link);\n\n return (\n <InfoTooltip description={tooltip ?? url} enterDelay={100}>\n <Chip\n label={name ?? url}\n component=\"a\"\n href={url}\n target={targetBlank ? '_blank' : '_self'}\n clickable\n size=\"medium\"\n icon={<LaunchIcon color=\"inherit\" fontSize=\"small\" />}\n sx={(theme) => ({ height: theme.spacing(3) })}\n />\n </InfoTooltip>\n );\n}\n\nfunction LinkButton({ link }: { link: Link }): ReactElement {\n const { url, name, tooltip, targetBlank } = useLink(link);\n\n return (\n <InfoTooltip description={tooltip ?? url} enterDelay={100}>\n <IconButton\n aria-label={name ?? url}\n size=\"small\"\n href={url}\n target={targetBlank ? '_blank' : '_self'}\n sx={(theme) => ({ borderRadius: theme.shape.borderRadius, padding: '4px' })}\n >\n <LaunchIcon fontSize=\"inherit\" sx={{ color: (theme: Theme) => theme.palette.text.secondary }} />\n </IconButton>\n </InfoTooltip>\n );\n}\n\nfunction LinkMenuItem({ link }: { link: Link }): ReactElement {\n const { url, name, tooltip, targetBlank } = useLink(link);\n\n return (\n <InfoTooltip description={tooltip ?? url} enterDelay={100}>\n <MenuItem component={LinkComponent} href={url} target={targetBlank ? '_blank' : '_self'}>\n {name ?? url}\n </MenuItem>\n </InfoTooltip>\n );\n}\n\nfunction useLink(link: Link): Link {\n const url = useReplaceVariablesInString(link.url) ?? link.url;\n const name = useReplaceVariablesInString(link.name);\n const tooltip = useReplaceVariablesInString(link.tooltip);\n\n if (link.renderVariables === false) {\n return link;\n }\n\n return { ...link, url, name, tooltip };\n}\n"],"names":["IconButton","Link","LinkComponent","Menu","MenuItem","Chip","capitalize","Stack","LaunchIcon","useState","InfoTooltip","useReplaceVariablesInString","LinksDisplay","links","variant","anchorEl","setAnchorEl","isMenuOpened","Boolean","handleOpenMenu","event","currentTarget","handleClose","length","LinkButton","link","canRenderAsChips","every","name","url","direction","spacing","map","LinkChip","description","enterDelay","aria-label","id","size","onClick","sx","theme","borderRadius","shape","padding","aria-describedby","fontSize","color","palette","text","secondary","open","onClose","MenuListProps","LinkMenuItem","tooltip","targetBlank","useLink","label","component","href","target","clickable","icon","height","renderVariables"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './LinksDisplay';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/LinksDisplay/index.ts"],"names":[],"mappings":"AAaA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,15 @@
1
+ // Copyright The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ export * from './LinksDisplay';
14
+
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/LinksDisplay/index.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\nexport * from './LinksDisplay';\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,iBAAiB"}
@@ -1,5 +1,6 @@
1
1
  import { CardProps } from '@mui/material';
2
- import { PanelDefinition, PanelGroupItemId } from '@perses-dev/core';
2
+ import { PanelGroupItemId } from '@perses-dev/core';
3
+ import { PanelDefinition } from '@perses-dev/spec';
3
4
  import { ReactNode } from 'react';
4
5
  import { PanelHeaderProps } from './PanelHeader';
5
6
  export interface PanelProps extends CardProps<'section'> {
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/Panel.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAqB,SAAS,EAAE,MAAM,eAAe,CAAC;AAS7D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,EAAE,SAAS,EAAsC,MAAM,OAAO,CAAC;AAGtE,OAAO,EAAe,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,WAAW,UAAW,SAAQ,SAAS,CAAC,SAAS,CAAC;IACtD,UAAU,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAChD,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAChD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,kBAAkB,CAAC,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;CAC7D;AAED,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,SAAS,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,kDAoLhB,CAAC"}
1
+ {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/Panel.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAqB,SAAS,EAAE,MAAM,eAAe,CAAC;AAS7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAsC,MAAM,OAAO,CAAC;AAGtE,OAAO,EAAe,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE9D,MAAM,WAAW,UAAW,SAAQ,SAAS,CAAC,SAAS,CAAC;IACtD,UAAU,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAChD,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAChD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,kBAAkB,CAAC,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;CAC7D;AAED,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,SAAS,CAAC;CAC/C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,kDAoLhB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/Panel.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 { Card, CardContent, CardProps } from '@mui/material';\nimport {\n ErrorAlert,\n ErrorBoundary,\n ItemActionsProvider,\n SelectionProvider,\n combineSx,\n useId,\n} from '@perses-dev/components';\nimport { PanelDefinition, PanelGroupItemId } from '@perses-dev/core';\nimport { ActionOptions, useDataQueriesContext, usePluginRegistry } from '@perses-dev/plugin-system';\nimport { ReactNode, memo, useEffect, useMemo, useState } from 'react';\nimport useResizeObserver from 'use-resize-observer';\nimport { PanelContent } from './PanelContent';\nimport { PanelHeader, PanelHeaderProps } from './PanelHeader';\n\nexport interface PanelProps extends CardProps<'section'> {\n definition: PanelDefinition;\n readHandlers?: PanelHeaderProps['readHandlers'];\n editHandlers?: PanelHeaderProps['editHandlers'];\n panelOptions?: PanelOptions;\n panelGroupItemId?: PanelGroupItemId;\n viewQueriesHandler?: PanelHeaderProps['viewQueriesHandler'];\n}\n\nexport type PanelOptions = {\n /**\n * Allow you to hide the panel header if desired.\n * This can be useful in embedded mode for example.\n */\n hideHeader?: boolean;\n /**\n * Whether to show panel icons always, or only when hovering over the panel.\n * Default: if the dashboard is in editing mode or the panel is in fullscreen mode: 'always', otherwise 'hover'\n */\n showIcons?: 'always' | 'hover';\n /**\n * Content to render in right of the panel header. (top right of the panel)\n * It will only be rendered when the panel is in edit mode.\n */\n extra?: (props: PanelExtraProps) => ReactNode;\n};\n\nexport type PanelExtraProps = {\n /**\n * The PanelDefinition for the panel.\n */\n panelDefinition?: PanelDefinition;\n /**\n * The PanelGroupItemId for the panel.\n */\n panelGroupItemId?: PanelGroupItemId;\n};\n\n/**\n * Renders a PanelDefinition's content inside of a Card.\n *\n * Internal structure:\n * <Panel> // renders an entire panel, incl. header and action buttons\n * <PanelContent> // renders loading, error or panel based on the queries' status\n * <PanelPluginLoader> // loads a panel plugin from the plugin registry and renders the PanelComponent with data from props.queryResults\n */\nexport const Panel = memo(function Panel(props: PanelProps) {\n const {\n definition,\n readHandlers,\n editHandlers,\n onMouseEnter,\n onMouseLeave,\n sx,\n panelOptions,\n panelGroupItemId,\n viewQueriesHandler,\n ...others\n } = props;\n\n // Make sure we have an ID we can use for aria attributes\n const generatedPanelId = useId('Panel');\n const headerId = `${generatedPanelId}-header`;\n\n const [contentElement, setContentElement] = useState<HTMLElement | null>(null);\n\n const { width, height } = useResizeObserver({ ref: contentElement });\n\n const contentDimensions = useMemo(() => {\n if (width === undefined || height === undefined) return undefined;\n return { width, height };\n }, [width, height]);\n\n const { queryResults } = useDataQueriesContext();\n const { getPlugin } = usePluginRegistry();\n\n const panelPropsForActions = useMemo(() => {\n return {\n spec: definition.spec.plugin.spec,\n queryResults: queryResults.map((query) => ({\n definition: query.definition,\n data: query.data,\n })),\n contentDimensions,\n definition,\n };\n }, [definition, contentDimensions, queryResults]);\n\n // Load plugin actions from the plugin\n const [pluginActions, setPluginActions] = useState<ReactNode[]>([]);\n\n useEffect(() => {\n const loadPluginActions = async (): Promise<void> => {\n const panelPluginKind = definition.spec.plugin.kind;\n\n if (!panelPluginKind || !panelPropsForActions || !getPlugin || typeof getPlugin !== 'function') {\n setPluginActions([]);\n return;\n }\n\n try {\n const plugin = await getPlugin('Panel', panelPluginKind);\n\n // More defensive checking for plugin and actions\n if (\n !plugin ||\n typeof plugin !== 'object' ||\n !plugin.actions ||\n !Array.isArray(plugin.actions) ||\n plugin.actions.length === 0\n ) {\n setPluginActions([]);\n return;\n }\n\n // Render plugin actions in header location\n const headerActions = plugin.actions\n .filter((action) => !action.location || action.location === 'header')\n .map((action, index): ReactNode | null => {\n const ActionComponent = action.component;\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return <ActionComponent key={`plugin-action-${index}`} {...(panelPropsForActions as any)} />;\n } catch (error) {\n console.warn(`Failed to render plugin action ${index}:`, error);\n return null;\n }\n })\n .filter((item): item is ReactNode => Boolean(item));\n\n setPluginActions(headerActions);\n } catch (error) {\n console.warn('Failed to load plugin actions:', error);\n setPluginActions([]);\n }\n };\n\n loadPluginActions();\n }, [definition.spec.plugin.kind, panelPropsForActions, getPlugin]);\n\n const handleMouseEnter: CardProps['onMouseEnter'] = (e) => {\n onMouseEnter?.(e);\n };\n\n const handleMouseLeave: CardProps['onMouseLeave'] = (e) => {\n onMouseLeave?.(e);\n };\n\n // default value for showIcons: if the dashboard is in editing mode or the panel is in fullscreen mode: 'always', otherwise 'hover'\n const showIcons = panelOptions?.showIcons ?? (editHandlers || readHandlers?.isPanelViewed ? 'always' : 'hover');\n const itemActionsConfig = definition.spec.plugin.spec?.actions\n ? (definition.spec.plugin.spec.actions as ActionOptions)\n : undefined;\n const itemActionsListConfig =\n itemActionsConfig?.enabled && itemActionsConfig.displayInHeader ? itemActionsConfig.actionsList : [];\n\n return (\n <SelectionProvider>\n <ItemActionsProvider>\n <Card\n component=\"section\"\n sx={combineSx(\n {\n width: '100%',\n height: '100%',\n display: 'flex',\n flexFlow: 'column nowrap',\n ':hover': { '--panel-hover': 'block' },\n },\n sx\n )}\n variant=\"outlined\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n aria-labelledby={headerId}\n aria-describedby={headerId}\n data-testid=\"panel\"\n {...others}\n >\n {!panelOptions?.hideHeader && (\n <PanelHeader\n extra={panelOptions?.extra?.({ panelDefinition: definition, panelGroupItemId })}\n id={headerId}\n title={definition.spec.display?.name ?? ''}\n description={definition.spec.display?.description}\n queryResults={queryResults}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n viewQueriesHandler={viewQueriesHandler}\n links={definition.spec.links}\n pluginActions={pluginActions}\n itemActionsListConfig={itemActionsListConfig}\n showIcons={showIcons}\n sx={{ py: '2px', pl: '8px', pr: '2px' }}\n dimension={contentDimensions}\n />\n )}\n <CardContent\n component=\"figure\"\n sx={{\n position: 'relative',\n overflow: 'hidden',\n flexGrow: 1,\n margin: 0,\n padding: 0,\n // Override MUI default style for last-child\n ':last-child': {\n padding: 0,\n },\n }}\n ref={setContentElement}\n >\n <ErrorBoundary FallbackComponent={ErrorAlert} resetKeys={[definition.spec, queryResults]}>\n <PanelContent\n definition={definition}\n panelPluginKind={definition.spec.plugin.kind}\n spec={definition.spec.plugin.spec}\n contentDimensions={contentDimensions}\n queryResults={queryResults}\n />\n </ErrorBoundary>\n </CardContent>\n </Card>\n </ItemActionsProvider>\n </SelectionProvider>\n );\n});\n"],"names":["Card","CardContent","ErrorAlert","ErrorBoundary","ItemActionsProvider","SelectionProvider","combineSx","useId","useDataQueriesContext","usePluginRegistry","memo","useEffect","useMemo","useState","useResizeObserver","PanelContent","PanelHeader","Panel","props","definition","readHandlers","editHandlers","onMouseEnter","onMouseLeave","sx","panelOptions","panelGroupItemId","viewQueriesHandler","others","generatedPanelId","headerId","contentElement","setContentElement","width","height","ref","contentDimensions","undefined","queryResults","getPlugin","panelPropsForActions","spec","plugin","map","query","data","pluginActions","setPluginActions","loadPluginActions","panelPluginKind","kind","actions","Array","isArray","length","headerActions","filter","action","location","index","ActionComponent","component","error","console","warn","item","Boolean","handleMouseEnter","e","handleMouseLeave","showIcons","isPanelViewed","itemActionsConfig","itemActionsListConfig","enabled","displayInHeader","actionsList","display","flexFlow","variant","aria-labelledby","aria-describedby","data-testid","hideHeader","extra","panelDefinition","id","title","name","description","links","py","pl","pr","dimension","position","overflow","flexGrow","margin","padding","FallbackComponent","resetKeys"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/Panel/Panel.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 { Card, CardContent, CardProps } from '@mui/material';\nimport {\n ErrorAlert,\n ErrorBoundary,\n ItemActionsProvider,\n SelectionProvider,\n combineSx,\n useId,\n} from '@perses-dev/components';\nimport { PanelGroupItemId } from '@perses-dev/core'; // TODO\nimport { PanelDefinition } from '@perses-dev/spec';\nimport { ActionOptions, useDataQueriesContext, usePluginRegistry } from '@perses-dev/plugin-system';\nimport { ReactNode, memo, useEffect, useMemo, useState } from 'react';\nimport useResizeObserver from 'use-resize-observer';\nimport { PanelContent } from './PanelContent';\nimport { PanelHeader, PanelHeaderProps } from './PanelHeader';\n\nexport interface PanelProps extends CardProps<'section'> {\n definition: PanelDefinition;\n readHandlers?: PanelHeaderProps['readHandlers'];\n editHandlers?: PanelHeaderProps['editHandlers'];\n panelOptions?: PanelOptions;\n panelGroupItemId?: PanelGroupItemId;\n viewQueriesHandler?: PanelHeaderProps['viewQueriesHandler'];\n}\n\nexport type PanelOptions = {\n /**\n * Allow you to hide the panel header if desired.\n * This can be useful in embedded mode for example.\n */\n hideHeader?: boolean;\n /**\n * Whether to show panel icons always, or only when hovering over the panel.\n * Default: if the dashboard is in editing mode or the panel is in fullscreen mode: 'always', otherwise 'hover'\n */\n showIcons?: 'always' | 'hover';\n /**\n * Content to render in right of the panel header. (top right of the panel)\n * It will only be rendered when the panel is in edit mode.\n */\n extra?: (props: PanelExtraProps) => ReactNode;\n};\n\nexport type PanelExtraProps = {\n /**\n * The PanelDefinition for the panel.\n */\n panelDefinition?: PanelDefinition;\n /**\n * The PanelGroupItemId for the panel.\n */\n panelGroupItemId?: PanelGroupItemId;\n};\n\n/**\n * Renders a PanelDefinition's content inside of a Card.\n *\n * Internal structure:\n * <Panel> // renders an entire panel, incl. header and action buttons\n * <PanelContent> // renders loading, error or panel based on the queries' status\n * <PanelPluginLoader> // loads a panel plugin from the plugin registry and renders the PanelComponent with data from props.queryResults\n */\nexport const Panel = memo(function Panel(props: PanelProps) {\n const {\n definition,\n readHandlers,\n editHandlers,\n onMouseEnter,\n onMouseLeave,\n sx,\n panelOptions,\n panelGroupItemId,\n viewQueriesHandler,\n ...others\n } = props;\n\n // Make sure we have an ID we can use for aria attributes\n const generatedPanelId = useId('Panel');\n const headerId = `${generatedPanelId}-header`;\n\n const [contentElement, setContentElement] = useState<HTMLElement | null>(null);\n\n const { width, height } = useResizeObserver({ ref: contentElement });\n\n const contentDimensions = useMemo(() => {\n if (width === undefined || height === undefined) return undefined;\n return { width, height };\n }, [width, height]);\n\n const { queryResults } = useDataQueriesContext();\n const { getPlugin } = usePluginRegistry();\n\n const panelPropsForActions = useMemo(() => {\n return {\n spec: definition.spec.plugin.spec,\n queryResults: queryResults.map((query) => ({\n definition: query.definition,\n data: query.data,\n })),\n contentDimensions,\n definition,\n };\n }, [definition, contentDimensions, queryResults]);\n\n // Load plugin actions from the plugin\n const [pluginActions, setPluginActions] = useState<ReactNode[]>([]);\n\n useEffect(() => {\n const loadPluginActions = async (): Promise<void> => {\n const panelPluginKind = definition.spec.plugin.kind;\n\n if (!panelPluginKind || !panelPropsForActions || !getPlugin || typeof getPlugin !== 'function') {\n setPluginActions([]);\n return;\n }\n\n try {\n const plugin = await getPlugin('Panel', panelPluginKind);\n\n // More defensive checking for plugin and actions\n if (\n !plugin ||\n typeof plugin !== 'object' ||\n !plugin.actions ||\n !Array.isArray(plugin.actions) ||\n plugin.actions.length === 0\n ) {\n setPluginActions([]);\n return;\n }\n\n // Render plugin actions in header location\n const headerActions = plugin.actions\n .filter((action) => !action.location || action.location === 'header')\n .map((action, index): ReactNode | null => {\n const ActionComponent = action.component;\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return <ActionComponent key={`plugin-action-${index}`} {...(panelPropsForActions as any)} />;\n } catch (error) {\n console.warn(`Failed to render plugin action ${index}:`, error);\n return null;\n }\n })\n .filter((item): item is ReactNode => Boolean(item));\n\n setPluginActions(headerActions);\n } catch (error) {\n console.warn('Failed to load plugin actions:', error);\n setPluginActions([]);\n }\n };\n\n loadPluginActions();\n }, [definition.spec.plugin.kind, panelPropsForActions, getPlugin]);\n\n const handleMouseEnter: CardProps['onMouseEnter'] = (e) => {\n onMouseEnter?.(e);\n };\n\n const handleMouseLeave: CardProps['onMouseLeave'] = (e) => {\n onMouseLeave?.(e);\n };\n\n // default value for showIcons: if the dashboard is in editing mode or the panel is in fullscreen mode: 'always', otherwise 'hover'\n const showIcons = panelOptions?.showIcons ?? (editHandlers || readHandlers?.isPanelViewed ? 'always' : 'hover');\n const itemActionsConfig = definition.spec.plugin.spec?.actions\n ? (definition.spec.plugin.spec.actions as ActionOptions)\n : undefined;\n const itemActionsListConfig =\n itemActionsConfig?.enabled && itemActionsConfig.displayInHeader ? itemActionsConfig.actionsList : [];\n\n return (\n <SelectionProvider>\n <ItemActionsProvider>\n <Card\n component=\"section\"\n sx={combineSx(\n {\n width: '100%',\n height: '100%',\n display: 'flex',\n flexFlow: 'column nowrap',\n ':hover': { '--panel-hover': 'block' },\n },\n sx\n )}\n variant=\"outlined\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n aria-labelledby={headerId}\n aria-describedby={headerId}\n data-testid=\"panel\"\n {...others}\n >\n {!panelOptions?.hideHeader && (\n <PanelHeader\n extra={panelOptions?.extra?.({ panelDefinition: definition, panelGroupItemId })}\n id={headerId}\n title={definition.spec.display?.name ?? ''}\n description={definition.spec.display?.description}\n queryResults={queryResults}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n viewQueriesHandler={viewQueriesHandler}\n links={definition.spec.links}\n pluginActions={pluginActions}\n itemActionsListConfig={itemActionsListConfig}\n showIcons={showIcons}\n sx={{ py: '2px', pl: '8px', pr: '2px' }}\n dimension={contentDimensions}\n />\n )}\n <CardContent\n component=\"figure\"\n sx={{\n position: 'relative',\n overflow: 'hidden',\n flexGrow: 1,\n margin: 0,\n padding: 0,\n // Override MUI default style for last-child\n ':last-child': {\n padding: 0,\n },\n }}\n ref={setContentElement}\n >\n <ErrorBoundary FallbackComponent={ErrorAlert} resetKeys={[definition.spec, queryResults]}>\n <PanelContent\n definition={definition}\n panelPluginKind={definition.spec.plugin.kind}\n spec={definition.spec.plugin.spec}\n contentDimensions={contentDimensions}\n queryResults={queryResults}\n />\n </ErrorBoundary>\n </CardContent>\n </Card>\n </ItemActionsProvider>\n </SelectionProvider>\n );\n});\n"],"names":["Card","CardContent","ErrorAlert","ErrorBoundary","ItemActionsProvider","SelectionProvider","combineSx","useId","useDataQueriesContext","usePluginRegistry","memo","useEffect","useMemo","useState","useResizeObserver","PanelContent","PanelHeader","Panel","props","definition","readHandlers","editHandlers","onMouseEnter","onMouseLeave","sx","panelOptions","panelGroupItemId","viewQueriesHandler","others","generatedPanelId","headerId","contentElement","setContentElement","width","height","ref","contentDimensions","undefined","queryResults","getPlugin","panelPropsForActions","spec","plugin","map","query","data","pluginActions","setPluginActions","loadPluginActions","panelPluginKind","kind","actions","Array","isArray","length","headerActions","filter","action","location","index","ActionComponent","component","error","console","warn","item","Boolean","handleMouseEnter","e","handleMouseLeave","showIcons","isPanelViewed","itemActionsConfig","itemActionsListConfig","enabled","displayInHeader","actionsList","display","flexFlow","variant","aria-labelledby","aria-describedby","data-testid","hideHeader","extra","panelDefinition","id","title","name","description","links","py","pl","pr","dimension","position","overflow","flexGrow","margin","padding","FallbackComponent","resetKeys"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { QueryData } from '@perses-dev/plugin-system';
3
- import { Link } from '@perses-dev/core';
3
+ import { Link } from '@perses-dev/spec';
4
4
  import { PanelOptions } from './Panel';
5
5
  export interface PanelActionsProps {
6
6
  title?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"PanelActions.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelActions.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAmD,SAAS,EAAqB,MAAM,OAAO,CAAC;AAEtG,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAatD,OAAO,EAAE,IAAI,EAAU,MAAM,kBAAkB,CAAC;AAUhD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE;QACb,gBAAgB,EAAE,MAAM,IAAI,CAAC;QAC7B,qBAAqB,EAAE,MAAM,IAAI,CAAC;QAClC,kBAAkB,EAAE,MAAM,IAAI,CAAC;KAChC,CAAC;IACF,YAAY,CAAC,EAAE;QACb,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,IAAI,CAAC;KAC9B,CAAC;IACF,kBAAkB,CAAC,EAAE;QACnB,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB,CAAC;IACF,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;CACtC;AASD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAkQpD,CAAC"}
1
+ {"version":3,"file":"PanelActions.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelActions.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAmD,SAAS,EAAiC,MAAM,OAAO,CAAC;AAElH,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAatD,OAAO,EAAE,IAAI,EAAU,MAAM,kBAAkB,CAAC;AAUhD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE;QACb,gBAAgB,EAAE,MAAM,IAAI,CAAC;QAC7B,qBAAqB,EAAE,MAAM,IAAI,CAAC;QAClC,kBAAkB,EAAE,MAAM,IAAI,CAAC;KAChC,CAAC;IACF,YAAY,CAAC,EAAE;QACb,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,IAAI,CAAC;KAC9B,CAAC;IACF,kBAAkB,CAAC,EAAE;QACnB,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB,CAAC;IACF,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;CACtC;AASD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAkQpD,CAAC"}
@@ -11,7 +11,7 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
- import { Stack, Box, Popover, CircularProgress, styled } from '@mui/material';
14
+ import { Stack, Box, CircularProgress, styled, Popper, ClickAwayListener } from '@mui/material';
15
15
  import { isValidElement, useMemo, useState } from 'react';
16
16
  import { InfoTooltip } from '@perses-dev/components';
17
17
  import DatabaseSearch from 'mdi-material-ui/DatabaseSearch';
@@ -27,8 +27,8 @@ import AlertCircleIcon from 'mdi-material-ui/AlertCircle';
27
27
  import InformationOutlineIcon from 'mdi-material-ui/InformationOutline';
28
28
  import LightningBoltIcon from 'mdi-material-ui/LightningBolt';
29
29
  import { ARIA_LABEL_TEXT, HEADER_ACTIONS_CONTAINER_NAME, HEADER_MEDIUM_WIDTH, HEADER_SMALL_WIDTH, TOOLTIP_TEXT } from '../../constants';
30
+ import { LinksDisplay } from '../LinksDisplay';
30
31
  import { HeaderIconButton } from './HeaderIconButton';
31
- import { PanelLinks } from './PanelLinks';
32
32
  const noticeTypeToIcon = {
33
33
  error: /*#__PURE__*/ _jsx(AlertCircleIcon, {
34
34
  color: "error"
@@ -74,8 +74,9 @@ export const PanelActions = ({ editHandlers, readHandlers, viewQueriesHandler, e
74
74
  descriptionTooltipId,
75
75
  description
76
76
  ]);
77
- const linksAction = links && links.length > 0 && /*#__PURE__*/ _jsx(PanelLinks, {
78
- links: links
77
+ const linksAction = links && links.length > 0 && /*#__PURE__*/ _jsx(LinksDisplay, {
78
+ links: links,
79
+ variant: "panel"
79
80
  });
80
81
  const extraActions = editHandlers === undefined && extra;
81
82
  const queryStateIndicator = useMemo(()=>{
@@ -383,20 +384,20 @@ export const PanelActions = ({ editHandlers, readHandlers, viewQueriesHandler, e
383
384
  ]
384
385
  });
385
386
  };
386
- const OverflowMenu = ({ children, title, icon, direction = 'row' })=>{
387
- const [anchorPosition, setAnchorPosition] = useState();
387
+ const OverflowMenu = ({ children, title, icon, direction = 'row', placement = 'bottom', offsetX = -2, offsetY = -25 })=>{
388
+ const [anchorEl, setAnchorEl] = useState(null);
388
389
  // do not show overflow menu if there is no content (for example, edit actions are hidden)
389
390
  const hasContent = /*#__PURE__*/ isValidElement(children) || Array.isArray(children) && children.some(isValidElement);
390
391
  if (!hasContent) {
391
392
  return null;
392
393
  }
393
394
  const handleClick = (event)=>{
394
- setAnchorPosition(event.currentTarget.getBoundingClientRect());
395
+ setAnchorEl(anchorEl ? null : event.currentTarget);
395
396
  };
396
397
  const handleClose = ()=>{
397
- setAnchorPosition(undefined);
398
+ setAnchorEl(null);
398
399
  };
399
- const open = Boolean(anchorPosition);
400
+ const open = Boolean(anchorEl);
400
401
  const id = open ? 'actions-menu' : undefined;
401
402
  return /*#__PURE__*/ _jsxs(Box, {
402
403
  sx: {
@@ -413,24 +414,38 @@ const OverflowMenu = ({ children, title, icon, direction = 'row' })=>{
413
414
  fontSize: "inherit"
414
415
  })
415
416
  }),
416
- /*#__PURE__*/ _jsx(Popover, {
417
+ /*#__PURE__*/ _jsx(Popper, {
417
418
  id: id,
418
419
  open: open,
419
- anchorReference: "anchorPosition",
420
- anchorPosition: anchorPosition,
421
- onClose: handleClose,
422
- anchorOrigin: {
423
- vertical: 'bottom',
424
- horizontal: 'left'
420
+ anchorEl: anchorEl,
421
+ placement: placement,
422
+ modifiers: [
423
+ {
424
+ name: 'offset',
425
+ options: {
426
+ offset: [
427
+ offsetX,
428
+ offsetY
429
+ ]
430
+ }
431
+ }
432
+ ],
433
+ sx: {
434
+ backgroundColor: (theme)=>theme.palette.background.paper,
435
+ borderRadius: 1,
436
+ boxShadow: (theme)=>theme.shadows[4]
425
437
  },
426
- children: /*#__PURE__*/ _jsx(Stack, {
427
- direction: direction,
428
- alignItems: "center",
429
- sx: {
430
- padding: 1
431
- },
432
- onClick: handleClose,
433
- children: children
438
+ children: /*#__PURE__*/ _jsx(ClickAwayListener, {
439
+ onClickAway: handleClose,
440
+ children: /*#__PURE__*/ _jsx(Stack, {
441
+ direction: direction,
442
+ alignItems: "center",
443
+ sx: {
444
+ padding: 1
445
+ },
446
+ onClick: handleClose,
447
+ children: children
448
+ })
434
449
  })
435
450
  })
436
451
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/PanelActions.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 { Stack, Box, Popover, CircularProgress, styled, PopoverPosition } from '@mui/material';\nimport { isValidElement, PropsWithChildren, ReactElement, ReactNode, useMemo, useState } from 'react';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { QueryData } from '@perses-dev/plugin-system';\nimport DatabaseSearch from 'mdi-material-ui/DatabaseSearch';\nimport ArrowCollapseIcon from 'mdi-material-ui/ArrowCollapse';\nimport ArrowExpandIcon from 'mdi-material-ui/ArrowExpand';\nimport PencilIcon from 'mdi-material-ui/PencilOutline';\nimport DeleteIcon from 'mdi-material-ui/DeleteOutline';\nimport DragIcon from 'mdi-material-ui/DragVertical';\nimport ContentCopyIcon from 'mdi-material-ui/ContentCopy';\nimport MenuIcon from 'mdi-material-ui/Menu';\nimport AlertIcon from 'mdi-material-ui/Alert';\nimport AlertCircleIcon from 'mdi-material-ui/AlertCircle';\nimport InformationOutlineIcon from 'mdi-material-ui/InformationOutline';\nimport LightningBoltIcon from 'mdi-material-ui/LightningBolt';\nimport { Link, Notice } from '@perses-dev/core';\nimport {\n ARIA_LABEL_TEXT,\n HEADER_ACTIONS_CONTAINER_NAME,\n HEADER_MEDIUM_WIDTH,\n HEADER_SMALL_WIDTH,\n TOOLTIP_TEXT,\n} from '../../constants';\nimport { HeaderIconButton } from './HeaderIconButton';\nimport { PanelLinks } from './PanelLinks';\nimport { PanelOptions } from './Panel';\n\nconst noticeTypeToIcon: Record<Notice['type'], ReactNode> = {\n error: <AlertCircleIcon color=\"error\" />,\n warning: <AlertIcon fontSize=\"inherit\" color=\"warning\" />,\n info: <InformationOutlineIcon fontSize=\"inherit\" color=\"info\" />,\n};\n\nexport interface PanelActionsProps {\n title?: string;\n description?: string;\n descriptionTooltipId: string;\n links?: Link[];\n extra?: React.ReactNode;\n editHandlers?: {\n onEditPanelClick: () => void;\n onDuplicatePanelClick: () => void;\n onDeletePanelClick: () => void;\n };\n readHandlers?: {\n isPanelViewed?: boolean;\n onViewPanelClick: () => void;\n };\n viewQueriesHandler?: {\n onClick: () => void;\n };\n queryResults: QueryData[];\n pluginActions?: ReactNode[];\n itemActions?: ReactNode[];\n areItemActionsDisabled?: boolean;\n showIcons: PanelOptions['showIcons'];\n}\n\nconst ConditionalBox = styled(Box)({\n display: 'none',\n alignItems: 'center',\n flexGrow: 1,\n justifyContent: 'flex-end',\n});\n\nexport const PanelActions: React.FC<PanelActionsProps> = ({\n editHandlers,\n readHandlers,\n viewQueriesHandler,\n extra,\n title,\n description,\n descriptionTooltipId,\n links,\n queryResults,\n pluginActions = [],\n itemActions = [],\n showIcons,\n}) => {\n const descriptionAction = useMemo((): ReactNode | undefined => {\n if (description && description.trim().length > 0) {\n return (\n <InfoTooltip id={descriptionTooltipId} description={description} enterDelay={100}>\n <HeaderIconButton aria-label=\"panel description\" size=\"small\">\n <InformationOutlineIcon\n aria-describedby=\"info-tooltip\"\n aria-hidden={false}\n fontSize=\"inherit\"\n sx={{ color: (theme) => theme.palette.text.secondary }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [descriptionTooltipId, description]);\n\n const linksAction = links && links.length > 0 && <PanelLinks links={links} />;\n const extraActions = editHandlers === undefined && extra;\n\n const queryStateIndicator = useMemo((): ReactNode | undefined => {\n const hasData = queryResults.some((q) => q.data);\n const isFetching = queryResults.some((q) => q.isFetching);\n const queryErrors = queryResults.filter((q) => q.error);\n\n if (isFetching && hasData) {\n return <CircularProgress aria-label=\"loading\" size=\"1.125rem\" />;\n } else if (queryErrors.length > 0) {\n const errorTexts = queryErrors\n .map((q) => q.error)\n .map((e) => e.message)\n .join('\\n');\n\n return (\n <InfoTooltip description={errorTexts}>\n <HeaderIconButton aria-label=\"panel errors\" size=\"small\">\n <AlertIcon\n fontSize=\"inherit\"\n sx={{\n color: (theme) => theme.palette.error.main,\n }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n }, [queryResults]);\n\n const noticesIndicator = useMemo(() => {\n const notices = queryResults.flatMap((q) => {\n return q.data?.metadata?.notices ?? [];\n });\n\n if (notices.length > 0) {\n const lastNotice = notices[notices.length - 1]!;\n\n return (\n <InfoTooltip description={lastNotice.message}>\n <HeaderIconButton aria-label=\"panel notices\" size=\"small\">\n {noticeTypeToIcon[lastNotice.type]}\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n }, [queryResults]);\n\n const readActions = useMemo((): ReactNode | undefined => {\n if (readHandlers !== undefined) {\n return (\n <InfoTooltip description={TOOLTIP_TEXT.viewPanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.viewPanel(title)}\n size=\"small\"\n onClick={readHandlers.onViewPanelClick}\n >\n {readHandlers.isPanelViewed ? (\n <ArrowCollapseIcon fontSize=\"inherit\" />\n ) : (\n <ArrowExpandIcon fontSize=\"inherit\" />\n )}\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [readHandlers, title]);\n\n const viewQueryAction = useMemo(() => {\n if (!viewQueriesHandler?.onClick) return null;\n return (\n <InfoTooltip description={TOOLTIP_TEXT.queryView}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.openQueryView(title)}\n size=\"small\"\n onClick={viewQueriesHandler.onClick}\n >\n <DatabaseSearch fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }, [viewQueriesHandler, title]);\n\n const editActions = useMemo((): ReactNode | undefined => {\n if (editHandlers !== undefined) {\n // If there are edit handlers, always just show the edit buttons\n return (\n <>\n <InfoTooltip description={TOOLTIP_TEXT.editPanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.editPanel(title)}\n size=\"small\"\n onClick={editHandlers.onEditPanelClick}\n >\n <PencilIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n <InfoTooltip description={TOOLTIP_TEXT.duplicatePanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.duplicatePanel(title)}\n size=\"small\"\n onClick={editHandlers.onDuplicatePanelClick}\n >\n <ContentCopyIcon\n fontSize=\"inherit\"\n sx={{\n // Shrink this icon a little bit to look more consistent\n // with the other icons in the header.\n transform: 'scale(0.925)',\n }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n <InfoTooltip description={TOOLTIP_TEXT.deletePanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.deletePanel(title)}\n size=\"small\"\n onClick={editHandlers.onDeletePanelClick}\n >\n <DeleteIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n </>\n );\n }\n return undefined;\n }, [editHandlers, title]);\n\n const moveAction = useMemo((): ReactNode | undefined => {\n if (editActions && !readHandlers?.isPanelViewed) {\n return (\n <Box sx={{ background: (theme) => theme.palette.background.default }}>\n <InfoTooltip description={TOOLTIP_TEXT.movePanel}>\n <HeaderIconButton aria-label={ARIA_LABEL_TEXT.movePanel(title)} size=\"small\">\n <DragIcon className=\"drag-handle\" sx={{ cursor: 'grab' }} fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n </Box>\n );\n }\n return undefined;\n }, [editActions, readHandlers, title]);\n\n const divider = <Box sx={{ flexGrow: 1 }}></Box>;\n\n // By default, the panel header shows certain icons only on hover if the panel is in non-editing, non-fullscreen mode\n const OnHover = ({ children }: PropsWithChildren): ReactNode =>\n showIcons === 'hover' ? <Box sx={{ display: 'var(--panel-hover, none)' }}>{children}</Box> : <>{children}</>;\n\n return (\n <>\n {/* small panel width: move all icons except move/grab to overflow menu */}\n <ConditionalBox\n sx={(theme) => ({\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).between(0, HEADER_SMALL_WIDTH)]: { display: 'flex' },\n })}\n >\n {divider}\n <OnHover>\n <OverflowMenu title={title}>\n {descriptionAction} {linksAction} {queryStateIndicator} {noticesIndicator} {extraActions} {viewQueryAction}\n {readActions} {pluginActions} {itemActions}\n {editActions}\n </OverflowMenu>\n {moveAction}\n </OnHover>\n </ConditionalBox>\n\n {/* medium panel width: move edit icons to overflow menu */}\n <ConditionalBox\n sx={(theme) => ({\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).between(HEADER_SMALL_WIDTH, HEADER_MEDIUM_WIDTH)]: {\n display: 'flex',\n },\n })}\n >\n <OnHover>\n {descriptionAction} {linksAction}\n </OnHover>\n {divider} {queryStateIndicator}\n {noticesIndicator}\n <OnHover>\n {extraActions}\n {readActions}\n <OverflowMenu title={title}>\n {editActions} {viewQueryAction} {pluginActions} {itemActions}\n </OverflowMenu>\n {moveAction}\n </OnHover>\n </ConditionalBox>\n\n {/* large panel width: show all icons in panel header */}\n <ConditionalBox\n sx={(theme) => ({\n // flip the logic here; if the browser (or jsdom) does not support container queries, always show all icons\n display: 'flex',\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).down(HEADER_MEDIUM_WIDTH)]: { display: 'none' },\n })}\n >\n <OnHover>\n {descriptionAction} {linksAction}\n </OnHover>\n {divider} {queryStateIndicator}\n {noticesIndicator}\n <OnHover>\n {extraActions}\n {viewQueryAction}\n {readActions} {editActions}\n {/* Show plugin actions inside a menu if it gets crowded */}\n {pluginActions.length <= 1 ? pluginActions : <OverflowMenu title={title}>{pluginActions}</OverflowMenu>}\n {itemActions.length <= 1 ? (\n itemActions\n ) : (\n <InfoTooltip description={`${itemActions.length} actions`}>\n <OverflowMenu icon={<LightningBoltIcon fontSize=\"inherit\" />} direction=\"column\" title={title}>\n {itemActions}\n </OverflowMenu>\n </InfoTooltip>\n )}\n {moveAction}\n </OnHover>\n </ConditionalBox>\n </>\n );\n};\n\nconst OverflowMenu: React.FC<\n PropsWithChildren<{ title?: string; icon?: ReactElement; direction?: 'row' | 'column' }>\n> = ({ children, title, icon, direction = 'row' }) => {\n const [anchorPosition, setAnchorPosition] = useState<PopoverPosition>();\n\n // do not show overflow menu if there is no content (for example, edit actions are hidden)\n const hasContent = isValidElement(children) || (Array.isArray(children) && children.some(isValidElement));\n if (!hasContent) {\n return null;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLElement>): void => {\n setAnchorPosition(event.currentTarget.getBoundingClientRect());\n };\n\n const handleClose = (): void => {\n setAnchorPosition(undefined);\n };\n\n const open = Boolean(anchorPosition);\n const id = open ? 'actions-menu' : undefined;\n\n return (\n <Box sx={{ background: (theme) => theme.palette.background.default }}>\n <HeaderIconButton\n className=\"show-actions\"\n aria-describedby={id}\n onClick={handleClick}\n aria-label={ARIA_LABEL_TEXT.showPanelActions(title)}\n size=\"small\"\n >\n {icon ?? <MenuIcon fontSize=\"inherit\" />}\n </HeaderIconButton>\n <Popover\n id={id}\n open={open}\n anchorReference=\"anchorPosition\"\n anchorPosition={anchorPosition}\n onClose={handleClose}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left',\n }}\n >\n <Stack direction={direction} alignItems=\"center\" sx={{ padding: 1 }} onClick={handleClose}>\n {children}\n </Stack>\n </Popover>\n </Box>\n );\n};\n"],"names":["Stack","Box","Popover","CircularProgress","styled","isValidElement","useMemo","useState","InfoTooltip","DatabaseSearch","ArrowCollapseIcon","ArrowExpandIcon","PencilIcon","DeleteIcon","DragIcon","ContentCopyIcon","MenuIcon","AlertIcon","AlertCircleIcon","InformationOutlineIcon","LightningBoltIcon","ARIA_LABEL_TEXT","HEADER_ACTIONS_CONTAINER_NAME","HEADER_MEDIUM_WIDTH","HEADER_SMALL_WIDTH","TOOLTIP_TEXT","HeaderIconButton","PanelLinks","noticeTypeToIcon","error","color","warning","fontSize","info","ConditionalBox","display","alignItems","flexGrow","justifyContent","PanelActions","editHandlers","readHandlers","viewQueriesHandler","extra","title","description","descriptionTooltipId","links","queryResults","pluginActions","itemActions","showIcons","descriptionAction","trim","length","id","enterDelay","aria-label","size","aria-describedby","aria-hidden","sx","theme","palette","text","secondary","undefined","linksAction","extraActions","queryStateIndicator","hasData","some","q","data","isFetching","queryErrors","filter","errorTexts","map","e","message","join","main","noticesIndicator","notices","flatMap","metadata","lastNotice","type","readActions","viewPanel","onClick","onViewPanelClick","isPanelViewed","viewQueryAction","queryView","openQueryView","editActions","editPanel","onEditPanelClick","duplicatePanel","onDuplicatePanelClick","transform","deletePanel","onDeletePanelClick","moveAction","background","default","movePanel","className","cursor","divider","OnHover","children","containerQueries","between","OverflowMenu","down","icon","direction","anchorPosition","setAnchorPosition","hasContent","Array","isArray","handleClick","event","currentTarget","getBoundingClientRect","handleClose","open","Boolean","showPanelActions","anchorReference","onClose","anchorOrigin","vertical","horizontal","padding"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelActions.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 { Stack, Box, CircularProgress, styled, Popper, ClickAwayListener } from '@mui/material';\nimport { isValidElement, PropsWithChildren, ReactElement, ReactNode, useMemo, useState, MouseEvent } from 'react';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { QueryData } from '@perses-dev/plugin-system';\nimport DatabaseSearch from 'mdi-material-ui/DatabaseSearch';\nimport ArrowCollapseIcon from 'mdi-material-ui/ArrowCollapse';\nimport ArrowExpandIcon from 'mdi-material-ui/ArrowExpand';\nimport PencilIcon from 'mdi-material-ui/PencilOutline';\nimport DeleteIcon from 'mdi-material-ui/DeleteOutline';\nimport DragIcon from 'mdi-material-ui/DragVertical';\nimport ContentCopyIcon from 'mdi-material-ui/ContentCopy';\nimport MenuIcon from 'mdi-material-ui/Menu';\nimport AlertIcon from 'mdi-material-ui/Alert';\nimport AlertCircleIcon from 'mdi-material-ui/AlertCircle';\nimport InformationOutlineIcon from 'mdi-material-ui/InformationOutline';\nimport LightningBoltIcon from 'mdi-material-ui/LightningBolt';\nimport { Link, Notice } from '@perses-dev/spec';\nimport {\n ARIA_LABEL_TEXT,\n HEADER_ACTIONS_CONTAINER_NAME,\n HEADER_MEDIUM_WIDTH,\n HEADER_SMALL_WIDTH,\n TOOLTIP_TEXT,\n} from '../../constants';\nimport { LinksDisplay } from '../LinksDisplay';\nimport { HeaderIconButton } from './HeaderIconButton';\nimport { PanelOptions } from './Panel';\n\nconst noticeTypeToIcon: Record<Notice['type'], ReactNode> = {\n error: <AlertCircleIcon color=\"error\" />,\n warning: <AlertIcon fontSize=\"inherit\" color=\"warning\" />,\n info: <InformationOutlineIcon fontSize=\"inherit\" color=\"info\" />,\n};\n\nexport interface PanelActionsProps {\n title?: string;\n description?: string;\n descriptionTooltipId: string;\n links?: Link[];\n extra?: React.ReactNode;\n editHandlers?: {\n onEditPanelClick: () => void;\n onDuplicatePanelClick: () => void;\n onDeletePanelClick: () => void;\n };\n readHandlers?: {\n isPanelViewed?: boolean;\n onViewPanelClick: () => void;\n };\n viewQueriesHandler?: {\n onClick: () => void;\n };\n queryResults: QueryData[];\n pluginActions?: ReactNode[];\n itemActions?: ReactNode[];\n areItemActionsDisabled?: boolean;\n showIcons: PanelOptions['showIcons'];\n}\n\nconst ConditionalBox = styled(Box)({\n display: 'none',\n alignItems: 'center',\n flexGrow: 1,\n justifyContent: 'flex-end',\n});\n\nexport const PanelActions: React.FC<PanelActionsProps> = ({\n editHandlers,\n readHandlers,\n viewQueriesHandler,\n extra,\n title,\n description,\n descriptionTooltipId,\n links,\n queryResults,\n pluginActions = [],\n itemActions = [],\n showIcons,\n}) => {\n const descriptionAction = useMemo((): ReactNode | undefined => {\n if (description && description.trim().length > 0) {\n return (\n <InfoTooltip id={descriptionTooltipId} description={description} enterDelay={100}>\n <HeaderIconButton aria-label=\"panel description\" size=\"small\">\n <InformationOutlineIcon\n aria-describedby=\"info-tooltip\"\n aria-hidden={false}\n fontSize=\"inherit\"\n sx={{ color: (theme) => theme.palette.text.secondary }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [descriptionTooltipId, description]);\n\n const linksAction = links && links.length > 0 && <LinksDisplay links={links} variant=\"panel\" />;\n const extraActions = editHandlers === undefined && extra;\n\n const queryStateIndicator = useMemo((): ReactNode | undefined => {\n const hasData = queryResults.some((q) => q.data);\n const isFetching = queryResults.some((q) => q.isFetching);\n const queryErrors = queryResults.filter((q) => q.error);\n\n if (isFetching && hasData) {\n return <CircularProgress aria-label=\"loading\" size=\"1.125rem\" />;\n } else if (queryErrors.length > 0) {\n const errorTexts = queryErrors\n .map((q) => q.error)\n .map((e) => e.message)\n .join('\\n');\n\n return (\n <InfoTooltip description={errorTexts}>\n <HeaderIconButton aria-label=\"panel errors\" size=\"small\">\n <AlertIcon\n fontSize=\"inherit\"\n sx={{\n color: (theme) => theme.palette.error.main,\n }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n }, [queryResults]);\n\n const noticesIndicator = useMemo(() => {\n const notices = queryResults.flatMap((q) => {\n return q.data?.metadata?.notices ?? [];\n });\n\n if (notices.length > 0) {\n const lastNotice = notices[notices.length - 1]!;\n\n return (\n <InfoTooltip description={lastNotice.message}>\n <HeaderIconButton aria-label=\"panel notices\" size=\"small\">\n {noticeTypeToIcon[lastNotice.type]}\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n }, [queryResults]);\n\n const readActions = useMemo((): ReactNode | undefined => {\n if (readHandlers !== undefined) {\n return (\n <InfoTooltip description={TOOLTIP_TEXT.viewPanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.viewPanel(title)}\n size=\"small\"\n onClick={readHandlers.onViewPanelClick}\n >\n {readHandlers.isPanelViewed ? (\n <ArrowCollapseIcon fontSize=\"inherit\" />\n ) : (\n <ArrowExpandIcon fontSize=\"inherit\" />\n )}\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [readHandlers, title]);\n\n const viewQueryAction = useMemo(() => {\n if (!viewQueriesHandler?.onClick) return null;\n return (\n <InfoTooltip description={TOOLTIP_TEXT.queryView}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.openQueryView(title)}\n size=\"small\"\n onClick={viewQueriesHandler.onClick}\n >\n <DatabaseSearch fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }, [viewQueriesHandler, title]);\n\n const editActions = useMemo((): ReactNode | undefined => {\n if (editHandlers !== undefined) {\n // If there are edit handlers, always just show the edit buttons\n return (\n <>\n <InfoTooltip description={TOOLTIP_TEXT.editPanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.editPanel(title)}\n size=\"small\"\n onClick={editHandlers.onEditPanelClick}\n >\n <PencilIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n <InfoTooltip description={TOOLTIP_TEXT.duplicatePanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.duplicatePanel(title)}\n size=\"small\"\n onClick={editHandlers.onDuplicatePanelClick}\n >\n <ContentCopyIcon\n fontSize=\"inherit\"\n sx={{\n // Shrink this icon a little bit to look more consistent\n // with the other icons in the header.\n transform: 'scale(0.925)',\n }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n <InfoTooltip description={TOOLTIP_TEXT.deletePanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.deletePanel(title)}\n size=\"small\"\n onClick={editHandlers.onDeletePanelClick}\n >\n <DeleteIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n </>\n );\n }\n return undefined;\n }, [editHandlers, title]);\n\n const moveAction = useMemo((): ReactNode | undefined => {\n if (editActions && !readHandlers?.isPanelViewed) {\n return (\n <Box sx={{ background: (theme) => theme.palette.background.default }}>\n <InfoTooltip description={TOOLTIP_TEXT.movePanel}>\n <HeaderIconButton aria-label={ARIA_LABEL_TEXT.movePanel(title)} size=\"small\">\n <DragIcon className=\"drag-handle\" sx={{ cursor: 'grab' }} fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n </Box>\n );\n }\n return undefined;\n }, [editActions, readHandlers, title]);\n\n const divider = <Box sx={{ flexGrow: 1 }}></Box>;\n\n // By default, the panel header shows certain icons only on hover if the panel is in non-editing, non-fullscreen mode\n const OnHover = ({ children }: PropsWithChildren): ReactNode =>\n showIcons === 'hover' ? <Box sx={{ display: 'var(--panel-hover, none)' }}>{children}</Box> : <>{children}</>;\n\n return (\n <>\n {/* small panel width: move all icons except move/grab to overflow menu */}\n <ConditionalBox\n sx={(theme) => ({\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).between(0, HEADER_SMALL_WIDTH)]: { display: 'flex' },\n })}\n >\n {divider}\n <OnHover>\n <OverflowMenu title={title}>\n {descriptionAction} {linksAction} {queryStateIndicator} {noticesIndicator} {extraActions} {viewQueryAction}\n {readActions} {pluginActions} {itemActions}\n {editActions}\n </OverflowMenu>\n {moveAction}\n </OnHover>\n </ConditionalBox>\n\n {/* medium panel width: move edit icons to overflow menu */}\n <ConditionalBox\n sx={(theme) => ({\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).between(HEADER_SMALL_WIDTH, HEADER_MEDIUM_WIDTH)]: {\n display: 'flex',\n },\n })}\n >\n <OnHover>\n {descriptionAction} {linksAction}\n </OnHover>\n {divider} {queryStateIndicator}\n {noticesIndicator}\n <OnHover>\n {extraActions}\n {readActions}\n <OverflowMenu title={title}>\n {editActions} {viewQueryAction} {pluginActions} {itemActions}\n </OverflowMenu>\n {moveAction}\n </OnHover>\n </ConditionalBox>\n\n {/* large panel width: show all icons in panel header */}\n <ConditionalBox\n sx={(theme) => ({\n // flip the logic here; if the browser (or jsdom) does not support container queries, always show all icons\n display: 'flex',\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).down(HEADER_MEDIUM_WIDTH)]: { display: 'none' },\n })}\n >\n <OnHover>\n {descriptionAction} {linksAction}\n </OnHover>\n {divider} {queryStateIndicator}\n {noticesIndicator}\n <OnHover>\n {extraActions}\n {viewQueryAction}\n {readActions} {editActions}\n {/* Show plugin actions inside a menu if it gets crowded */}\n {pluginActions.length <= 1 ? pluginActions : <OverflowMenu title={title}>{pluginActions}</OverflowMenu>}\n {itemActions.length <= 1 ? (\n itemActions\n ) : (\n <InfoTooltip description={`${itemActions.length} actions`}>\n <OverflowMenu icon={<LightningBoltIcon fontSize=\"inherit\" />} direction=\"column\" title={title}>\n {itemActions}\n </OverflowMenu>\n </InfoTooltip>\n )}\n {moveAction}\n </OnHover>\n </ConditionalBox>\n </>\n );\n};\n\nconst OverflowMenu: React.FC<\n PropsWithChildren<{\n title?: string;\n icon?: ReactElement;\n direction?: 'row' | 'column';\n placement?:\n | 'bottom'\n | 'top'\n | 'left'\n | 'right'\n | 'bottom-start'\n | 'bottom-end'\n | 'top-start'\n | 'top-end'\n | 'left-start'\n | 'left-end'\n | 'right-start'\n | 'right-end';\n offsetX?: number;\n offsetY?: number;\n }>\n> = ({ children, title, icon, direction = 'row', placement = 'bottom', offsetX = -2, offsetY = -25 }) => {\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n\n // do not show overflow menu if there is no content (for example, edit actions are hidden)\n const hasContent = isValidElement(children) || (Array.isArray(children) && children.some(isValidElement));\n if (!hasContent) {\n return null;\n }\n\n const handleClick = (event: MouseEvent<HTMLElement>): void => {\n setAnchorEl(anchorEl ? null : event.currentTarget);\n };\n\n const handleClose = (): void => {\n setAnchorEl(null);\n };\n\n const open = Boolean(anchorEl);\n const id = open ? 'actions-menu' : undefined;\n\n return (\n <Box sx={{ background: (theme) => theme.palette.background.default }}>\n <HeaderIconButton\n className=\"show-actions\"\n aria-describedby={id}\n onClick={handleClick}\n aria-label={ARIA_LABEL_TEXT.showPanelActions(title)}\n size=\"small\"\n >\n {icon ?? <MenuIcon fontSize=\"inherit\" />}\n </HeaderIconButton>\n <Popper\n id={id}\n open={open}\n anchorEl={anchorEl}\n placement={placement}\n modifiers={[\n {\n name: 'offset',\n options: {\n offset: [offsetX, offsetY],\n },\n },\n ]}\n sx={{\n backgroundColor: (theme) => theme.palette.background.paper,\n borderRadius: 1,\n boxShadow: (theme) => theme.shadows[4],\n }}\n >\n <ClickAwayListener onClickAway={handleClose}>\n <Stack direction={direction} alignItems=\"center\" sx={{ padding: 1 }} onClick={handleClose}>\n {children}\n </Stack>\n </ClickAwayListener>\n </Popper>\n </Box>\n );\n};\n"],"names":["Stack","Box","CircularProgress","styled","Popper","ClickAwayListener","isValidElement","useMemo","useState","InfoTooltip","DatabaseSearch","ArrowCollapseIcon","ArrowExpandIcon","PencilIcon","DeleteIcon","DragIcon","ContentCopyIcon","MenuIcon","AlertIcon","AlertCircleIcon","InformationOutlineIcon","LightningBoltIcon","ARIA_LABEL_TEXT","HEADER_ACTIONS_CONTAINER_NAME","HEADER_MEDIUM_WIDTH","HEADER_SMALL_WIDTH","TOOLTIP_TEXT","LinksDisplay","HeaderIconButton","noticeTypeToIcon","error","color","warning","fontSize","info","ConditionalBox","display","alignItems","flexGrow","justifyContent","PanelActions","editHandlers","readHandlers","viewQueriesHandler","extra","title","description","descriptionTooltipId","links","queryResults","pluginActions","itemActions","showIcons","descriptionAction","trim","length","id","enterDelay","aria-label","size","aria-describedby","aria-hidden","sx","theme","palette","text","secondary","undefined","linksAction","variant","extraActions","queryStateIndicator","hasData","some","q","data","isFetching","queryErrors","filter","errorTexts","map","e","message","join","main","noticesIndicator","notices","flatMap","metadata","lastNotice","type","readActions","viewPanel","onClick","onViewPanelClick","isPanelViewed","viewQueryAction","queryView","openQueryView","editActions","editPanel","onEditPanelClick","duplicatePanel","onDuplicatePanelClick","transform","deletePanel","onDeletePanelClick","moveAction","background","default","movePanel","className","cursor","divider","OnHover","children","containerQueries","between","OverflowMenu","down","icon","direction","placement","offsetX","offsetY","anchorEl","setAnchorEl","hasContent","Array","isArray","handleClick","event","currentTarget","handleClose","open","Boolean","showPanelActions","modifiers","name","options","offset","backgroundColor","paper","borderRadius","boxShadow","shadows","onClickAway","padding"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { PanelProps, QueryData } from '@perses-dev/plugin-system';
2
- import { UnknownSpec, PanelDefinition } from '@perses-dev/core';
2
+ import { UnknownSpec, PanelDefinition } from '@perses-dev/spec';
3
3
  import { ReactElement } from 'react';
4
4
  export interface PanelContentProps extends Omit<PanelProps<UnknownSpec>, 'queryResults'> {
5
5
  panelPluginKind: string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/PanelContent.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 { usePlugin, PanelProps, QueryData, PanelPlugin } from '@perses-dev/plugin-system';\nimport { UnknownSpec, PanelDefinition, QueryDataType } from '@perses-dev/core';\nimport { ReactElement } from 'react';\nimport { LoadingOverlay } from '@perses-dev/components';\nimport { Skeleton } from '@mui/material';\nimport { PanelPluginLoader } from './PanelPluginLoader';\n\nexport interface PanelContentProps extends Omit<PanelProps<UnknownSpec>, 'queryResults'> {\n panelPluginKind: string;\n definition?: PanelDefinition<UnknownSpec>;\n queryResults: QueryData[];\n}\n\n/**\n * Based on the status of the queries (loading, error or data available), this component renders a\n * loading overlay, throws an error, or renders the panel content.\n */\nexport function PanelContent(props: PanelContentProps): ReactElement {\n const { panelPluginKind, definition, queryResults, spec, contentDimensions } = props;\n const { data: plugin, isLoading: isPanelLoading } = usePlugin('Panel', panelPluginKind, { useErrorBoundary: true });\n\n // Show fullsize skeleton if the panel plugin is loading.\n if (isPanelLoading) {\n return (\n <Skeleton\n variant=\"rectangular\"\n width={contentDimensions?.width}\n height={contentDimensions?.height}\n aria-label=\"Loading...\"\n />\n );\n }\n\n // Render the panel if any query has data, or the panel doesn't have a query attached (for example MarkdownPanel).\n // Loading indicator or errors of other queries are shown in the panel header.\n const queryResultsWithData = queryResults.flatMap((q) =>\n q.data ? [{ data: q.data, definition: q.definition }] : []\n );\n if (queryResultsWithData.length > 0 || queryResults.length === 0) {\n return (\n <PanelPluginLoader\n kind={panelPluginKind}\n spec={spec}\n contentDimensions={contentDimensions}\n definition={definition}\n queryResults={queryResultsWithData}\n />\n );\n }\n\n // No query has data, show loading overlay if any query is fetching data.\n if (queryResults.some((q) => q.isFetching)) {\n return <PanelLoading plugin={plugin} spec={spec} definition={definition} contentDimensions={contentDimensions} />;\n }\n\n // No query has data or is loading, show the error if any query has an error.\n // The error will be catched in <ErrorBoundary> of <Panel>.\n const queryError = queryResults.find((q) => q.error);\n if (queryError) {\n throw queryError.error;\n }\n\n // At this point, one or more queries are defined, but no query has data, is loading, or has an error.\n // This can happen if all queries are disabled (e.g. dependent dashboard variables are loading, or they are not in the viewport of the browser).\n // Most likely, some query will be enabled later. Render the panel loading skeleton.\n return <PanelLoading plugin={plugin} spec={spec} definition={definition} contentDimensions={contentDimensions} />;\n}\n\ninterface PanelLoadingProps extends Pick<PanelContentProps, 'spec' | 'definition' | 'contentDimensions'> {\n plugin?: PanelPlugin<UnknownSpec, PanelProps<UnknownSpec, QueryDataType>>;\n}\n\nfunction PanelLoading({ plugin, spec, definition, contentDimensions }: PanelLoadingProps): ReactElement {\n if (plugin?.LoadingComponent) {\n return (\n <plugin.LoadingComponent\n spec={spec}\n contentDimensions={contentDimensions}\n definition={definition}\n queryResults={[]}\n />\n );\n }\n return <LoadingOverlay />;\n}\n"],"names":["usePlugin","LoadingOverlay","Skeleton","PanelPluginLoader","PanelContent","props","panelPluginKind","definition","queryResults","spec","contentDimensions","data","plugin","isLoading","isPanelLoading","useErrorBoundary","variant","width","height","aria-label","queryResultsWithData","flatMap","q","length","kind","some","isFetching","PanelLoading","queryError","find","error","LoadingComponent"],"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,SAASA,SAAS,QAA4C,4BAA4B;AAG1F,SAASC,cAAc,QAAQ,yBAAyB;AACxD,SAASC,QAAQ,QAAQ,gBAAgB;AACzC,SAASC,iBAAiB,QAAQ,sBAAsB;AAQxD;;;CAGC,GACD,OAAO,SAASC,aAAaC,KAAwB;IACnD,MAAM,EAAEC,eAAe,EAAEC,UAAU,EAAEC,YAAY,EAAEC,IAAI,EAAEC,iBAAiB,EAAE,GAAGL;IAC/E,MAAM,EAAEM,MAAMC,MAAM,EAAEC,WAAWC,cAAc,EAAE,GAAGd,UAAU,SAASM,iBAAiB;QAAES,kBAAkB;IAAK;IAEjH,yDAAyD;IACzD,IAAID,gBAAgB;QAClB,qBACE,KAACZ;YACCc,SAAQ;YACRC,OAAOP,mBAAmBO;YAC1BC,QAAQR,mBAAmBQ;YAC3BC,cAAW;;IAGjB;IAEA,kHAAkH;IAClH,8EAA8E;IAC9E,MAAMC,uBAAuBZ,aAAaa,OAAO,CAAC,CAACC,IACjDA,EAAEX,IAAI,GAAG;YAAC;gBAAEA,MAAMW,EAAEX,IAAI;gBAAEJ,YAAYe,EAAEf,UAAU;YAAC;SAAE,GAAG,EAAE;IAE5D,IAAIa,qBAAqBG,MAAM,GAAG,KAAKf,aAAae,MAAM,KAAK,GAAG;QAChE,qBACE,KAACpB;YACCqB,MAAMlB;YACNG,MAAMA;YACNC,mBAAmBA;YACnBH,YAAYA;YACZC,cAAcY;;IAGpB;IAEA,yEAAyE;IACzE,IAAIZ,aAAaiB,IAAI,CAAC,CAACH,IAAMA,EAAEI,UAAU,GAAG;QAC1C,qBAAO,KAACC;YAAaf,QAAQA;YAAQH,MAAMA;YAAMF,YAAYA;YAAYG,mBAAmBA;;IAC9F;IAEA,6EAA6E;IAC7E,2DAA2D;IAC3D,MAAMkB,aAAapB,aAAaqB,IAAI,CAAC,CAACP,IAAMA,EAAEQ,KAAK;IACnD,IAAIF,YAAY;QACd,MAAMA,WAAWE,KAAK;IACxB;IAEA,sGAAsG;IACtG,gJAAgJ;IAChJ,oFAAoF;IACpF,qBAAO,KAACH;QAAaf,QAAQA;QAAQH,MAAMA;QAAMF,YAAYA;QAAYG,mBAAmBA;;AAC9F;AAMA,SAASiB,aAAa,EAAEf,MAAM,EAAEH,IAAI,EAAEF,UAAU,EAAEG,iBAAiB,EAAqB;IACtF,IAAIE,QAAQmB,kBAAkB;QAC5B,qBACE,KAACnB,OAAOmB,gBAAgB;YACtBtB,MAAMA;YACNC,mBAAmBA;YACnBH,YAAYA;YACZC,cAAc,EAAE;;IAGtB;IACA,qBAAO,KAACP;AACV"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelContent.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 { usePlugin, PanelProps, QueryData, PanelPlugin } from '@perses-dev/plugin-system';\nimport { UnknownSpec, PanelDefinition, QueryDataType } from '@perses-dev/spec';\nimport { ReactElement } from 'react';\nimport { LoadingOverlay } from '@perses-dev/components';\nimport { Skeleton } from '@mui/material';\nimport { PanelPluginLoader } from './PanelPluginLoader';\n\nexport interface PanelContentProps extends Omit<PanelProps<UnknownSpec>, 'queryResults'> {\n panelPluginKind: string;\n definition?: PanelDefinition<UnknownSpec>;\n queryResults: QueryData[];\n}\n\n/**\n * Based on the status of the queries (loading, error or data available), this component renders a\n * loading overlay, throws an error, or renders the panel content.\n */\nexport function PanelContent(props: PanelContentProps): ReactElement {\n const { panelPluginKind, definition, queryResults, spec, contentDimensions } = props;\n const { data: plugin, isLoading: isPanelLoading } = usePlugin('Panel', panelPluginKind, { useErrorBoundary: true });\n\n // Show fullsize skeleton if the panel plugin is loading.\n if (isPanelLoading) {\n return (\n <Skeleton\n variant=\"rectangular\"\n width={contentDimensions?.width}\n height={contentDimensions?.height}\n aria-label=\"Loading...\"\n />\n );\n }\n\n // Render the panel if any query has data, or the panel doesn't have a query attached (for example MarkdownPanel).\n // Loading indicator or errors of other queries are shown in the panel header.\n const queryResultsWithData = queryResults.flatMap((q) =>\n q.data ? [{ data: q.data, definition: q.definition }] : []\n );\n if (queryResultsWithData.length > 0 || queryResults.length === 0) {\n return (\n <PanelPluginLoader\n kind={panelPluginKind}\n spec={spec}\n contentDimensions={contentDimensions}\n definition={definition}\n queryResults={queryResultsWithData}\n />\n );\n }\n\n // No query has data, show loading overlay if any query is fetching data.\n if (queryResults.some((q) => q.isFetching)) {\n return <PanelLoading plugin={plugin} spec={spec} definition={definition} contentDimensions={contentDimensions} />;\n }\n\n // No query has data or is loading, show the error if any query has an error.\n // The error will be catched in <ErrorBoundary> of <Panel>.\n const queryError = queryResults.find((q) => q.error);\n if (queryError) {\n throw queryError.error;\n }\n\n // At this point, one or more queries are defined, but no query has data, is loading, or has an error.\n // This can happen if all queries are disabled (e.g. dependent dashboard variables are loading, or they are not in the viewport of the browser).\n // Most likely, some query will be enabled later. Render the panel loading skeleton.\n return <PanelLoading plugin={plugin} spec={spec} definition={definition} contentDimensions={contentDimensions} />;\n}\n\ninterface PanelLoadingProps extends Pick<PanelContentProps, 'spec' | 'definition' | 'contentDimensions'> {\n plugin?: PanelPlugin<UnknownSpec, PanelProps<UnknownSpec, QueryDataType>>;\n}\n\nfunction PanelLoading({ plugin, spec, definition, contentDimensions }: PanelLoadingProps): ReactElement {\n if (plugin?.LoadingComponent) {\n return (\n <plugin.LoadingComponent\n spec={spec}\n contentDimensions={contentDimensions}\n definition={definition}\n queryResults={[]}\n />\n );\n }\n return <LoadingOverlay />;\n}\n"],"names":["usePlugin","LoadingOverlay","Skeleton","PanelPluginLoader","PanelContent","props","panelPluginKind","definition","queryResults","spec","contentDimensions","data","plugin","isLoading","isPanelLoading","useErrorBoundary","variant","width","height","aria-label","queryResultsWithData","flatMap","q","length","kind","some","isFetching","PanelLoading","queryError","find","error","LoadingComponent"],"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,SAASA,SAAS,QAA4C,4BAA4B;AAG1F,SAASC,cAAc,QAAQ,yBAAyB;AACxD,SAASC,QAAQ,QAAQ,gBAAgB;AACzC,SAASC,iBAAiB,QAAQ,sBAAsB;AAQxD;;;CAGC,GACD,OAAO,SAASC,aAAaC,KAAwB;IACnD,MAAM,EAAEC,eAAe,EAAEC,UAAU,EAAEC,YAAY,EAAEC,IAAI,EAAEC,iBAAiB,EAAE,GAAGL;IAC/E,MAAM,EAAEM,MAAMC,MAAM,EAAEC,WAAWC,cAAc,EAAE,GAAGd,UAAU,SAASM,iBAAiB;QAAES,kBAAkB;IAAK;IAEjH,yDAAyD;IACzD,IAAID,gBAAgB;QAClB,qBACE,KAACZ;YACCc,SAAQ;YACRC,OAAOP,mBAAmBO;YAC1BC,QAAQR,mBAAmBQ;YAC3BC,cAAW;;IAGjB;IAEA,kHAAkH;IAClH,8EAA8E;IAC9E,MAAMC,uBAAuBZ,aAAaa,OAAO,CAAC,CAACC,IACjDA,EAAEX,IAAI,GAAG;YAAC;gBAAEA,MAAMW,EAAEX,IAAI;gBAAEJ,YAAYe,EAAEf,UAAU;YAAC;SAAE,GAAG,EAAE;IAE5D,IAAIa,qBAAqBG,MAAM,GAAG,KAAKf,aAAae,MAAM,KAAK,GAAG;QAChE,qBACE,KAACpB;YACCqB,MAAMlB;YACNG,MAAMA;YACNC,mBAAmBA;YACnBH,YAAYA;YACZC,cAAcY;;IAGpB;IAEA,yEAAyE;IACzE,IAAIZ,aAAaiB,IAAI,CAAC,CAACH,IAAMA,EAAEI,UAAU,GAAG;QAC1C,qBAAO,KAACC;YAAaf,QAAQA;YAAQH,MAAMA;YAAMF,YAAYA;YAAYG,mBAAmBA;;IAC9F;IAEA,6EAA6E;IAC7E,2DAA2D;IAC3D,MAAMkB,aAAapB,aAAaqB,IAAI,CAAC,CAACP,IAAMA,EAAEQ,KAAK;IACnD,IAAIF,YAAY;QACd,MAAMA,WAAWE,KAAK;IACxB;IAEA,sGAAsG;IACtG,gJAAgJ;IAChJ,oFAAoF;IACpF,qBAAO,KAACH;QAAaf,QAAQA;QAAQH,MAAMA;QAAMF,YAAYA;QAAYG,mBAAmBA;;AAC9F;AAMA,SAASiB,aAAa,EAAEf,MAAM,EAAEH,IAAI,EAAEF,UAAU,EAAEG,iBAAiB,EAAqB;IACtF,IAAIE,QAAQmB,kBAAkB;QAC5B,qBACE,KAACnB,OAAOmB,gBAAgB;YACtBtB,MAAMA;YACNC,mBAAmBA;YACnBH,YAAYA;YACZC,cAAc,EAAE;;IAGtB;IACA,qBAAO,KAACP;AACV"}
@@ -1,5 +1,5 @@
1
1
  import { CardHeaderProps } from '@mui/material';
2
- import { Link } from '@perses-dev/core';
2
+ import { Link } from '@perses-dev/spec';
3
3
  import { ItemAction, QueryData } from '@perses-dev/plugin-system';
4
4
  import { ReactElement, ReactNode } from 'react';
5
5
  import { PanelActionsProps } from './PanelActions';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/PanelHeader.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 { CardHeader, CardHeaderProps, Stack, Typography, Tooltip } from '@mui/material';\nimport { combineSx } from '@perses-dev/components';\nimport { Link } from '@perses-dev/core';\nimport { ItemAction, QueryData, useAllVariableValues, useReplaceVariablesInString } from '@perses-dev/plugin-system';\nimport { ReactElement, ReactNode, useRef } from 'react';\nimport { HEADER_ACTIONS_CONTAINER_NAME } from '../../constants';\nimport { PanelActions, PanelActionsProps } from './PanelActions';\nimport { PanelOptions } from './Panel';\nimport { useSelectionItemActions } from './useSelectionItemActions';\n\ntype OmittedProps = 'children' | 'action' | 'title' | 'disableTypography';\n\nexport interface PanelHeaderProps extends Omit<CardHeaderProps, OmittedProps> {\n id: string;\n title?: string;\n description?: string;\n links?: Link[];\n extra?: ReactNode;\n queryResults: QueryData[];\n viewQueriesHandler?: PanelActionsProps['viewQueriesHandler'];\n readHandlers?: PanelActionsProps['readHandlers'];\n editHandlers?: PanelActionsProps['editHandlers'];\n pluginActions?: ReactNode[];\n itemActionsListConfig?: ItemAction[];\n showIcons: PanelOptions['showIcons'];\n dimension?: { width: number };\n}\n\nexport function PanelHeader({\n id,\n title: rawTitle,\n description: rawDescription,\n links,\n queryResults,\n readHandlers,\n editHandlers,\n sx,\n extra,\n pluginActions,\n itemActionsListConfig,\n showIcons,\n viewQueriesHandler,\n dimension,\n ...rest\n}: PanelHeaderProps): ReactElement {\n const titleElementId = `${id}-title`;\n const descriptionTooltipId = `${id}-description`;\n\n const title = useReplaceVariablesInString(rawTitle);\n const description = useReplaceVariablesInString(rawDescription);\n const variableState = useAllVariableValues();\n\n const textRef = useRef<HTMLDivElement>(null);\n\n const isEllipsisActive =\n textRef.current && dimension?.width ? textRef.current.scrollWidth > textRef.current.clientWidth : false;\n\n const { actionButtons, confirmDialog } = useSelectionItemActions({\n actions: itemActionsListConfig,\n variableState,\n disabledWithEmptySelection: true,\n });\n\n return (\n <>\n {title ? (\n <CardHeader\n id={id}\n component=\"header\"\n aria-labelledby={titleElementId}\n aria-describedby={descriptionTooltipId}\n disableTypography\n title={\n <Stack direction=\"row\" alignItems=\"center\" height=\"var(--panel-header-height, 30px)\">\n <Tooltip title={title} disableHoverListener={!isEllipsisActive}>\n <Typography\n id={titleElementId}\n variant=\"subtitle1\"\n ref={textRef}\n sx={{\n // `minHeight` guarantees that the header has the correct height\n // when there is no title (i.e. in the preview)\n lineHeight: '24px',\n minHeight: '26px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {title}\n </Typography>\n </Tooltip>\n <PanelActions\n title={title}\n description={description}\n descriptionTooltipId={descriptionTooltipId}\n links={links}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n viewQueriesHandler={viewQueriesHandler}\n extra={extra}\n queryResults={queryResults}\n pluginActions={pluginActions}\n itemActions={actionButtons}\n showIcons={showIcons}\n />\n </Stack>\n }\n sx={combineSx(\n (theme) => ({\n containerType: 'inline-size',\n containerName: HEADER_ACTIONS_CONTAINER_NAME,\n padding: theme.spacing(1),\n borderBottom: `solid 1px ${theme.palette.divider}`,\n '.MuiCardHeader-content': {\n overflow: 'hidden',\n },\n }),\n sx\n )}\n {...rest}\n />\n ) : (\n <Stack\n id={id}\n component=\"header\"\n aria-describedby={descriptionTooltipId}\n sx={combineSx(\n {\n position: 'absolute',\n right: 0,\n top: 0,\n zIndex: 5,\n containerType: 'inline-size',\n containerName: HEADER_ACTIONS_CONTAINER_NAME,\n },\n sx\n )}\n {...rest}\n >\n <PanelActions\n title={title}\n description={description}\n descriptionTooltipId={descriptionTooltipId}\n links={links}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n viewQueriesHandler={viewQueriesHandler}\n extra={extra}\n queryResults={queryResults}\n pluginActions={pluginActions}\n itemActions={actionButtons}\n showIcons={showIcons}\n />\n </Stack>\n )}\n {confirmDialog}\n </>\n );\n}\n"],"names":["CardHeader","Stack","Typography","Tooltip","combineSx","useAllVariableValues","useReplaceVariablesInString","useRef","HEADER_ACTIONS_CONTAINER_NAME","PanelActions","useSelectionItemActions","PanelHeader","id","title","rawTitle","description","rawDescription","links","queryResults","readHandlers","editHandlers","sx","extra","pluginActions","itemActionsListConfig","showIcons","viewQueriesHandler","dimension","rest","titleElementId","descriptionTooltipId","variableState","textRef","isEllipsisActive","current","width","scrollWidth","clientWidth","actionButtons","confirmDialog","actions","disabledWithEmptySelection","component","aria-labelledby","aria-describedby","disableTypography","direction","alignItems","height","disableHoverListener","variant","ref","lineHeight","minHeight","whiteSpace","overflow","textOverflow","itemActions","theme","containerType","containerName","padding","spacing","borderBottom","palette","divider","position","right","top","zIndex"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelHeader.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 { CardHeader, CardHeaderProps, Stack, Typography, Tooltip } from '@mui/material';\nimport { combineSx } from '@perses-dev/components';\nimport { Link } from '@perses-dev/spec';\nimport { ItemAction, QueryData, useAllVariableValues, useReplaceVariablesInString } from '@perses-dev/plugin-system';\nimport { ReactElement, ReactNode, useRef } from 'react';\nimport { HEADER_ACTIONS_CONTAINER_NAME } from '../../constants';\nimport { PanelActions, PanelActionsProps } from './PanelActions';\nimport { PanelOptions } from './Panel';\nimport { useSelectionItemActions } from './useSelectionItemActions';\n\ntype OmittedProps = 'children' | 'action' | 'title' | 'disableTypography';\n\nexport interface PanelHeaderProps extends Omit<CardHeaderProps, OmittedProps> {\n id: string;\n title?: string;\n description?: string;\n links?: Link[];\n extra?: ReactNode;\n queryResults: QueryData[];\n viewQueriesHandler?: PanelActionsProps['viewQueriesHandler'];\n readHandlers?: PanelActionsProps['readHandlers'];\n editHandlers?: PanelActionsProps['editHandlers'];\n pluginActions?: ReactNode[];\n itemActionsListConfig?: ItemAction[];\n showIcons: PanelOptions['showIcons'];\n dimension?: { width: number };\n}\n\nexport function PanelHeader({\n id,\n title: rawTitle,\n description: rawDescription,\n links,\n queryResults,\n readHandlers,\n editHandlers,\n sx,\n extra,\n pluginActions,\n itemActionsListConfig,\n showIcons,\n viewQueriesHandler,\n dimension,\n ...rest\n}: PanelHeaderProps): ReactElement {\n const titleElementId = `${id}-title`;\n const descriptionTooltipId = `${id}-description`;\n\n const title = useReplaceVariablesInString(rawTitle);\n const description = useReplaceVariablesInString(rawDescription);\n const variableState = useAllVariableValues();\n\n const textRef = useRef<HTMLDivElement>(null);\n\n const isEllipsisActive =\n textRef.current && dimension?.width ? textRef.current.scrollWidth > textRef.current.clientWidth : false;\n\n const { actionButtons, confirmDialog } = useSelectionItemActions({\n actions: itemActionsListConfig,\n variableState,\n disabledWithEmptySelection: true,\n });\n\n return (\n <>\n {title ? (\n <CardHeader\n id={id}\n component=\"header\"\n aria-labelledby={titleElementId}\n aria-describedby={descriptionTooltipId}\n disableTypography\n title={\n <Stack direction=\"row\" alignItems=\"center\" height=\"var(--panel-header-height, 30px)\">\n <Tooltip title={title} disableHoverListener={!isEllipsisActive}>\n <Typography\n id={titleElementId}\n variant=\"subtitle1\"\n ref={textRef}\n sx={{\n // `minHeight` guarantees that the header has the correct height\n // when there is no title (i.e. in the preview)\n lineHeight: '24px',\n minHeight: '26px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {title}\n </Typography>\n </Tooltip>\n <PanelActions\n title={title}\n description={description}\n descriptionTooltipId={descriptionTooltipId}\n links={links}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n viewQueriesHandler={viewQueriesHandler}\n extra={extra}\n queryResults={queryResults}\n pluginActions={pluginActions}\n itemActions={actionButtons}\n showIcons={showIcons}\n />\n </Stack>\n }\n sx={combineSx(\n (theme) => ({\n containerType: 'inline-size',\n containerName: HEADER_ACTIONS_CONTAINER_NAME,\n padding: theme.spacing(1),\n borderBottom: `solid 1px ${theme.palette.divider}`,\n '.MuiCardHeader-content': {\n overflow: 'hidden',\n },\n }),\n sx\n )}\n {...rest}\n />\n ) : (\n <Stack\n id={id}\n component=\"header\"\n aria-describedby={descriptionTooltipId}\n sx={combineSx(\n {\n position: 'absolute',\n right: 0,\n top: 0,\n zIndex: 5,\n containerType: 'inline-size',\n containerName: HEADER_ACTIONS_CONTAINER_NAME,\n },\n sx\n )}\n {...rest}\n >\n <PanelActions\n title={title}\n description={description}\n descriptionTooltipId={descriptionTooltipId}\n links={links}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n viewQueriesHandler={viewQueriesHandler}\n extra={extra}\n queryResults={queryResults}\n pluginActions={pluginActions}\n itemActions={actionButtons}\n showIcons={showIcons}\n />\n </Stack>\n )}\n {confirmDialog}\n </>\n );\n}\n"],"names":["CardHeader","Stack","Typography","Tooltip","combineSx","useAllVariableValues","useReplaceVariablesInString","useRef","HEADER_ACTIONS_CONTAINER_NAME","PanelActions","useSelectionItemActions","PanelHeader","id","title","rawTitle","description","rawDescription","links","queryResults","readHandlers","editHandlers","sx","extra","pluginActions","itemActionsListConfig","showIcons","viewQueriesHandler","dimension","rest","titleElementId","descriptionTooltipId","variableState","textRef","isEllipsisActive","current","width","scrollWidth","clientWidth","actionButtons","confirmDialog","actions","disabledWithEmptySelection","component","aria-labelledby","aria-describedby","disableTypography","direction","alignItems","height","disableHoverListener","variant","ref","lineHeight","minHeight","whiteSpace","overflow","textOverflow","itemActions","theme","containerType","containerName","padding","spacing","borderBottom","palette","divider","position","right","top","zIndex"],"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,SAASA,UAAU,EAAmBC,KAAK,EAAEC,UAAU,EAAEC,OAAO,QAAQ,gBAAgB;AACxF,SAASC,SAAS,QAAQ,yBAAyB;AAEnD,SAAgCC,oBAAoB,EAAEC,2BAA2B,QAAQ,4BAA4B;AACrH,SAAkCC,MAAM,QAAQ,QAAQ;AACxD,SAASC,6BAA6B,QAAQ,kBAAkB;AAChE,SAASC,YAAY,QAA2B,iBAAiB;AAEjE,SAASC,uBAAuB,QAAQ,4BAA4B;AAoBpE,OAAO,SAASC,YAAY,EAC1BC,EAAE,EACFC,OAAOC,QAAQ,EACfC,aAAaC,cAAc,EAC3BC,KAAK,EACLC,YAAY,EACZC,YAAY,EACZC,YAAY,EACZC,EAAE,EACFC,KAAK,EACLC,aAAa,EACbC,qBAAqB,EACrBC,SAAS,EACTC,kBAAkB,EAClBC,SAAS,EACT,GAAGC,MACc;IACjB,MAAMC,iBAAiB,GAAGjB,GAAG,MAAM,CAAC;IACpC,MAAMkB,uBAAuB,GAAGlB,GAAG,YAAY,CAAC;IAEhD,MAAMC,QAAQP,4BAA4BQ;IAC1C,MAAMC,cAAcT,4BAA4BU;IAChD,MAAMe,gBAAgB1B;IAEtB,MAAM2B,UAAUzB,OAAuB;IAEvC,MAAM0B,mBACJD,QAAQE,OAAO,IAAIP,WAAWQ,QAAQH,QAAQE,OAAO,CAACE,WAAW,GAAGJ,QAAQE,OAAO,CAACG,WAAW,GAAG;IAEpG,MAAM,EAAEC,aAAa,EAAEC,aAAa,EAAE,GAAG7B,wBAAwB;QAC/D8B,SAAShB;QACTO;QACAU,4BAA4B;IAC9B;IAEA,qBACE;;YACG5B,sBACC,KAACb;gBACCY,IAAIA;gBACJ8B,WAAU;gBACVC,mBAAiBd;gBACjBe,oBAAkBd;gBAClBe,iBAAiB;gBACjBhC,qBACE,MAACZ;oBAAM6C,WAAU;oBAAMC,YAAW;oBAASC,QAAO;;sCAChD,KAAC7C;4BAAQU,OAAOA;4BAAOoC,sBAAsB,CAAChB;sCAC5C,cAAA,KAAC/B;gCACCU,IAAIiB;gCACJqB,SAAQ;gCACRC,KAAKnB;gCACLX,IAAI;oCACF,gEAAgE;oCAChE,+CAA+C;oCAC/C+B,YAAY;oCACZC,WAAW;oCACXC,YAAY;oCACZC,UAAU;oCACVC,cAAc;gCAChB;0CAEC3C;;;sCAGL,KAACJ;4BACCI,OAAOA;4BACPE,aAAaA;4BACbe,sBAAsBA;4BACtBb,OAAOA;4BACPE,cAAcA;4BACdC,cAAcA;4BACdM,oBAAoBA;4BACpBJ,OAAOA;4BACPJ,cAAcA;4BACdK,eAAeA;4BACfkC,aAAanB;4BACbb,WAAWA;;;;gBAIjBJ,IAAIjB,UACF,CAACsD,QAAW,CAAA;wBACVC,eAAe;wBACfC,eAAepD;wBACfqD,SAASH,MAAMI,OAAO,CAAC;wBACvBC,cAAc,CAAC,UAAU,EAAEL,MAAMM,OAAO,CAACC,OAAO,EAAE;wBAClD,0BAA0B;4BACxBV,UAAU;wBACZ;oBACF,CAAA,GACAlC;gBAED,GAAGO,IAAI;+BAGV,KAAC3B;gBACCW,IAAIA;gBACJ8B,WAAU;gBACVE,oBAAkBd;gBAClBT,IAAIjB,UACF;oBACE8D,UAAU;oBACVC,OAAO;oBACPC,KAAK;oBACLC,QAAQ;oBACRV,eAAe;oBACfC,eAAepD;gBACjB,GACAa;gBAED,GAAGO,IAAI;0BAER,cAAA,KAACnB;oBACCI,OAAOA;oBACPE,aAAaA;oBACbe,sBAAsBA;oBACtBb,OAAOA;oBACPE,cAAcA;oBACdC,cAAcA;oBACdM,oBAAoBA;oBACpBJ,OAAOA;oBACPJ,cAAcA;oBACdK,eAAeA;oBACfkC,aAAanB;oBACbb,WAAWA;;;YAIhBc;;;AAGP"}
@@ -1,5 +1,5 @@
1
1
  import { PanelProps } from '@perses-dev/plugin-system';
2
- import { UnknownSpec, QueryDataType } from '@perses-dev/core';
2
+ import { UnknownSpec, QueryDataType } from '@perses-dev/spec';
3
3
  import { ReactElement } from 'react';
4
4
  interface PanelPluginProps extends PanelProps<UnknownSpec, QueryDataType> {
5
5
  kind: string;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/PanelPluginLoader.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 { usePlugin, PanelProps } from '@perses-dev/plugin-system';\nimport { UnknownSpec, QueryDataType } from '@perses-dev/core';\nimport { ReactElement } from 'react';\nimport { Skeleton } from '@mui/material';\n\ninterface PanelPluginProps extends PanelProps<UnknownSpec, QueryDataType> {\n kind: string;\n}\n\n/**\n * PanelPluginLoader loads the panel plugin specified by the 'kind' prop from the plugin registry and\n * renders its PanelComponent.\n */\nexport function PanelPluginLoader(props: PanelPluginProps): ReactElement {\n const { kind, spec, contentDimensions, definition, queryResults } = props;\n const { data: plugin, isLoading: isPanelLoading } = usePlugin('Panel', kind, { useErrorBoundary: true });\n const PanelComponent = plugin?.PanelComponent;\n const supportedQueryTypes = plugin?.supportedQueryTypes || [];\n // Clear out the queryResults parameter for plugins which don't support any query types\n const supportedQueryResults = supportedQueryTypes.length > 0 ? queryResults : [];\n\n // Show fullsize skeleton if the panel plugin is loading.\n if (isPanelLoading) {\n return (\n <Skeleton\n variant=\"rectangular\"\n width={contentDimensions?.width}\n height={contentDimensions?.height}\n aria-label=\"Loading...\"\n />\n );\n }\n\n if (PanelComponent === undefined) {\n throw new Error(`Missing PanelComponent from panel plugin for kind '${kind}'`);\n }\n\n for (const queryResult of supportedQueryResults) {\n if (!supportedQueryTypes.includes(queryResult.definition.kind)) {\n throw new Error(\n `This panel does not support queries of type '${queryResult.definition.kind}'. Supported query types: ${supportedQueryTypes.join(', ')}.`\n );\n }\n }\n\n return (\n <PanelComponent\n spec={spec}\n contentDimensions={contentDimensions}\n definition={definition}\n queryResults={supportedQueryResults}\n />\n );\n}\n"],"names":["usePlugin","Skeleton","PanelPluginLoader","props","kind","spec","contentDimensions","definition","queryResults","data","plugin","isLoading","isPanelLoading","useErrorBoundary","PanelComponent","supportedQueryTypes","supportedQueryResults","length","variant","width","height","aria-label","undefined","Error","queryResult","includes","join"],"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,SAASA,SAAS,QAAoB,4BAA4B;AAGlE,SAASC,QAAQ,QAAQ,gBAAgB;AAMzC;;;CAGC,GACD,OAAO,SAASC,kBAAkBC,KAAuB;IACvD,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAEC,iBAAiB,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGL;IACpE,MAAM,EAAEM,MAAMC,MAAM,EAAEC,WAAWC,cAAc,EAAE,GAAGZ,UAAU,SAASI,MAAM;QAAES,kBAAkB;IAAK;IACtG,MAAMC,iBAAiBJ,QAAQI;IAC/B,MAAMC,sBAAsBL,QAAQK,uBAAuB,EAAE;IAC7D,uFAAuF;IACvF,MAAMC,wBAAwBD,oBAAoBE,MAAM,GAAG,IAAIT,eAAe,EAAE;IAEhF,yDAAyD;IACzD,IAAII,gBAAgB;QAClB,qBACE,KAACX;YACCiB,SAAQ;YACRC,OAAOb,mBAAmBa;YAC1BC,QAAQd,mBAAmBc;YAC3BC,cAAW;;IAGjB;IAEA,IAAIP,mBAAmBQ,WAAW;QAChC,MAAM,IAAIC,MAAM,CAAC,mDAAmD,EAAEnB,KAAK,CAAC,CAAC;IAC/E;IAEA,KAAK,MAAMoB,eAAeR,sBAAuB;QAC/C,IAAI,CAACD,oBAAoBU,QAAQ,CAACD,YAAYjB,UAAU,CAACH,IAAI,GAAG;YAC9D,MAAM,IAAImB,MACR,CAAC,6CAA6C,EAAEC,YAAYjB,UAAU,CAACH,IAAI,CAAC,0BAA0B,EAAEW,oBAAoBW,IAAI,CAAC,MAAM,CAAC,CAAC;QAE7I;IACF;IAEA,qBACE,KAACZ;QACCT,MAAMA;QACNC,mBAAmBA;QACnBC,YAAYA;QACZC,cAAcQ;;AAGpB"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelPluginLoader.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 { usePlugin, PanelProps } from '@perses-dev/plugin-system';\nimport { UnknownSpec, QueryDataType } from '@perses-dev/spec';\nimport { ReactElement } from 'react';\nimport { Skeleton } from '@mui/material';\n\ninterface PanelPluginProps extends PanelProps<UnknownSpec, QueryDataType> {\n kind: string;\n}\n\n/**\n * PanelPluginLoader loads the panel plugin specified by the 'kind' prop from the plugin registry and\n * renders its PanelComponent.\n */\nexport function PanelPluginLoader(props: PanelPluginProps): ReactElement {\n const { kind, spec, contentDimensions, definition, queryResults } = props;\n const { data: plugin, isLoading: isPanelLoading } = usePlugin('Panel', kind, { useErrorBoundary: true });\n const PanelComponent = plugin?.PanelComponent;\n const supportedQueryTypes = plugin?.supportedQueryTypes || [];\n // Clear out the queryResults parameter for plugins which don't support any query types\n const supportedQueryResults = supportedQueryTypes.length > 0 ? queryResults : [];\n\n // Show fullsize skeleton if the panel plugin is loading.\n if (isPanelLoading) {\n return (\n <Skeleton\n variant=\"rectangular\"\n width={contentDimensions?.width}\n height={contentDimensions?.height}\n aria-label=\"Loading...\"\n />\n );\n }\n\n if (PanelComponent === undefined) {\n throw new Error(`Missing PanelComponent from panel plugin for kind '${kind}'`);\n }\n\n for (const queryResult of supportedQueryResults) {\n if (!supportedQueryTypes.includes(queryResult.definition.kind)) {\n throw new Error(\n `This panel does not support queries of type '${queryResult.definition.kind}'. Supported query types: ${supportedQueryTypes.join(', ')}.`\n );\n }\n }\n\n return (\n <PanelComponent\n spec={spec}\n contentDimensions={contentDimensions}\n definition={definition}\n queryResults={supportedQueryResults}\n />\n );\n}\n"],"names":["usePlugin","Skeleton","PanelPluginLoader","props","kind","spec","contentDimensions","definition","queryResults","data","plugin","isLoading","isPanelLoading","useErrorBoundary","PanelComponent","supportedQueryTypes","supportedQueryResults","length","variant","width","height","aria-label","undefined","Error","queryResult","includes","join"],"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,SAASA,SAAS,QAAoB,4BAA4B;AAGlE,SAASC,QAAQ,QAAQ,gBAAgB;AAMzC;;;CAGC,GACD,OAAO,SAASC,kBAAkBC,KAAuB;IACvD,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAEC,iBAAiB,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGL;IACpE,MAAM,EAAEM,MAAMC,MAAM,EAAEC,WAAWC,cAAc,EAAE,GAAGZ,UAAU,SAASI,MAAM;QAAES,kBAAkB;IAAK;IACtG,MAAMC,iBAAiBJ,QAAQI;IAC/B,MAAMC,sBAAsBL,QAAQK,uBAAuB,EAAE;IAC7D,uFAAuF;IACvF,MAAMC,wBAAwBD,oBAAoBE,MAAM,GAAG,IAAIT,eAAe,EAAE;IAEhF,yDAAyD;IACzD,IAAII,gBAAgB;QAClB,qBACE,KAACX;YACCiB,SAAQ;YACRC,OAAOb,mBAAmBa;YAC1BC,QAAQd,mBAAmBc;YAC3BC,cAAW;;IAGjB;IAEA,IAAIP,mBAAmBQ,WAAW;QAChC,MAAM,IAAIC,MAAM,CAAC,mDAAmD,EAAEnB,KAAK,CAAC,CAAC;IAC/E;IAEA,KAAK,MAAMoB,eAAeR,sBAAuB;QAC/C,IAAI,CAACD,oBAAoBU,QAAQ,CAACD,YAAYjB,UAAU,CAACH,IAAI,GAAG;YAC9D,MAAM,IAAImB,MACR,CAAC,6CAA6C,EAAEC,YAAYjB,UAAU,CAACH,IAAI,CAAC,0BAA0B,EAAEW,oBAAoBW,IAAI,CAAC,MAAM,CAAC,CAAC;QAE7I;IACF;IAEA,qBACE,KAACZ;QACCT,MAAMA;QACNC,mBAAmBA;QACnBC,YAAYA;QACZC,cAAcQ;;AAGpB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/PanelDrawer/PanelDrawer.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\n/* eslint-disable @typescript-eslint/no-empty-function */\n// 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 { ReactElement, useState, useMemo, ReactNode, useCallback } from 'react';\nimport { Drawer, ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { PanelEditorValues } from '@perses-dev/core';\nimport { useVariableValues, VariableContext } from '@perses-dev/plugin-system';\nimport { usePanelEditor, usePanelKey } from '../../context';\nimport { PanelEditorForm } from './PanelEditorForm';\n\n/**\n * The Add/Edit panel drawer for editing a panel's options.\n */\nexport const PanelDrawer = (): ReactElement => {\n const panelEditor = usePanelEditor();\n const panelKey = usePanelKey(panelEditor?.panelGroupItemId);\n\n // When the user clicks close, start closing but don't call the store yet to keep values stable during animtation\n const [isClosing, setIsClosing] = useState(false);\n\n // Drawer is open if we have a model and we're not transitioning out\n const isOpen = panelEditor !== undefined && !isClosing;\n\n const handleSave = useCallback(\n (values: PanelEditorValues) => {\n // This shouldn't happen since we don't render the submit button until we have a model, but check to make TS happy\n if (panelEditor === undefined || values === undefined) {\n throw new Error('Cannot apply changes');\n }\n panelEditor.applyChanges(values);\n setIsClosing(true);\n },\n [panelEditor]\n );\n\n const handleClose = (): void => {\n setIsClosing(true);\n };\n\n // Don't call closeDrawer on the store until the Drawer has completely transitioned out and reset close state\n const handleExited = useCallback(() => {\n panelEditor?.close();\n setIsClosing(false);\n }, [panelEditor]);\n\n // Disables closing on click out. This is a quick-win solution to avoid losing draft changes.\n // -> TODO find a way to enable closing by clicking-out in edit view, with a discard confirmation modal popping up\n const handleClickOut = (): void => {\n /* do nothing */\n };\n\n const drawer = useMemo(() => {\n return (\n <Drawer\n isOpen={isOpen}\n onClose={handleClickOut}\n slotProps={{ transition: { onExited: handleExited } }}\n data-testid=\"panel-editor\"\n >\n {/* When the drawer is opened, we should have panel editor state (this also ensures the form state gets reset between opens) */}\n {panelEditor && (\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelEditorForm\n panelKey={panelKey}\n initialAction={panelEditor.mode}\n initialValues={panelEditor.initialValues}\n onSave={handleSave}\n onClose={handleClose}\n />\n </ErrorBoundary>\n )}\n </Drawer>\n );\n }, [handleExited, handleSave, isOpen, panelEditor, panelKey]);\n\n // If the panel editor is using a repeat variable, we need to wrap the drawer in a VariableContext.Provider\n if (panelEditor?.panelGroupItemId?.repeatVariable) {\n return (\n <RepeatVariableWrapper repeatVariable={panelEditor.panelGroupItemId.repeatVariable}>\n {drawer}\n </RepeatVariableWrapper>\n );\n }\n\n return drawer;\n};\n\n// Wraps the drawer in a VariableContext.Provider to provide the repeat variable value\n// This is necessary for previewing panels that use repeat variables and query editor\nfunction RepeatVariableWrapper({\n repeatVariable,\n children,\n}: {\n repeatVariable: [string, string];\n children: ReactNode;\n}): ReactElement {\n const variables = useVariableValues();\n\n return (\n <VariableContext.Provider\n value={{ state: { ...variables, [repeatVariable[0]]: { value: repeatVariable[1], loading: false } } }}\n >\n {children}\n </VariableContext.Provider>\n );\n}\n"],"names":["useState","useMemo","useCallback","Drawer","ErrorAlert","ErrorBoundary","useVariableValues","VariableContext","usePanelEditor","usePanelKey","PanelEditorForm","PanelDrawer","panelEditor","panelKey","panelGroupItemId","isClosing","setIsClosing","isOpen","undefined","handleSave","values","Error","applyChanges","handleClose","handleExited","close","handleClickOut","drawer","onClose","slotProps","transition","onExited","data-testid","FallbackComponent","initialAction","mode","initialValues","onSave","repeatVariable","RepeatVariableWrapper","children","variables","Provider","value","state","loading"],"mappings":"AAAA,+BAA+B;AAC/B,oEAAoE;AACpE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,sEAAsE;AACtE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,uDAAuD,GACvD,+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,SAAuBA,QAAQ,EAAEC,OAAO,EAAaC,WAAW,QAAQ,QAAQ;AAChF,SAASC,MAAM,EAAEC,UAAU,EAAEC,aAAa,QAAQ,yBAAyB;AAE3E,SAASC,iBAAiB,EAAEC,eAAe,QAAQ,4BAA4B;AAC/E,SAASC,cAAc,EAAEC,WAAW,QAAQ,gBAAgB;AAC5D,SAASC,eAAe,QAAQ,oBAAoB;AAEpD;;CAEC,GACD,OAAO,MAAMC,cAAc;IACzB,MAAMC,cAAcJ;IACpB,MAAMK,WAAWJ,YAAYG,aAAaE;IAE1C,iHAAiH;IACjH,MAAM,CAACC,WAAWC,aAAa,GAAGhB,SAAS;IAE3C,oEAAoE;IACpE,MAAMiB,SAASL,gBAAgBM,aAAa,CAACH;IAE7C,MAAMI,aAAajB,YACjB,CAACkB;QACC,kHAAkH;QAClH,IAAIR,gBAAgBM,aAAaE,WAAWF,WAAW;YACrD,MAAM,IAAIG,MAAM;QAClB;QACAT,YAAYU,YAAY,CAACF;QACzBJ,aAAa;IACf,GACA;QAACJ;KAAY;IAGf,MAAMW,cAAc;QAClBP,aAAa;IACf;IAEA,6GAA6G;IAC7G,MAAMQ,eAAetB,YAAY;QAC/BU,aAAaa;QACbT,aAAa;IACf,GAAG;QAACJ;KAAY;IAEhB,6FAA6F;IAC7F,kHAAkH;IAClH,MAAMc,iBAAiB;IACrB,cAAc,GAChB;IAEA,MAAMC,SAAS1B,QAAQ;QACrB,qBACE,KAACE;YACCc,QAAQA;YACRW,SAASF;YACTG,WAAW;gBAAEC,YAAY;oBAAEC,UAAUP;gBAAa;YAAE;YACpDQ,eAAY;sBAGXpB,6BACC,KAACP;gBAAc4B,mBAAmB7B;0BAChC,cAAA,KAACM;oBACCG,UAAUA;oBACVqB,eAAetB,YAAYuB,IAAI;oBAC/BC,eAAexB,YAAYwB,aAAa;oBACxCC,QAAQlB;oBACRS,SAASL;;;;IAMrB,GAAG;QAACC;QAAcL;QAAYF;QAAQL;QAAaC;KAAS;IAE5D,2GAA2G;IAC3G,IAAID,aAAaE,kBAAkBwB,gBAAgB;QACjD,qBACE,KAACC;YAAsBD,gBAAgB1B,YAAYE,gBAAgB,CAACwB,cAAc;sBAC/EX;;IAGP;IAEA,OAAOA;AACT,EAAE;AAEF,sFAAsF;AACtF,qFAAqF;AACrF,SAASY,sBAAsB,EAC7BD,cAAc,EACdE,QAAQ,EAIT;IACC,MAAMC,YAAYnC;IAElB,qBACE,KAACC,gBAAgBmC,QAAQ;QACvBC,OAAO;YAAEC,OAAO;gBAAE,GAAGH,SAAS;gBAAE,CAACH,cAAc,CAAC,EAAE,CAAC,EAAE;oBAAEK,OAAOL,cAAc,CAAC,EAAE;oBAAEO,SAAS;gBAAM;YAAE;QAAE;kBAEnGL;;AAGP"}
1
+ {"version":3,"sources":["../../../src/components/PanelDrawer/PanelDrawer.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\n/* eslint-disable @typescript-eslint/no-empty-function */\n// 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 { ReactElement, useState, useMemo, ReactNode, useCallback } from 'react';\nimport { Drawer, ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { PanelEditorValues } from '@perses-dev/spec';\nimport { useVariableValues, VariableContext } from '@perses-dev/plugin-system';\nimport { usePanelEditor, usePanelKey } from '../../context';\nimport { PanelEditorForm } from './PanelEditorForm';\n\n/**\n * The Add/Edit panel drawer for editing a panel's options.\n */\nexport const PanelDrawer = (): ReactElement => {\n const panelEditor = usePanelEditor();\n const panelKey = usePanelKey(panelEditor?.panelGroupItemId);\n\n // When the user clicks close, start closing but don't call the store yet to keep values stable during animtation\n const [isClosing, setIsClosing] = useState(false);\n\n // Drawer is open if we have a model and we're not transitioning out\n const isOpen = panelEditor !== undefined && !isClosing;\n\n const handleSave = useCallback(\n (values: PanelEditorValues) => {\n // This shouldn't happen since we don't render the submit button until we have a model, but check to make TS happy\n if (panelEditor === undefined || values === undefined) {\n throw new Error('Cannot apply changes');\n }\n panelEditor.applyChanges(values);\n setIsClosing(true);\n },\n [panelEditor]\n );\n\n const handleClose = (): void => {\n setIsClosing(true);\n };\n\n // Don't call closeDrawer on the store until the Drawer has completely transitioned out and reset close state\n const handleExited = useCallback(() => {\n panelEditor?.close();\n setIsClosing(false);\n }, [panelEditor]);\n\n // Disables closing on click out. This is a quick-win solution to avoid losing draft changes.\n // -> TODO find a way to enable closing by clicking-out in edit view, with a discard confirmation modal popping up\n const handleClickOut = (): void => {\n /* do nothing */\n };\n\n const drawer = useMemo(() => {\n return (\n <Drawer\n isOpen={isOpen}\n onClose={handleClickOut}\n slotProps={{ transition: { onExited: handleExited } }}\n data-testid=\"panel-editor\"\n >\n {/* When the drawer is opened, we should have panel editor state (this also ensures the form state gets reset between opens) */}\n {panelEditor && (\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelEditorForm\n panelKey={panelKey}\n initialAction={panelEditor.mode}\n initialValues={panelEditor.initialValues}\n onSave={handleSave}\n onClose={handleClose}\n />\n </ErrorBoundary>\n )}\n </Drawer>\n );\n }, [handleExited, handleSave, isOpen, panelEditor, panelKey]);\n\n // If the panel editor is using a repeat variable, we need to wrap the drawer in a VariableContext.Provider\n if (panelEditor?.panelGroupItemId?.repeatVariable) {\n return (\n <RepeatVariableWrapper repeatVariable={panelEditor.panelGroupItemId.repeatVariable}>\n {drawer}\n </RepeatVariableWrapper>\n );\n }\n\n return drawer;\n};\n\n// Wraps the drawer in a VariableContext.Provider to provide the repeat variable value\n// This is necessary for previewing panels that use repeat variables and query editor\nfunction RepeatVariableWrapper({\n repeatVariable,\n children,\n}: {\n repeatVariable: [string, string];\n children: ReactNode;\n}): ReactElement {\n const variables = useVariableValues();\n\n return (\n <VariableContext.Provider\n value={{ state: { ...variables, [repeatVariable[0]]: { value: repeatVariable[1], loading: false } } }}\n >\n {children}\n </VariableContext.Provider>\n );\n}\n"],"names":["useState","useMemo","useCallback","Drawer","ErrorAlert","ErrorBoundary","useVariableValues","VariableContext","usePanelEditor","usePanelKey","PanelEditorForm","PanelDrawer","panelEditor","panelKey","panelGroupItemId","isClosing","setIsClosing","isOpen","undefined","handleSave","values","Error","applyChanges","handleClose","handleExited","close","handleClickOut","drawer","onClose","slotProps","transition","onExited","data-testid","FallbackComponent","initialAction","mode","initialValues","onSave","repeatVariable","RepeatVariableWrapper","children","variables","Provider","value","state","loading"],"mappings":"AAAA,+BAA+B;AAC/B,oEAAoE;AACpE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,sEAAsE;AACtE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,uDAAuD,GACvD,+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,SAAuBA,QAAQ,EAAEC,OAAO,EAAaC,WAAW,QAAQ,QAAQ;AAChF,SAASC,MAAM,EAAEC,UAAU,EAAEC,aAAa,QAAQ,yBAAyB;AAE3E,SAASC,iBAAiB,EAAEC,eAAe,QAAQ,4BAA4B;AAC/E,SAASC,cAAc,EAAEC,WAAW,QAAQ,gBAAgB;AAC5D,SAASC,eAAe,QAAQ,oBAAoB;AAEpD;;CAEC,GACD,OAAO,MAAMC,cAAc;IACzB,MAAMC,cAAcJ;IACpB,MAAMK,WAAWJ,YAAYG,aAAaE;IAE1C,iHAAiH;IACjH,MAAM,CAACC,WAAWC,aAAa,GAAGhB,SAAS;IAE3C,oEAAoE;IACpE,MAAMiB,SAASL,gBAAgBM,aAAa,CAACH;IAE7C,MAAMI,aAAajB,YACjB,CAACkB;QACC,kHAAkH;QAClH,IAAIR,gBAAgBM,aAAaE,WAAWF,WAAW;YACrD,MAAM,IAAIG,MAAM;QAClB;QACAT,YAAYU,YAAY,CAACF;QACzBJ,aAAa;IACf,GACA;QAACJ;KAAY;IAGf,MAAMW,cAAc;QAClBP,aAAa;IACf;IAEA,6GAA6G;IAC7G,MAAMQ,eAAetB,YAAY;QAC/BU,aAAaa;QACbT,aAAa;IACf,GAAG;QAACJ;KAAY;IAEhB,6FAA6F;IAC7F,kHAAkH;IAClH,MAAMc,iBAAiB;IACrB,cAAc,GAChB;IAEA,MAAMC,SAAS1B,QAAQ;QACrB,qBACE,KAACE;YACCc,QAAQA;YACRW,SAASF;YACTG,WAAW;gBAAEC,YAAY;oBAAEC,UAAUP;gBAAa;YAAE;YACpDQ,eAAY;sBAGXpB,6BACC,KAACP;gBAAc4B,mBAAmB7B;0BAChC,cAAA,KAACM;oBACCG,UAAUA;oBACVqB,eAAetB,YAAYuB,IAAI;oBAC/BC,eAAexB,YAAYwB,aAAa;oBACxCC,QAAQlB;oBACRS,SAASL;;;;IAMrB,GAAG;QAACC;QAAcL;QAAYF;QAAQL;QAAaC;KAAS;IAE5D,2GAA2G;IAC3G,IAAID,aAAaE,kBAAkBwB,gBAAgB;QACjD,qBACE,KAACC;YAAsBD,gBAAgB1B,YAAYE,gBAAgB,CAACwB,cAAc;sBAC/EX;;IAGP;IAEA,OAAOA;AACT,EAAE;AAEF,sFAAsF;AACtF,qFAAqF;AACrF,SAASY,sBAAsB,EAC7BD,cAAc,EACdE,QAAQ,EAIT;IACC,MAAMC,YAAYnC;IAElB,qBACE,KAACC,gBAAgBmC,QAAQ;QACvBC,OAAO;YAAEC,OAAO;gBAAE,GAAGH,SAAS;gBAAE,CAACH,cAAc,CAAC,EAAE,CAAC,EAAE;oBAAEK,OAAOL,cAAc,CAAC,EAAE;oBAAEO,SAAS;gBAAM;YAAE;QAAE;kBAEnGL;;AAGP"}
@@ -1,5 +1,6 @@
1
1
  import { ReactElement } from 'react';
2
- import { Action, PanelEditorValues } from '@perses-dev/core';
2
+ import { Action } from '@perses-dev/core';
3
+ import { PanelEditorValues } from '@perses-dev/spec';
3
4
  export interface PanelEditorFormProps {
4
5
  initialValues: PanelEditorValues;
5
6
  initialAction: Action;