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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/dist/cjs/components/GridLayout/GridItemContent.js +2 -2
  2. package/dist/cjs/components/Panel/Panel.js +4 -1
  3. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +2 -2
  4. package/dist/cjs/components/Variables/VariableEditor.js +51 -17
  5. package/dist/cjs/constants/defaults.js +32 -0
  6. package/dist/cjs/constants/index.js +1 -0
  7. package/dist/cjs/context/DashboardProvider/DashboardProvider.js +3 -3
  8. package/dist/cjs/context/DatasourceStoreProvider.js +4 -1
  9. package/dist/cjs/context/VariableProvider/VariableProvider.js +10 -6
  10. package/dist/cjs/index.js +1 -0
  11. package/dist/cjs/keyboard-shortcuts/index.js +3 -0
  12. package/dist/cjs/keyboard-shortcuts/utils.js +11 -0
  13. package/dist/cjs/model/PanelGroupDefinition.js +25 -0
  14. package/dist/cjs/model/VariableDefinition.js +16 -0
  15. package/dist/cjs/model/index.js +1 -0
  16. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +3 -3
  17. package/dist/components/AddGroupButton/AddGroupButton.js +1 -1
  18. package/dist/components/AddGroupButton/AddGroupButton.js.map +1 -1
  19. package/dist/components/AddPanelButton/AddPanelButton.js +1 -1
  20. package/dist/components/AddPanelButton/AddPanelButton.js.map +1 -1
  21. package/dist/components/Dashboard/Dashboard.js +1 -1
  22. package/dist/components/Dashboard/Dashboard.js.map +1 -1
  23. package/dist/components/DashboardLinks/DashboardLinksEditor.js +1 -1
  24. package/dist/components/DashboardLinks/DashboardLinksEditor.js.map +1 -1
  25. package/dist/components/DashboardLinks/EditDashboardLinksButton.js +1 -1
  26. package/dist/components/DashboardLinks/EditDashboardLinksButton.js.map +1 -1
  27. package/dist/components/DashboardShortcuts/useDashboardShortcuts.js.map +1 -1
  28. package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.js +1 -1
  29. package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.js.map +1 -1
  30. package/dist/components/DashboardToolbar/DashboardToolbar.js +1 -1
  31. package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
  32. package/dist/components/Datasources/DatasourceEditor.d.ts.map +1 -1
  33. package/dist/components/Datasources/DatasourceEditor.js +1 -1
  34. package/dist/components/Datasources/DatasourceEditor.js.map +1 -1
  35. package/dist/components/Datasources/EditDatasourcesButton.js +1 -1
  36. package/dist/components/Datasources/EditDatasourcesButton.js.map +1 -1
  37. package/dist/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.js +1 -1
  38. package/dist/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.js.map +1 -1
  39. package/dist/components/DownloadButton/DownloadButton.js +1 -1
  40. package/dist/components/DownloadButton/DownloadButton.js.map +1 -1
  41. package/dist/components/EditButton/EditButton.js +1 -1
  42. package/dist/components/EditButton/EditButton.js.map +1 -1
  43. package/dist/components/EditJsonButton/EditJsonButton.js +1 -1
  44. package/dist/components/EditJsonButton/EditJsonButton.js.map +1 -1
  45. package/dist/components/EditJsonDialog/EditJsonDialog.js +1 -1
  46. package/dist/components/EditJsonDialog/EditJsonDialog.js.map +1 -1
  47. package/dist/components/EmptyDashboard/EmptyDashboard.js +1 -1
  48. package/dist/components/EmptyDashboard/EmptyDashboard.js.map +1 -1
  49. package/dist/components/GridLayout/GridContainer.js +1 -1
  50. package/dist/components/GridLayout/GridContainer.js.map +1 -1
  51. package/dist/components/GridLayout/GridItemContent.d.ts +1 -1
  52. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  53. package/dist/components/GridLayout/GridItemContent.js +2 -2
  54. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  55. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  56. package/dist/components/GridLayout/GridLayout.js +1 -1
  57. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  58. package/dist/components/GridLayout/GridTitle.js +1 -1
  59. package/dist/components/GridLayout/GridTitle.js.map +1 -1
  60. package/dist/components/GridLayout/Row.d.ts +1 -1
  61. package/dist/components/GridLayout/Row.d.ts.map +1 -1
  62. package/dist/components/GridLayout/Row.js +1 -1
  63. package/dist/components/GridLayout/Row.js.map +1 -1
  64. package/dist/components/LeaveDialog/LeaveDialog.js +1 -1
  65. package/dist/components/LeaveDialog/LeaveDialog.js.map +1 -1
  66. package/dist/components/LinksDisplay/LinksDisplay.js +1 -1
  67. package/dist/components/LinksDisplay/LinksDisplay.js.map +1 -1
  68. package/dist/components/Panel/Panel.d.ts +1 -1
  69. package/dist/components/Panel/Panel.d.ts.map +1 -1
  70. package/dist/components/Panel/Panel.js +5 -2
  71. package/dist/components/Panel/Panel.js.map +1 -1
  72. package/dist/components/Panel/PanelActions.js +1 -1
  73. package/dist/components/Panel/PanelActions.js.map +1 -1
  74. package/dist/components/Panel/PanelContent.js +1 -1
  75. package/dist/components/Panel/PanelContent.js.map +1 -1
  76. package/dist/components/Panel/PanelHeader.js +1 -1
  77. package/dist/components/Panel/PanelHeader.js.map +1 -1
  78. package/dist/components/Panel/PanelPluginLoader.js +1 -1
  79. package/dist/components/Panel/PanelPluginLoader.js.map +1 -1
  80. package/dist/components/Panel/useSelectionItemActions.js +1 -1
  81. package/dist/components/Panel/useSelectionItemActions.js.map +1 -1
  82. package/dist/components/PanelDrawer/PanelDrawer.js +1 -1
  83. package/dist/components/PanelDrawer/PanelDrawer.js.map +1 -1
  84. package/dist/components/PanelDrawer/PanelEditorForm.d.ts +1 -1
  85. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  86. package/dist/components/PanelDrawer/PanelEditorForm.js +3 -3
  87. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  88. package/dist/components/PanelDrawer/PanelPreview.js +1 -1
  89. package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
  90. package/dist/components/PanelDrawer/PanelQueriesSharedControls.js +1 -1
  91. package/dist/components/PanelDrawer/PanelQueriesSharedControls.js.map +1 -1
  92. package/dist/components/PanelGroupDialog/PanelGroupDialog.js +1 -1
  93. package/dist/components/PanelGroupDialog/PanelGroupDialog.js.map +1 -1
  94. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js +1 -1
  95. package/dist/components/PanelGroupDialog/PanelGroupEditorForm.js.map +1 -1
  96. package/dist/components/QuerySummaryTable/QuerySummaryTable.js +1 -1
  97. package/dist/components/QuerySummaryTable/QuerySummaryTable.js.map +1 -1
  98. package/dist/components/QueryViewerDialog/QueryViewerDialog.js +1 -1
  99. package/dist/components/QueryViewerDialog/QueryViewerDialog.js.map +1 -1
  100. package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js +1 -1
  101. package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js.map +1 -1
  102. package/dist/components/Variables/EditVariablesButton.js +1 -1
  103. package/dist/components/Variables/EditVariablesButton.js.map +1 -1
  104. package/dist/components/Variables/ListVariableListBox.js +1 -1
  105. package/dist/components/Variables/ListVariableListBox.js.map +1 -1
  106. package/dist/components/Variables/Variable.js +2 -2
  107. package/dist/components/Variables/Variable.js.map +1 -1
  108. package/dist/components/Variables/VariableEditor.d.ts +1 -1
  109. package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
  110. package/dist/components/Variables/VariableEditor.js +56 -22
  111. package/dist/components/Variables/VariableEditor.js.map +1 -1
  112. package/dist/components/Variables/VariableList.d.ts.map +1 -1
  113. package/dist/components/Variables/VariableList.js +1 -1
  114. package/dist/components/Variables/VariableList.js.map +1 -1
  115. package/dist/constants/defaults.d.ts +4 -0
  116. package/dist/constants/defaults.d.ts.map +1 -0
  117. package/dist/constants/defaults.js +16 -0
  118. package/dist/constants/defaults.js.map +1 -0
  119. package/dist/constants/index.d.ts +1 -0
  120. package/dist/constants/index.d.ts.map +1 -1
  121. package/dist/constants/index.js +1 -0
  122. package/dist/constants/index.js.map +1 -1
  123. package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
  124. package/dist/context/DashboardProvider/DashboardProvider.js +2 -2
  125. package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
  126. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +1 -2
  127. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  128. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  129. package/dist/context/DashboardProvider/delete-panel-slice.d.ts +1 -1
  130. package/dist/context/DashboardProvider/delete-panel-slice.d.ts.map +1 -1
  131. package/dist/context/DashboardProvider/delete-panel-slice.js.map +1 -1
  132. package/dist/context/DashboardProvider/duplicate-panel-slice.d.ts +1 -1
  133. package/dist/context/DashboardProvider/duplicate-panel-slice.d.ts.map +1 -1
  134. package/dist/context/DashboardProvider/duplicate-panel-slice.js.map +1 -1
  135. package/dist/context/DashboardProvider/panel-editor-slice.d.ts +2 -1
  136. package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -1
  137. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  138. package/dist/context/DashboardProvider/panel-group-slice.d.ts +1 -1
  139. package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
  140. package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
  141. package/dist/context/DashboardProvider/view-panel-slice.d.ts +1 -1
  142. package/dist/context/DashboardProvider/view-panel-slice.d.ts.map +1 -1
  143. package/dist/context/DashboardProvider/view-panel-slice.js.map +1 -1
  144. package/dist/context/DatasourceStoreProvider.d.ts +1 -1
  145. package/dist/context/DatasourceStoreProvider.d.ts.map +1 -1
  146. package/dist/context/DatasourceStoreProvider.js +5 -2
  147. package/dist/context/DatasourceStoreProvider.js.map +1 -1
  148. package/dist/context/PanelEditorProvider/PanelEditorProvider.js +1 -1
  149. package/dist/context/PanelEditorProvider/PanelEditorProvider.js.map +1 -1
  150. package/dist/context/VariableProvider/VariableProvider.d.ts +3 -2
  151. package/dist/context/VariableProvider/VariableProvider.d.ts.map +1 -1
  152. package/dist/context/VariableProvider/VariableProvider.js +12 -8
  153. package/dist/context/VariableProvider/VariableProvider.js.map +1 -1
  154. package/dist/context/VariableProvider/hydrationUtils.d.ts +1 -1
  155. package/dist/context/VariableProvider/hydrationUtils.d.ts.map +1 -1
  156. package/dist/context/VariableProvider/hydrationUtils.js.map +1 -1
  157. package/dist/context/VariableProvider/utils.d.ts +1 -1
  158. package/dist/context/VariableProvider/utils.d.ts.map +1 -1
  159. package/dist/context/VariableProvider/utils.js.map +1 -1
  160. package/dist/context/useDashboard.d.ts +1 -2
  161. package/dist/context/useDashboard.d.ts.map +1 -1
  162. package/dist/context/useDashboard.js.map +1 -1
  163. package/dist/index.d.ts +1 -0
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js +1 -0
  166. package/dist/index.js.map +1 -1
  167. package/dist/keyboard-shortcuts/PanelFocusProvider.js +1 -1
  168. package/dist/keyboard-shortcuts/PanelFocusProvider.js.map +1 -1
  169. package/dist/keyboard-shortcuts/index.d.ts +1 -1
  170. package/dist/keyboard-shortcuts/index.d.ts.map +1 -1
  171. package/dist/keyboard-shortcuts/index.js +1 -1
  172. package/dist/keyboard-shortcuts/index.js.map +1 -1
  173. package/dist/keyboard-shortcuts/utils.d.ts +8 -0
  174. package/dist/keyboard-shortcuts/utils.d.ts.map +1 -1
  175. package/dist/keyboard-shortcuts/utils.js +13 -0
  176. package/dist/keyboard-shortcuts/utils.js.map +1 -1
  177. package/dist/model/PanelGroupDefinition.d.ts +59 -0
  178. package/dist/model/PanelGroupDefinition.d.ts.map +1 -0
  179. package/dist/model/PanelGroupDefinition.js +19 -0
  180. package/dist/model/PanelGroupDefinition.js.map +1 -0
  181. package/dist/model/VariableDefinition.d.ts +50 -0
  182. package/dist/model/VariableDefinition.d.ts.map +1 -0
  183. package/dist/model/VariableDefinition.js +20 -0
  184. package/dist/model/VariableDefinition.js.map +1 -0
  185. package/dist/model/index.d.ts +1 -0
  186. package/dist/model/index.d.ts.map +1 -1
  187. package/dist/model/index.js +1 -0
  188. package/dist/model/index.js.map +1 -1
  189. package/dist/test/datasource-provider.d.ts +1 -1
  190. package/dist/test/datasource-provider.d.ts.map +1 -1
  191. package/dist/test/datasource-provider.js.map +1 -1
  192. package/dist/test/render.js +1 -1
  193. package/dist/test/render.js.map +1 -1
  194. package/dist/utils/panelUtils.d.ts +1 -1
  195. package/dist/utils/panelUtils.d.ts.map +1 -1
  196. package/dist/utils/panelUtils.js.map +1 -1
  197. package/dist/views/ViewDashboard/DashboardApp.js +1 -1
  198. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  199. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  200. package/dist/views/ViewDashboard/ViewDashboard.js +2 -2
  201. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  202. package/package.json +6 -9
package/dist/index.js CHANGED
@@ -15,5 +15,6 @@ export * from './context';
15
15
  export * from './keyboard-shortcuts';
16
16
  export * from './views';
17
17
  export * from './model';
18
+ export * from './constants';
18
19
 
19
20
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/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 './components';\nexport * from './context';\nexport * from './keyboard-shortcuts';\nexport * from './views';\nexport * from './model';\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,eAAe;AAC7B,cAAc,YAAY;AAC1B,cAAc,uBAAuB;AACrC,cAAc,UAAU;AACxB,cAAc,UAAU"}
1
+ {"version":3,"sources":["../src/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 './components';\nexport * from './context';\nexport * from './keyboard-shortcuts';\nexport * from './views';\nexport * from './model';\nexport * from './constants';\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,eAAe;AAC7B,cAAc,YAAY;AAC1B,cAAc,uBAAuB;AACrC,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,cAAc"}
@@ -1,3 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  // Copyright The Perses Authors
2
3
  // Licensed under the Apache License, Version 2.0 (the "License");
3
4
  // you may not use this file except in compliance with the License.
@@ -10,7 +11,6 @@
10
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
12
  // See the License for the specific language governing permissions and
12
13
  // limitations under the License.
13
- import { jsx as _jsx } from "react/jsx-runtime";
14
14
  import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
15
15
  const PanelFocusContext = /*#__PURE__*/ createContext(undefined);
16
16
  function usePanelFocusContext() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/keyboard-shortcuts/PanelFocusProvider.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 React, {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\ninterface PanelFocusContextValue {\n focusedPanelKey: string | null;\n setFocusedPanel: (panelKey: string) => void;\n clearFocusedPanel: () => void;\n}\n\nconst PanelFocusContext = createContext<PanelFocusContextValue | undefined>(undefined);\n\nfunction usePanelFocusContext(): PanelFocusContextValue {\n const ctx = useContext(PanelFocusContext);\n if (ctx === undefined) {\n throw new Error('Panel focus hooks must be used within a PanelFocusProvider');\n }\n return ctx;\n}\n\n/** Tracks which dashboard panel is currently focused (hovered) for panel-scoped shortcuts. */\nexport function PanelFocusProvider({ children }: { children: ReactNode }): ReactElement {\n const [focusedPanelKey, setFocusedPanelKeyState] = useState<string | null>(null);\n\n // This wrapper narrow the setter type (string-only / null-only) and provide\n // stable references for the useMemo context value below. React guarantees\n // setFocusedPanelKeyState is stable, but useCallback makes the stability\n // explicit and satisfies exhaustive-deps when used in useMemo.\n const setFocusedPanel = useCallback((panelKey: string) => {\n setFocusedPanelKeyState(panelKey);\n }, []);\n\n const clearFocusedPanel = useCallback(() => {\n setFocusedPanelKeyState(null);\n }, []);\n\n const value = useMemo(\n (): PanelFocusContextValue => ({\n focusedPanelKey,\n setFocusedPanel,\n clearFocusedPanel,\n }),\n [focusedPanelKey, setFocusedPanel, clearFocusedPanel]\n );\n\n return <PanelFocusContext.Provider value={value}>{children}</PanelFocusContext.Provider>;\n}\n\nexport function useFocusedPanel(): string | null {\n return usePanelFocusContext().focusedPanelKey;\n}\n\nconst PANEL_FOCUS_DEBOUNCE_MS = 50;\n\n/** Debounced mouse enter/leave handlers for panel focus. Add `tabIndex={-1}` to the panel element. */\nexport function usePanelFocusHandlers(panelKey: string): {\n onMouseEnter: (e: React.MouseEvent<HTMLElement>) => void;\n onMouseLeave: () => void;\n} {\n const { setFocusedPanel, clearFocusedPanel } = usePanelFocusContext();\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const onMouseEnter = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n const element = e.currentTarget;\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n timerRef.current = setTimeout(() => {\n setFocusedPanel(panelKey);\n element.focus({ preventScroll: true });\n timerRef.current = null;\n }, PANEL_FOCUS_DEBOUNCE_MS);\n },\n [panelKey, setFocusedPanel]\n );\n\n const onMouseLeave = useCallback(() => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n clearFocusedPanel();\n }, [clearFocusedPanel]);\n\n useEffect(() => {\n return (): void => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n };\n }, []);\n\n return useMemo(() => ({ onMouseEnter, onMouseLeave }), [onMouseEnter, onMouseLeave]);\n}\n"],"names":["React","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","PanelFocusContext","undefined","usePanelFocusContext","ctx","Error","PanelFocusProvider","children","focusedPanelKey","setFocusedPanelKeyState","setFocusedPanel","panelKey","clearFocusedPanel","value","Provider","useFocusedPanel","PANEL_FOCUS_DEBOUNCE_MS","usePanelFocusHandlers","timerRef","onMouseEnter","e","element","currentTarget","current","clearTimeout","setTimeout","focus","preventScroll","onMouseLeave"],"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,OAAOA,SACLC,aAAa,EAGbC,WAAW,EACXC,UAAU,EACVC,SAAS,EACTC,OAAO,EACPC,MAAM,EACNC,QAAQ,QACH,QAAQ;AAQf,MAAMC,kCAAoBP,cAAkDQ;AAE5E,SAASC;IACP,MAAMC,MAAMR,WAAWK;IACvB,IAAIG,QAAQF,WAAW;QACrB,MAAM,IAAIG,MAAM;IAClB;IACA,OAAOD;AACT;AAEA,4FAA4F,GAC5F,OAAO,SAASE,mBAAmB,EAAEC,QAAQ,EAA2B;IACtE,MAAM,CAACC,iBAAiBC,wBAAwB,GAAGT,SAAwB;IAE3E,4EAA4E;IAC5E,0EAA0E;IAC1E,yEAAyE;IACzE,+DAA+D;IAC/D,MAAMU,kBAAkBf,YAAY,CAACgB;QACnCF,wBAAwBE;IAC1B,GAAG,EAAE;IAEL,MAAMC,oBAAoBjB,YAAY;QACpCc,wBAAwB;IAC1B,GAAG,EAAE;IAEL,MAAMI,QAAQf,QACZ,IAA+B,CAAA;YAC7BU;YACAE;YACAE;QACF,CAAA,GACA;QAACJ;QAAiBE;QAAiBE;KAAkB;IAGvD,qBAAO,KAACX,kBAAkBa,QAAQ;QAACD,OAAOA;kBAAQN;;AACpD;AAEA,OAAO,SAASQ;IACd,OAAOZ,uBAAuBK,eAAe;AAC/C;AAEA,MAAMQ,0BAA0B;AAEhC,oGAAoG,GACpG,OAAO,SAASC,sBAAsBN,QAAgB;IAIpD,MAAM,EAAED,eAAe,EAAEE,iBAAiB,EAAE,GAAGT;IAC/C,MAAMe,WAAWnB,OAA6C;IAE9D,MAAMoB,eAAexB,YACnB,CAACyB;QACC,MAAMC,UAAUD,EAAEE,aAAa;QAC/B,IAAIJ,SAASK,OAAO,KAAK,MAAM;YAC7BC,aAAaN,SAASK,OAAO;QAC/B;QACAL,SAASK,OAAO,GAAGE,WAAW;YAC5Bf,gBAAgBC;YAChBU,QAAQK,KAAK,CAAC;gBAAEC,eAAe;YAAK;YACpCT,SAASK,OAAO,GAAG;QACrB,GAAGP;IACL,GACA;QAACL;QAAUD;KAAgB;IAG7B,MAAMkB,eAAejC,YAAY;QAC/B,IAAIuB,SAASK,OAAO,KAAK,MAAM;YAC7BC,aAAaN,SAASK,OAAO;YAC7BL,SAASK,OAAO,GAAG;QACrB;QACAX;IACF,GAAG;QAACA;KAAkB;IAEtBf,UAAU;QACR,OAAO;YACL,IAAIqB,SAASK,OAAO,KAAK,MAAM;gBAC7BC,aAAaN,SAASK,OAAO;YAC/B;QACF;IACF,GAAG,EAAE;IAEL,OAAOzB,QAAQ,IAAO,CAAA;YAAEqB;YAAcS;QAAa,CAAA,GAAI;QAACT;QAAcS;KAAa;AACrF"}
1
+ {"version":3,"sources":["../../src/keyboard-shortcuts/PanelFocusProvider.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 React, {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\ninterface PanelFocusContextValue {\n focusedPanelKey: string | null;\n setFocusedPanel: (panelKey: string) => void;\n clearFocusedPanel: () => void;\n}\n\nconst PanelFocusContext = createContext<PanelFocusContextValue | undefined>(undefined);\n\nfunction usePanelFocusContext(): PanelFocusContextValue {\n const ctx = useContext(PanelFocusContext);\n if (ctx === undefined) {\n throw new Error('Panel focus hooks must be used within a PanelFocusProvider');\n }\n return ctx;\n}\n\n/** Tracks which dashboard panel is currently focused (hovered) for panel-scoped shortcuts. */\nexport function PanelFocusProvider({ children }: { children: ReactNode }): ReactElement {\n const [focusedPanelKey, setFocusedPanelKeyState] = useState<string | null>(null);\n\n // This wrapper narrow the setter type (string-only / null-only) and provide\n // stable references for the useMemo context value below. React guarantees\n // setFocusedPanelKeyState is stable, but useCallback makes the stability\n // explicit and satisfies exhaustive-deps when used in useMemo.\n const setFocusedPanel = useCallback((panelKey: string) => {\n setFocusedPanelKeyState(panelKey);\n }, []);\n\n const clearFocusedPanel = useCallback(() => {\n setFocusedPanelKeyState(null);\n }, []);\n\n const value = useMemo(\n (): PanelFocusContextValue => ({\n focusedPanelKey,\n setFocusedPanel,\n clearFocusedPanel,\n }),\n [focusedPanelKey, setFocusedPanel, clearFocusedPanel]\n );\n\n return <PanelFocusContext.Provider value={value}>{children}</PanelFocusContext.Provider>;\n}\n\nexport function useFocusedPanel(): string | null {\n return usePanelFocusContext().focusedPanelKey;\n}\n\nconst PANEL_FOCUS_DEBOUNCE_MS = 50;\n\n/** Debounced mouse enter/leave handlers for panel focus. Add `tabIndex={-1}` to the panel element. */\nexport function usePanelFocusHandlers(panelKey: string): {\n onMouseEnter: (e: React.MouseEvent<HTMLElement>) => void;\n onMouseLeave: () => void;\n} {\n const { setFocusedPanel, clearFocusedPanel } = usePanelFocusContext();\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const onMouseEnter = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n const element = e.currentTarget;\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n timerRef.current = setTimeout(() => {\n setFocusedPanel(panelKey);\n element.focus({ preventScroll: true });\n timerRef.current = null;\n }, PANEL_FOCUS_DEBOUNCE_MS);\n },\n [panelKey, setFocusedPanel]\n );\n\n const onMouseLeave = useCallback(() => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n clearFocusedPanel();\n }, [clearFocusedPanel]);\n\n useEffect(() => {\n return (): void => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n };\n }, []);\n\n return useMemo(() => ({ onMouseEnter, onMouseLeave }), [onMouseEnter, onMouseLeave]);\n}\n"],"names":["React","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","PanelFocusContext","undefined","usePanelFocusContext","ctx","Error","PanelFocusProvider","children","focusedPanelKey","setFocusedPanelKeyState","setFocusedPanel","panelKey","clearFocusedPanel","value","Provider","useFocusedPanel","PANEL_FOCUS_DEBOUNCE_MS","usePanelFocusHandlers","timerRef","onMouseEnter","e","element","currentTarget","current","clearTimeout","setTimeout","focus","preventScroll","onMouseLeave"],"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,OAAOA,SACLC,aAAa,EAGbC,WAAW,EACXC,UAAU,EACVC,SAAS,EACTC,OAAO,EACPC,MAAM,EACNC,QAAQ,QACH,QAAQ;AAQf,MAAMC,kCAAoBP,cAAkDQ;AAE5E,SAASC;IACP,MAAMC,MAAMR,WAAWK;IACvB,IAAIG,QAAQF,WAAW;QACrB,MAAM,IAAIG,MAAM;IAClB;IACA,OAAOD;AACT;AAEA,4FAA4F,GAC5F,OAAO,SAASE,mBAAmB,EAAEC,QAAQ,EAA2B;IACtE,MAAM,CAACC,iBAAiBC,wBAAwB,GAAGT,SAAwB;IAE3E,4EAA4E;IAC5E,0EAA0E;IAC1E,yEAAyE;IACzE,+DAA+D;IAC/D,MAAMU,kBAAkBf,YAAY,CAACgB;QACnCF,wBAAwBE;IAC1B,GAAG,EAAE;IAEL,MAAMC,oBAAoBjB,YAAY;QACpCc,wBAAwB;IAC1B,GAAG,EAAE;IAEL,MAAMI,QAAQf,QACZ,IAA+B,CAAA;YAC7BU;YACAE;YACAE;QACF,CAAA,GACA;QAACJ;QAAiBE;QAAiBE;KAAkB;IAGvD,qBAAO,KAACX,kBAAkBa,QAAQ;QAACD,OAAOA;kBAAQN;;AACpD;AAEA,OAAO,SAASQ;IACd,OAAOZ,uBAAuBK,eAAe;AAC/C;AAEA,MAAMQ,0BAA0B;AAEhC,oGAAoG,GACpG,OAAO,SAASC,sBAAsBN,QAAgB;IAIpD,MAAM,EAAED,eAAe,EAAEE,iBAAiB,EAAE,GAAGT;IAC/C,MAAMe,WAAWnB,OAA6C;IAE9D,MAAMoB,eAAexB,YACnB,CAACyB;QACC,MAAMC,UAAUD,EAAEE,aAAa;QAC/B,IAAIJ,SAASK,OAAO,KAAK,MAAM;YAC7BC,aAAaN,SAASK,OAAO;QAC/B;QACAL,SAASK,OAAO,GAAGE,WAAW;YAC5Bf,gBAAgBC;YAChBU,QAAQK,KAAK,CAAC;gBAAEC,eAAe;YAAK;YACpCT,SAASK,OAAO,GAAG;QACrB,GAAGP;IACL,GACA;QAACL;QAAUD;KAAgB;IAG7B,MAAMkB,eAAejC,YAAY;QAC/B,IAAIuB,SAASK,OAAO,KAAK,MAAM;YAC7BC,aAAaN,SAASK,OAAO;YAC7BL,SAASK,OAAO,GAAG;QACrB;QACAX;IACF,GAAG;QAACA;KAAkB;IAEtBf,UAAU;QACR,OAAO;YACL,IAAIqB,SAASK,OAAO,KAAK,MAAM;gBAC7BC,aAAaN,SAASK,OAAO;YAC/B;QACF;IACF,GAAG,EAAE;IAEL,OAAOzB,QAAQ,IAAO,CAAA;YAAEqB;YAAcS;QAAa,CAAA,GAAI;QAACT;QAAcS;KAAa;AACrF"}
@@ -1,7 +1,7 @@
1
1
  export * from './types';
2
2
  export * from './events';
3
3
  export { PanelFocusProvider, useFocusedPanel, usePanelFocusHandlers } from './PanelFocusProvider';
4
- export { buildShortcutOptions, dispatchShortcutEvent, requireShortcutEvent, requireShortcutHotkey, requireShortcutSequence, } from './utils';
4
+ export { buildShortcutOptions, createModEnterHandler, dispatchShortcutEvent, requireShortcutEvent, requireShortcutHotkey, requireShortcutSequence, } from './utils';
5
5
  export * from './default-shortcuts';
6
6
  export { HotkeysProvider, useHotkey, useHotkeys, useHotkeySequence, useHotkeySequences, useHotkeyRegistrations, } from '@tanstack/react-hotkeys';
7
7
  export { formatForDisplay } from '@tanstack/hotkeys';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keyboard-shortcuts/index.ts"],"names":[],"mappings":"AAaA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AACjB,cAAc,qBAAqB,CAAC;AACpC,OAAO,EACL,eAAe,EACf,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keyboard-shortcuts/index.ts"],"names":[],"mappings":"AAaA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AACjB,cAAc,qBAAqB,CAAC;AACpC,OAAO,EACL,eAAe,EACf,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
@@ -13,7 +13,7 @@
13
13
  export * from './types';
14
14
  export * from './events';
15
15
  export { PanelFocusProvider, useFocusedPanel, usePanelFocusHandlers } from './PanelFocusProvider';
16
- export { buildShortcutOptions, dispatchShortcutEvent, requireShortcutEvent, requireShortcutHotkey, requireShortcutSequence } from './utils';
16
+ export { buildShortcutOptions, createModEnterHandler, dispatchShortcutEvent, requireShortcutEvent, requireShortcutHotkey, requireShortcutSequence } from './utils';
17
17
  export * from './default-shortcuts';
18
18
  export { HotkeysProvider, useHotkey, useHotkeys, useHotkeySequence, useHotkeySequences, useHotkeyRegistrations } from '@tanstack/react-hotkeys';
19
19
  export { formatForDisplay } from '@tanstack/hotkeys';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/keyboard-shortcuts/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 './types';\nexport * from './events';\nexport { PanelFocusProvider, useFocusedPanel, usePanelFocusHandlers } from './PanelFocusProvider';\nexport {\n buildShortcutOptions,\n dispatchShortcutEvent,\n requireShortcutEvent,\n requireShortcutHotkey,\n requireShortcutSequence,\n} from './utils';\nexport * from './default-shortcuts';\nexport {\n HotkeysProvider,\n useHotkey,\n useHotkeys,\n useHotkeySequence,\n useHotkeySequences,\n useHotkeyRegistrations,\n} from '@tanstack/react-hotkeys';\nexport { formatForDisplay } from '@tanstack/hotkeys';\nexport type { HotkeyMeta, HotkeySequence } from '@tanstack/hotkeys';\n"],"names":["PanelFocusProvider","useFocusedPanel","usePanelFocusHandlers","buildShortcutOptions","dispatchShortcutEvent","requireShortcutEvent","requireShortcutHotkey","requireShortcutSequence","HotkeysProvider","useHotkey","useHotkeys","useHotkeySequence","useHotkeySequences","useHotkeyRegistrations","formatForDisplay"],"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,UAAU;AACxB,cAAc,WAAW;AACzB,SAASA,kBAAkB,EAAEC,eAAe,EAAEC,qBAAqB,QAAQ,uBAAuB;AAClG,SACEC,oBAAoB,EACpBC,qBAAqB,EACrBC,oBAAoB,EACpBC,qBAAqB,EACrBC,uBAAuB,QAClB,UAAU;AACjB,cAAc,sBAAsB;AACpC,SACEC,eAAe,EACfC,SAAS,EACTC,UAAU,EACVC,iBAAiB,EACjBC,kBAAkB,EAClBC,sBAAsB,QACjB,0BAA0B;AACjC,SAASC,gBAAgB,QAAQ,oBAAoB"}
1
+ {"version":3,"sources":["../../src/keyboard-shortcuts/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 './types';\nexport * from './events';\nexport { PanelFocusProvider, useFocusedPanel, usePanelFocusHandlers } from './PanelFocusProvider';\nexport {\n buildShortcutOptions,\n createModEnterHandler,\n dispatchShortcutEvent,\n requireShortcutEvent,\n requireShortcutHotkey,\n requireShortcutSequence,\n} from './utils';\nexport * from './default-shortcuts';\nexport {\n HotkeysProvider,\n useHotkey,\n useHotkeys,\n useHotkeySequence,\n useHotkeySequences,\n useHotkeyRegistrations,\n} from '@tanstack/react-hotkeys';\nexport { formatForDisplay } from '@tanstack/hotkeys';\nexport type { HotkeyMeta, HotkeySequence } from '@tanstack/hotkeys';\n"],"names":["PanelFocusProvider","useFocusedPanel","usePanelFocusHandlers","buildShortcutOptions","createModEnterHandler","dispatchShortcutEvent","requireShortcutEvent","requireShortcutHotkey","requireShortcutSequence","HotkeysProvider","useHotkey","useHotkeys","useHotkeySequence","useHotkeySequences","useHotkeyRegistrations","formatForDisplay"],"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,UAAU;AACxB,cAAc,WAAW;AACzB,SAASA,kBAAkB,EAAEC,eAAe,EAAEC,qBAAqB,QAAQ,uBAAuB;AAClG,SACEC,oBAAoB,EACpBC,qBAAqB,EACrBC,qBAAqB,EACrBC,oBAAoB,EACpBC,qBAAqB,EACrBC,uBAAuB,QAClB,UAAU;AACjB,cAAc,sBAAsB;AACpC,SACEC,eAAe,EACfC,SAAS,EACTC,UAAU,EACVC,iBAAiB,EACjBC,kBAAkB,EAClBC,sBAAsB,QACjB,0BAA0B;AACjC,SAASC,gBAAgB,QAAQ,oBAAoB"}
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import { HotkeyMeta, HotkeySequence, RegisterableHotkey } from '@tanstack/hotkeys';
2
3
  import { PersesShortcutDef } from './types';
3
4
  export declare function buildShortcutOptions(def: PersesShortcutDef, enabled: boolean): {
@@ -9,4 +10,11 @@ export declare function requireShortcutHotkey(def: PersesShortcutDef): Registera
9
10
  export declare function requireShortcutSequence(def: PersesShortcutDef): HotkeySequence;
10
11
  export declare function requireShortcutEvent(def: PersesShortcutDef): string;
11
12
  export declare function dispatchShortcutEvent(eventName: string): void;
13
+ /**
14
+ * Creates an onKeyDown handler that fires `execute` on exact Mod+Enter (Cmd+Enter on Mac, Ctrl+Enter on others).
15
+ * Performs exact modifier matching: Mod+Shift+Enter or Mod+Alt+Enter will NOT trigger the handler.
16
+ * Designed for use with CodeMirror editors via the onKeyDown prop, where it must call
17
+ * preventDefault() before CodeMirror processes the key event.
18
+ */
19
+ export declare function createModEnterHandler(execute: () => void): React.KeyboardEventHandler<HTMLElement>;
12
20
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/keyboard-shortcuts/utils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,OAAO,GACf;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAaA;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,iBAAiB,GAAG,kBAAkB,CAKhF;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,iBAAiB,GAAG,cAAc,CAK9E;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,CAKnE;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE7D"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/keyboard-shortcuts/utils.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,OAAO,GACf;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAaA;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,iBAAiB,GAAG,kBAAkB,CAKhF;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,iBAAiB,GAAG,cAAc,CAK9E;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,CAKnE;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE7D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,KAAK,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAOlG"}
@@ -47,5 +47,18 @@ export function requireShortcutEvent(def) {
47
47
  export function dispatchShortcutEvent(eventName) {
48
48
  window.dispatchEvent(new CustomEvent(eventName));
49
49
  }
50
+ /**
51
+ * Creates an onKeyDown handler that fires `execute` on exact Mod+Enter (Cmd+Enter on Mac, Ctrl+Enter on others).
52
+ * Performs exact modifier matching: Mod+Shift+Enter or Mod+Alt+Enter will NOT trigger the handler.
53
+ * Designed for use with CodeMirror editors via the onKeyDown prop, where it must call
54
+ * preventDefault() before CodeMirror processes the key event.
55
+ */ export function createModEnterHandler(execute) {
56
+ return (event)=>{
57
+ if (event.key === 'Enter' && (event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey) {
58
+ event.preventDefault();
59
+ execute();
60
+ }
61
+ };
62
+ }
50
63
 
51
64
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/keyboard-shortcuts/utils.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { HotkeyMeta, HotkeySequence, RegisterableHotkey } from '@tanstack/hotkeys';\nimport { PersesShortcutDef } from './types';\n\nexport function buildShortcutOptions(\n def: PersesShortcutDef,\n enabled: boolean\n): {\n enabled: boolean;\n meta: HotkeyMeta;\n ignoreInputs?: boolean;\n} {\n return {\n enabled,\n meta: {\n id: def.id,\n name: def.name,\n description: def.description,\n category: def.category,\n scope: def.scope,\n displayOverride: def.displayOverride,\n },\n ...(def.ignoreInputs !== undefined ? { ignoreInputs: def.ignoreInputs } : {}),\n };\n}\n\nexport function requireShortcutHotkey(def: PersesShortcutDef): RegisterableHotkey {\n if (def.hotkey === undefined) {\n throw new Error(`Shortcut ${def.id} is missing a hotkey definition`);\n }\n return def.hotkey;\n}\n\nexport function requireShortcutSequence(def: PersesShortcutDef): HotkeySequence {\n if (def.sequence === undefined) {\n throw new Error(`Shortcut ${def.id} is missing a sequence definition`);\n }\n return def.sequence;\n}\n\nexport function requireShortcutEvent(def: PersesShortcutDef): string {\n if (def.event === undefined) {\n throw new Error(`Shortcut ${def.id} is missing an event definition`);\n }\n return def.event;\n}\n\nexport function dispatchShortcutEvent(eventName: string): void {\n window.dispatchEvent(new CustomEvent(eventName));\n}\n"],"names":["buildShortcutOptions","def","enabled","meta","id","name","description","category","scope","displayOverride","ignoreInputs","undefined","requireShortcutHotkey","hotkey","Error","requireShortcutSequence","sequence","requireShortcutEvent","event","dispatchShortcutEvent","eventName","window","dispatchEvent","CustomEvent"],"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;AAKjC,OAAO,SAASA,qBACdC,GAAsB,EACtBC,OAAgB;IAMhB,OAAO;QACLA;QACAC,MAAM;YACJC,IAAIH,IAAIG,EAAE;YACVC,MAAMJ,IAAII,IAAI;YACdC,aAAaL,IAAIK,WAAW;YAC5BC,UAAUN,IAAIM,QAAQ;YACtBC,OAAOP,IAAIO,KAAK;YAChBC,iBAAiBR,IAAIQ,eAAe;QACtC;QACA,GAAIR,IAAIS,YAAY,KAAKC,YAAY;YAAED,cAAcT,IAAIS,YAAY;QAAC,IAAI,CAAC,CAAC;IAC9E;AACF;AAEA,OAAO,SAASE,sBAAsBX,GAAsB;IAC1D,IAAIA,IAAIY,MAAM,KAAKF,WAAW;QAC5B,MAAM,IAAIG,MAAM,CAAC,SAAS,EAAEb,IAAIG,EAAE,CAAC,+BAA+B,CAAC;IACrE;IACA,OAAOH,IAAIY,MAAM;AACnB;AAEA,OAAO,SAASE,wBAAwBd,GAAsB;IAC5D,IAAIA,IAAIe,QAAQ,KAAKL,WAAW;QAC9B,MAAM,IAAIG,MAAM,CAAC,SAAS,EAAEb,IAAIG,EAAE,CAAC,iCAAiC,CAAC;IACvE;IACA,OAAOH,IAAIe,QAAQ;AACrB;AAEA,OAAO,SAASC,qBAAqBhB,GAAsB;IACzD,IAAIA,IAAIiB,KAAK,KAAKP,WAAW;QAC3B,MAAM,IAAIG,MAAM,CAAC,SAAS,EAAEb,IAAIG,EAAE,CAAC,+BAA+B,CAAC;IACrE;IACA,OAAOH,IAAIiB,KAAK;AAClB;AAEA,OAAO,SAASC,sBAAsBC,SAAiB;IACrDC,OAAOC,aAAa,CAAC,IAAIC,YAAYH;AACvC"}
1
+ {"version":3,"sources":["../../src/keyboard-shortcuts/utils.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport React from 'react';\nimport { HotkeyMeta, HotkeySequence, RegisterableHotkey } from '@tanstack/hotkeys';\nimport { PersesShortcutDef } from './types';\n\nexport function buildShortcutOptions(\n def: PersesShortcutDef,\n enabled: boolean\n): {\n enabled: boolean;\n meta: HotkeyMeta;\n ignoreInputs?: boolean;\n} {\n return {\n enabled,\n meta: {\n id: def.id,\n name: def.name,\n description: def.description,\n category: def.category,\n scope: def.scope,\n displayOverride: def.displayOverride,\n },\n ...(def.ignoreInputs !== undefined ? { ignoreInputs: def.ignoreInputs } : {}),\n };\n}\n\nexport function requireShortcutHotkey(def: PersesShortcutDef): RegisterableHotkey {\n if (def.hotkey === undefined) {\n throw new Error(`Shortcut ${def.id} is missing a hotkey definition`);\n }\n return def.hotkey;\n}\n\nexport function requireShortcutSequence(def: PersesShortcutDef): HotkeySequence {\n if (def.sequence === undefined) {\n throw new Error(`Shortcut ${def.id} is missing a sequence definition`);\n }\n return def.sequence;\n}\n\nexport function requireShortcutEvent(def: PersesShortcutDef): string {\n if (def.event === undefined) {\n throw new Error(`Shortcut ${def.id} is missing an event definition`);\n }\n return def.event;\n}\n\nexport function dispatchShortcutEvent(eventName: string): void {\n window.dispatchEvent(new CustomEvent(eventName));\n}\n\n/**\n * Creates an onKeyDown handler that fires `execute` on exact Mod+Enter (Cmd+Enter on Mac, Ctrl+Enter on others).\n * Performs exact modifier matching: Mod+Shift+Enter or Mod+Alt+Enter will NOT trigger the handler.\n * Designed for use with CodeMirror editors via the onKeyDown prop, where it must call\n * preventDefault() before CodeMirror processes the key event.\n */\nexport function createModEnterHandler(execute: () => void): React.KeyboardEventHandler<HTMLElement> {\n return (event: React.KeyboardEvent<HTMLElement>): void => {\n if (event.key === 'Enter' && (event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey) {\n event.preventDefault();\n execute();\n }\n };\n}\n"],"names":["buildShortcutOptions","def","enabled","meta","id","name","description","category","scope","displayOverride","ignoreInputs","undefined","requireShortcutHotkey","hotkey","Error","requireShortcutSequence","sequence","requireShortcutEvent","event","dispatchShortcutEvent","eventName","window","dispatchEvent","CustomEvent","createModEnterHandler","execute","key","ctrlKey","metaKey","shiftKey","altKey","preventDefault"],"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;AAMjC,OAAO,SAASA,qBACdC,GAAsB,EACtBC,OAAgB;IAMhB,OAAO;QACLA;QACAC,MAAM;YACJC,IAAIH,IAAIG,EAAE;YACVC,MAAMJ,IAAII,IAAI;YACdC,aAAaL,IAAIK,WAAW;YAC5BC,UAAUN,IAAIM,QAAQ;YACtBC,OAAOP,IAAIO,KAAK;YAChBC,iBAAiBR,IAAIQ,eAAe;QACtC;QACA,GAAIR,IAAIS,YAAY,KAAKC,YAAY;YAAED,cAAcT,IAAIS,YAAY;QAAC,IAAI,CAAC,CAAC;IAC9E;AACF;AAEA,OAAO,SAASE,sBAAsBX,GAAsB;IAC1D,IAAIA,IAAIY,MAAM,KAAKF,WAAW;QAC5B,MAAM,IAAIG,MAAM,CAAC,SAAS,EAAEb,IAAIG,EAAE,CAAC,+BAA+B,CAAC;IACrE;IACA,OAAOH,IAAIY,MAAM;AACnB;AAEA,OAAO,SAASE,wBAAwBd,GAAsB;IAC5D,IAAIA,IAAIe,QAAQ,KAAKL,WAAW;QAC9B,MAAM,IAAIG,MAAM,CAAC,SAAS,EAAEb,IAAIG,EAAE,CAAC,iCAAiC,CAAC;IACvE;IACA,OAAOH,IAAIe,QAAQ;AACrB;AAEA,OAAO,SAASC,qBAAqBhB,GAAsB;IACzD,IAAIA,IAAIiB,KAAK,KAAKP,WAAW;QAC3B,MAAM,IAAIG,MAAM,CAAC,SAAS,EAAEb,IAAIG,EAAE,CAAC,+BAA+B,CAAC;IACrE;IACA,OAAOH,IAAIiB,KAAK;AAClB;AAEA,OAAO,SAASC,sBAAsBC,SAAiB;IACrDC,OAAOC,aAAa,CAAC,IAAIC,YAAYH;AACvC;AAEA;;;;;CAKC,GACD,OAAO,SAASI,sBAAsBC,OAAmB;IACvD,OAAO,CAACP;QACN,IAAIA,MAAMQ,GAAG,KAAK,WAAYR,CAAAA,MAAMS,OAAO,IAAIT,MAAMU,OAAO,AAAD,KAAM,CAACV,MAAMW,QAAQ,IAAI,CAACX,MAAMY,MAAM,EAAE;YACjGZ,MAAMa,cAAc;YACpBN;QACF;IACF;AACF"}
@@ -0,0 +1,59 @@
1
+ export type PanelGroupId = number;
2
+ /**
3
+ * Panel Group Item Layout ID type. String identifier for items within a panel group.
4
+ */
5
+ export type PanelGroupItemLayoutId = string;
6
+ /**
7
+ * Uniquely identifies an item in a PanelGroup.
8
+ */
9
+ export interface PanelGroupItemId {
10
+ panelGroupId: PanelGroupId;
11
+ panelGroupItemLayoutId: PanelGroupItemLayoutId;
12
+ repeatVariable?: [string, string];
13
+ }
14
+ /**
15
+ * Base layout properties for positioning and sizing items in a grid.
16
+ * This is a framework-agnostic representation that can be used with various grid systems.
17
+ */
18
+ export interface BaseLayout {
19
+ /**
20
+ * Item identifier
21
+ */
22
+ i: string;
23
+ /**
24
+ * X position in grid units
25
+ */
26
+ x: number;
27
+ /**
28
+ * Y position in grid units
29
+ */
30
+ y: number;
31
+ /**
32
+ * Width in grid units
33
+ */
34
+ w: number;
35
+ /**
36
+ * Height in grid units
37
+ */
38
+ h: number;
39
+ }
40
+ export interface PanelGroupItemLayout extends BaseLayout {
41
+ i: PanelGroupItemLayoutId;
42
+ }
43
+ /**
44
+ * Definition of a panel group, containing layout and panel information.
45
+ */
46
+ export interface PanelGroupDefinition {
47
+ id: PanelGroupId;
48
+ isCollapsed: boolean;
49
+ title?: string;
50
+ repeatedOriginId?: PanelGroupId;
51
+ repeatVariable?: string;
52
+ itemLayouts: PanelGroupItemLayout[];
53
+ itemPanelKeys: Record<PanelGroupItemLayoutId, string>;
54
+ }
55
+ /**
56
+ * Check if two PanelGroupItemId are equal
57
+ */
58
+ export declare function isPanelGroupItemIdEqual(a?: PanelGroupItemId, b?: PanelGroupItemId): boolean;
59
+ //# sourceMappingURL=PanelGroupDefinition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelGroupDefinition.d.ts","sourceRoot":"","sources":["../../src/model/PanelGroupDefinition.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,YAAY,CAAC;IAC3B,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,CAAC,EAAE,MAAM,CAAC;IACV;;OAEG;IACH,CAAC,EAAE,MAAM,CAAC;IACV;;OAEG;IACH,CAAC,EAAE,MAAM,CAAC;IACV;;OAEG;IACH,CAAC,EAAE,MAAM,CAAC;IACV;;OAEG;IACH,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,CAAC,EAAE,sBAAsB,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,YAAY,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;CACvD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAE3F"}
@@ -0,0 +1,19 @@
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
+ /**
14
+ * Check if two PanelGroupItemId are equal
15
+ */ export function isPanelGroupItemIdEqual(a, b) {
16
+ return a?.panelGroupId === b?.panelGroupId && a?.panelGroupItemLayoutId === b?.panelGroupItemLayoutId;
17
+ }
18
+
19
+ //# sourceMappingURL=PanelGroupDefinition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/model/PanelGroupDefinition.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 type PanelGroupId = number;\n\n/**\n * Panel Group Item Layout ID type. String identifier for items within a panel group.\n */\nexport type PanelGroupItemLayoutId = string;\n\n/**\n * Uniquely identifies an item in a PanelGroup.\n */\nexport interface PanelGroupItemId {\n panelGroupId: PanelGroupId;\n panelGroupItemLayoutId: PanelGroupItemLayoutId;\n repeatVariable?: [string, string]; // Optional, used for repeated panel groups. Variable name and value.\n}\n\n/**\n * Base layout properties for positioning and sizing items in a grid.\n * This is a framework-agnostic representation that can be used with various grid systems.\n */\nexport interface BaseLayout {\n /**\n * Item identifier\n */\n i: string;\n /**\n * X position in grid units\n */\n x: number;\n /**\n * Y position in grid units\n */\n y: number;\n /**\n * Width in grid units\n */\n w: number;\n /**\n * Height in grid units\n */\n h: number;\n}\n\nexport interface PanelGroupItemLayout extends BaseLayout {\n i: PanelGroupItemLayoutId;\n}\n\n/**\n * Definition of a panel group, containing layout and panel information.\n */\nexport interface PanelGroupDefinition {\n id: PanelGroupId;\n isCollapsed: boolean;\n title?: string;\n repeatedOriginId?: PanelGroupId; // ID of the original panel group from which this repeated group is derived\n repeatVariable?: string; // Optional, used for repeated panel groups\n itemLayouts: PanelGroupItemLayout[];\n itemPanelKeys: Record<PanelGroupItemLayoutId, string>;\n}\n\n/**\n * Check if two PanelGroupItemId are equal\n */\nexport function isPanelGroupItemIdEqual(a?: PanelGroupItemId, b?: PanelGroupItemId): boolean {\n return a?.panelGroupId === b?.panelGroupId && a?.panelGroupItemLayoutId === b?.panelGroupItemLayoutId;\n}\n"],"names":["isPanelGroupItemIdEqual","a","b","panelGroupId","panelGroupItemLayoutId"],"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;AA8DjC;;CAEC,GACD,OAAO,SAASA,wBAAwBC,CAAoB,EAAEC,CAAoB;IAChF,OAAOD,GAAGE,iBAAiBD,GAAGC,gBAAgBF,GAAGG,2BAA2BF,GAAGE;AACjF"}
@@ -0,0 +1,50 @@
1
+ import { Definition, UnknownSpec, VariableSpec } from '@perses-dev/spec';
2
+ export type VariableValue = string | string[] | null;
3
+ export interface TextVariableSpec extends VariableSpec {
4
+ value: string;
5
+ constant?: boolean;
6
+ }
7
+ export interface ListVariableSpec<PluginSpec = UnknownSpec> extends VariableSpec {
8
+ defaultValue?: VariableValue;
9
+ allowMultiple: boolean;
10
+ allowAllValue: boolean;
11
+ customAllValue?: string;
12
+ capturingRegexp?: string;
13
+ sort?: string;
14
+ plugin: Definition<PluginSpec>;
15
+ }
16
+ export interface ListVariableDefinition extends Definition<ListVariableSpec> {
17
+ kind: 'ListVariable';
18
+ }
19
+ export interface TextVariableDefinition extends Definition<TextVariableSpec> {
20
+ kind: 'TextVariable';
21
+ }
22
+ export type VariableDefinition = TextVariableDefinition | ListVariableDefinition;
23
+ /**
24
+ * External variable definition that can be provided from an external source.
25
+ * Multiple external variable definitions can be provided to a dashboard, and
26
+ * the order of the sources is important as first one will take precedence on
27
+ * the following ones, in case they have same names.
28
+ */
29
+ export interface ExternalVariableDefinition {
30
+ /**
31
+ * Source identifier for this set of external variables
32
+ */
33
+ source: string;
34
+ /**
35
+ * Optional tooltip information for the external variables
36
+ */
37
+ tooltip?: {
38
+ title?: string;
39
+ description?: string;
40
+ };
41
+ /**
42
+ * Optional link to edit these external variables
43
+ */
44
+ editLink?: string;
45
+ /**
46
+ * The variable definitions from this external source
47
+ */
48
+ definitions: VariableDefinition[];
49
+ }
50
+ //# sourceMappingURL=VariableDefinition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableDefinition.d.ts","sourceRoot":"","sources":["../../src/model/VariableDefinition.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEzE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;AAErD,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB,CAAC,UAAU,GAAG,WAAW,CAAE,SAAQ,YAAY;IAC9E,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,sBAAuB,SAAQ,UAAU,CAAC,gBAAgB,CAAC;IAC1E,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,WAAW,sBAAuB,SAAQ,UAAU,CAAC,gBAAgB,CAAC;IAC1E,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,GAAG,sBAAsB,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,WAAW,EAAE,kBAAkB,EAAE,CAAC;CACnC"}
@@ -0,0 +1,20 @@
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
+ /**
14
+ * External variable definition that can be provided from an external source.
15
+ * Multiple external variable definitions can be provided to a dashboard, and
16
+ * the order of the sources is important as first one will take precedence on
17
+ * the following ones, in case they have same names.
18
+ */ export { };
19
+
20
+ //# sourceMappingURL=VariableDefinition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/model/VariableDefinition.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Definition, UnknownSpec, VariableSpec } from '@perses-dev/spec';\n\nexport type VariableValue = string | string[] | null;\n\nexport interface TextVariableSpec extends VariableSpec {\n value: string;\n constant?: boolean;\n}\n\nexport interface ListVariableSpec<PluginSpec = UnknownSpec> extends VariableSpec {\n defaultValue?: VariableValue;\n allowMultiple: boolean;\n allowAllValue: boolean;\n customAllValue?: string;\n capturingRegexp?: string;\n sort?: string;\n plugin: Definition<PluginSpec>;\n}\n\nexport interface ListVariableDefinition extends Definition<ListVariableSpec> {\n kind: 'ListVariable';\n}\n\nexport interface TextVariableDefinition extends Definition<TextVariableSpec> {\n kind: 'TextVariable';\n}\n\nexport type VariableDefinition = TextVariableDefinition | ListVariableDefinition;\n\n/**\n * External variable definition that can be provided from an external source.\n * Multiple external variable definitions can be provided to a dashboard, and\n * the order of the sources is important as first one will take precedence on\n * the following ones, in case they have same names.\n */\nexport interface ExternalVariableDefinition {\n /**\n * Source identifier for this set of external variables\n */\n source: string;\n /**\n * Optional tooltip information for the external variables\n */\n tooltip?: {\n title?: string;\n description?: string;\n };\n /**\n * Optional link to edit these external variables\n */\n editLink?: string;\n /**\n * The variable definitions from this external source\n */\n definitions: VariableDefinition[];\n}\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;AA+BjC;;;;;CAKC,GACD,WAoBC"}
@@ -1,2 +1,3 @@
1
1
  export * from './DashboardResource';
2
+ export * from './PanelGroupDefinition';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"AAaA,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/model/index.ts"],"names":[],"mappings":"AAaA,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
@@ -11,5 +11,6 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  export * from './DashboardResource';
14
+ export * from './PanelGroupDefinition';
14
15
 
15
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/model/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 './DashboardResource';\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,sBAAsB"}
1
+ {"version":3,"sources":["../../src/model/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 './DashboardResource';\nexport * from './PanelGroupDefinition';\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,sBAAsB;AACpC,cAAc,yBAAyB"}
@@ -1,4 +1,4 @@
1
- import { GlobalDatasourceResource } from '@perses-dev/core';
1
+ import { GlobalDatasourceResource } from '@perses-dev/client';
2
2
  import { DatasourceStoreProviderProps } from '../context';
3
3
  export declare const prometheusDemoUrl = "https://prometheus.demo.prometheus.io";
4
4
  export declare const prometheusDemo: GlobalDatasourceResource;
@@ -1 +1 @@
1
- {"version":3,"file":"datasource-provider.d.ts","sourceRoot":"","sources":["../../src/test/datasource-provider.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAG1D,eAAO,MAAM,iBAAiB,0CAA0C,CAAC;AACzE,eAAO,MAAM,cAAc,EAAE,wBAenB,CAAC;AAKX,eAAO,MAAM,sBAAsB,EAAE,IAAI,CAAC,4BAA4B,EAAE,eAAe,GAAG,mBAAmB,CAqB5G,CAAC"}
1
+ {"version":3,"file":"datasource-provider.d.ts","sourceRoot":"","sources":["../../src/test/datasource-provider.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAG1D,eAAO,MAAM,iBAAiB,0CAA0C,CAAC;AACzE,eAAO,MAAM,cAAc,EAAE,wBAenB,CAAC;AAKX,eAAO,MAAM,sBAAsB,EAAE,IAAI,CAAC,4BAA4B,EAAE,eAAe,GAAG,mBAAmB,CAqB5G,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/test/datasource-provider.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 { GlobalDatasourceResource } from '@perses-dev/core'; // TODO\nimport { DatasourceStoreProviderProps } from '../context';\nimport { getTestDashboard } from './dashboard-provider';\n\nexport const prometheusDemoUrl = 'https://prometheus.demo.prometheus.io';\nexport const prometheusDemo: GlobalDatasourceResource = {\n kind: 'GlobalDatasource',\n metadata: {\n name: 'PrometheusDemo',\n createdAt: '0001-01-01T00:00:00Z',\n updatedAt: '0001-01-01T00:00:00Z',\n version: 0,\n },\n spec: {\n default: true,\n plugin: {\n kind: 'PrometheusDatasource',\n spec: { directUrl: prometheusDemoUrl },\n },\n },\n} as const;\n\n// This default currently defines the bare minimum to get a story working in\n// the `Dashboard` storybook with the Prometheus demo api. We'll likely want\n// to expand it to do more in the future.\nexport const defaultDatasourceProps: Pick<DatasourceStoreProviderProps, 'datasourceApi' | 'dashboardResource'> = {\n dashboardResource: getTestDashboard(),\n datasourceApi: {\n buildProxyUrl: () => '',\n getDatasource: () => {\n return Promise.resolve(undefined);\n },\n getGlobalDatasource: (selector) => {\n if (selector.kind === 'PrometheusDatasource') {\n return Promise.resolve(prometheusDemo);\n }\n\n return Promise.resolve(undefined);\n },\n listDatasources: () => {\n return Promise.resolve([]);\n },\n listGlobalDatasources: () => {\n return Promise.resolve([]);\n },\n },\n};\n"],"names":["getTestDashboard","prometheusDemoUrl","prometheusDemo","kind","metadata","name","createdAt","updatedAt","version","spec","default","plugin","directUrl","defaultDatasourceProps","dashboardResource","datasourceApi","buildProxyUrl","getDatasource","Promise","resolve","undefined","getGlobalDatasource","selector","listDatasources","listGlobalDatasources"],"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;AAIjC,SAASA,gBAAgB,QAAQ,uBAAuB;AAExD,OAAO,MAAMC,oBAAoB,wCAAwC;AACzE,OAAO,MAAMC,iBAA2C;IACtDC,MAAM;IACNC,UAAU;QACRC,MAAM;QACNC,WAAW;QACXC,WAAW;QACXC,SAAS;IACX;IACAC,MAAM;QACJC,SAAS;QACTC,QAAQ;YACNR,MAAM;YACNM,MAAM;gBAAEG,WAAWX;YAAkB;QACvC;IACF;AACF,EAAW;AAEX,4EAA4E;AAC5E,4EAA4E;AAC5E,yCAAyC;AACzC,OAAO,MAAMY,yBAAoG;IAC/GC,mBAAmBd;IACnBe,eAAe;QACbC,eAAe,IAAM;QACrBC,eAAe;YACb,OAAOC,QAAQC,OAAO,CAACC;QACzB;QACAC,qBAAqB,CAACC;YACpB,IAAIA,SAASnB,IAAI,KAAK,wBAAwB;gBAC5C,OAAOe,QAAQC,OAAO,CAACjB;YACzB;YAEA,OAAOgB,QAAQC,OAAO,CAACC;QACzB;QACAG,iBAAiB;YACf,OAAOL,QAAQC,OAAO,CAAC,EAAE;QAC3B;QACAK,uBAAuB;YACrB,OAAON,QAAQC,OAAO,CAAC,EAAE;QAC3B;IACF;AACF,EAAE"}
1
+ {"version":3,"sources":["../../src/test/datasource-provider.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 { GlobalDatasourceResource } from '@perses-dev/client';\nimport { DatasourceStoreProviderProps } from '../context';\nimport { getTestDashboard } from './dashboard-provider';\n\nexport const prometheusDemoUrl = 'https://prometheus.demo.prometheus.io';\nexport const prometheusDemo: GlobalDatasourceResource = {\n kind: 'GlobalDatasource',\n metadata: {\n name: 'PrometheusDemo',\n createdAt: '0001-01-01T00:00:00Z',\n updatedAt: '0001-01-01T00:00:00Z',\n version: 0,\n },\n spec: {\n default: true,\n plugin: {\n kind: 'PrometheusDatasource',\n spec: { directUrl: prometheusDemoUrl },\n },\n },\n} as const;\n\n// This default currently defines the bare minimum to get a story working in\n// the `Dashboard` storybook with the Prometheus demo api. We'll likely want\n// to expand it to do more in the future.\nexport const defaultDatasourceProps: Pick<DatasourceStoreProviderProps, 'datasourceApi' | 'dashboardResource'> = {\n dashboardResource: getTestDashboard(),\n datasourceApi: {\n buildProxyUrl: () => '',\n getDatasource: () => {\n return Promise.resolve(undefined);\n },\n getGlobalDatasource: (selector) => {\n if (selector.kind === 'PrometheusDatasource') {\n return Promise.resolve(prometheusDemo);\n }\n\n return Promise.resolve(undefined);\n },\n listDatasources: () => {\n return Promise.resolve([]);\n },\n listGlobalDatasources: () => {\n return Promise.resolve([]);\n },\n },\n};\n"],"names":["getTestDashboard","prometheusDemoUrl","prometheusDemo","kind","metadata","name","createdAt","updatedAt","version","spec","default","plugin","directUrl","defaultDatasourceProps","dashboardResource","datasourceApi","buildProxyUrl","getDatasource","Promise","resolve","undefined","getGlobalDatasource","selector","listDatasources","listGlobalDatasources"],"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;AAIjC,SAASA,gBAAgB,QAAQ,uBAAuB;AAExD,OAAO,MAAMC,oBAAoB,wCAAwC;AACzE,OAAO,MAAMC,iBAA2C;IACtDC,MAAM;IACNC,UAAU;QACRC,MAAM;QACNC,WAAW;QACXC,WAAW;QACXC,SAAS;IACX;IACAC,MAAM;QACJC,SAAS;QACTC,QAAQ;YACNR,MAAM;YACNM,MAAM;gBAAEG,WAAWX;YAAkB;QACvC;IACF;AACF,EAAW;AAEX,4EAA4E;AAC5E,4EAA4E;AAC5E,yCAAyC;AACzC,OAAO,MAAMY,yBAAoG;IAC/GC,mBAAmBd;IACnBe,eAAe;QACbC,eAAe,IAAM;QACrBC,eAAe;YACb,OAAOC,QAAQC,OAAO,CAACC;QACzB;QACAC,qBAAqB,CAACC;YACpB,IAAIA,SAASnB,IAAI,KAAK,wBAAwB;gBAC5C,OAAOe,QAAQC,OAAO,CAACjB;YACzB;YAEA,OAAOgB,QAAQC,OAAO,CAACC;QACzB;QACAG,iBAAiB;YACf,OAAOL,QAAQC,OAAO,CAAC,EAAE;QAC3B;QACAK,uBAAuB;YACrB,OAAON,QAAQC,OAAO,CAAC,EAAE;QAC3B;IACF;AACF,EAAE"}
@@ -1,3 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  // Copyright The Perses Authors
2
3
  // Licensed under the Apache License, Version 2.0 (the "License");
3
4
  // you may not use this file except in compliance with the License.
@@ -10,7 +11,6 @@
10
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
12
  // See the License for the specific language governing permissions and
12
13
  // limitations under the License.
13
- import { jsx as _jsx } from "react/jsx-runtime";
14
14
  import { ChartsProvider, SnackbarProvider, testChartsTheme } from '@perses-dev/components';
15
15
  import { mockPluginRegistry, PluginRegistry } from '@perses-dev/plugin-system';
16
16
  import { HotkeysProvider } from '@tanstack/react-hotkeys';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/test/render.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 { ChartsProvider, SnackbarProvider, testChartsTheme } from '@perses-dev/components';\nimport { mockPluginRegistry, PluginRegistry } from '@perses-dev/plugin-system';\nimport { HotkeysProvider } from '@tanstack/react-hotkeys';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { render, RenderOptions, RenderResult } from '@testing-library/react';\nimport { createMemoryHistory, MemoryHistory } from 'history';\nimport { ReactElement, useLayoutEffect, useState } from 'react';\nimport { Router } from 'react-router-dom';\nimport { QueryParamProvider } from 'use-query-params';\nimport { ReactRouter6Adapter } from 'use-query-params/adapters/react-router-6';\nimport { DatasourceStoreProvider } from '../context';\nimport { PanelFocusProvider } from '../keyboard-shortcuts';\nimport { defaultDatasourceProps } from '../test';\nimport { MOCK_PLUGINS } from './plugin-registry';\n\ninterface CustomRouterProps {\n history: MemoryHistory;\n children: React.ReactNode;\n}\n\n/*\n * Workaround for React router upgrade type errors.\n * More details: https://stackoverflow.com/a/69948457/17575201\n */\nconst CustomRouter: React.FC<CustomRouterProps> = ({ history, children }) => {\n const [state, setState] = useState({\n action: history.action,\n location: history.location,\n });\n\n useLayoutEffect(() => history.listen(setState), [history]);\n\n return (\n <Router location={state.location} navigationType={state.action} navigator={history}>\n {children}\n </Router>\n );\n};\n\n/**\n * Test helper to render a React component with some common app-level providers wrapped around it.\n */\nexport function renderWithContext(\n ui: React.ReactElement,\n options?: Omit<RenderOptions, 'queries'>,\n history?: MemoryHistory\n): RenderResult {\n // Create a new QueryClient for each test to avoid caching issues\n const queryClient = new QueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: false, retry: false } } });\n\n const customHistory = history ?? createMemoryHistory();\n\n const mockRegistry = mockPluginRegistry(...MOCK_PLUGINS);\n\n const BaseRender = (): ReactElement => (\n <CustomRouter history={customHistory}>\n <QueryClientProvider client={queryClient}>\n <QueryParamProvider adapter={ReactRouter6Adapter}>\n <SnackbarProvider anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}>\n <ChartsProvider chartsTheme={testChartsTheme}>\n <PluginRegistry\n pluginLoader={mockRegistry.pluginLoader}\n defaultPluginKinds={mockRegistry.defaultPluginKinds}\n >\n <HotkeysProvider\n defaultOptions={{\n hotkey: { preventDefault: true, stopPropagation: true },\n hotkeySequence: { timeout: 1000 },\n }}\n >\n <PanelFocusProvider>\n <DatasourceStoreProvider {...defaultDatasourceProps}>{ui}</DatasourceStoreProvider>\n </PanelFocusProvider>\n </HotkeysProvider>\n </PluginRegistry>\n </ChartsProvider>\n </SnackbarProvider>\n </QueryParamProvider>\n </QueryClientProvider>\n </CustomRouter>\n );\n\n return render(<BaseRender />, options);\n}\n"],"names":["ChartsProvider","SnackbarProvider","testChartsTheme","mockPluginRegistry","PluginRegistry","HotkeysProvider","QueryClient","QueryClientProvider","render","createMemoryHistory","useLayoutEffect","useState","Router","QueryParamProvider","ReactRouter6Adapter","DatasourceStoreProvider","PanelFocusProvider","defaultDatasourceProps","MOCK_PLUGINS","CustomRouter","history","children","state","setState","action","location","listen","navigationType","navigator","renderWithContext","ui","options","queryClient","defaultOptions","queries","refetchOnWindowFocus","retry","customHistory","mockRegistry","BaseRender","client","adapter","anchorOrigin","vertical","horizontal","chartsTheme","pluginLoader","defaultPluginKinds","hotkey","preventDefault","stopPropagation","hotkeySequence","timeout"],"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,cAAc,EAAEC,gBAAgB,EAAEC,eAAe,QAAQ,yBAAyB;AAC3F,SAASC,kBAAkB,EAAEC,cAAc,QAAQ,4BAA4B;AAC/E,SAASC,eAAe,QAAQ,0BAA0B;AAC1D,SAASC,WAAW,EAAEC,mBAAmB,QAAQ,wBAAwB;AACzE,SAASC,MAAM,QAAqC,yBAAyB;AAC7E,SAASC,mBAAmB,QAAuB,UAAU;AAC7D,SAAuBC,eAAe,EAAEC,QAAQ,QAAQ,QAAQ;AAChE,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,kBAAkB,QAAQ,mBAAmB;AACtD,SAASC,mBAAmB,QAAQ,2CAA2C;AAC/E,SAASC,uBAAuB,QAAQ,aAAa;AACrD,SAASC,kBAAkB,QAAQ,wBAAwB;AAC3D,SAASC,sBAAsB,QAAQ,UAAU;AACjD,SAASC,YAAY,QAAQ,oBAAoB;AAOjD;;;CAGC,GACD,MAAMC,eAA4C,CAAC,EAAEC,OAAO,EAAEC,QAAQ,EAAE;IACtE,MAAM,CAACC,OAAOC,SAAS,GAAGZ,SAAS;QACjCa,QAAQJ,QAAQI,MAAM;QACtBC,UAAUL,QAAQK,QAAQ;IAC5B;IAEAf,gBAAgB,IAAMU,QAAQM,MAAM,CAACH,WAAW;QAACH;KAAQ;IAEzD,qBACE,KAACR;QAAOa,UAAUH,MAAMG,QAAQ;QAAEE,gBAAgBL,MAAME,MAAM;QAAEI,WAAWR;kBACxEC;;AAGP;AAEA;;CAEC,GACD,OAAO,SAASQ,kBACdC,EAAsB,EACtBC,OAAwC,EACxCX,OAAuB;IAEvB,iEAAiE;IACjE,MAAMY,cAAc,IAAI1B,YAAY;QAAE2B,gBAAgB;YAAEC,SAAS;gBAAEC,sBAAsB;gBAAOC,OAAO;YAAM;QAAE;IAAE;IAEjH,MAAMC,gBAAgBjB,WAAWX;IAEjC,MAAM6B,eAAenC,sBAAsBe;IAE3C,MAAMqB,aAAa,kBACjB,KAACpB;YAAaC,SAASiB;sBACrB,cAAA,KAAC9B;gBAAoBiC,QAAQR;0BAC3B,cAAA,KAACnB;oBAAmB4B,SAAS3B;8BAC3B,cAAA,KAACb;wBAAiByC,cAAc;4BAAEC,UAAU;4BAAUC,YAAY;wBAAQ;kCACxE,cAAA,KAAC5C;4BAAe6C,aAAa3C;sCAC3B,cAAA,KAACE;gCACC0C,cAAcR,aAAaQ,YAAY;gCACvCC,oBAAoBT,aAAaS,kBAAkB;0CAEnD,cAAA,KAAC1C;oCACC4B,gBAAgB;wCACde,QAAQ;4CAAEC,gBAAgB;4CAAMC,iBAAiB;wCAAK;wCACtDC,gBAAgB;4CAAEC,SAAS;wCAAK;oCAClC;8CAEA,cAAA,KAACpC;kDACC,cAAA,KAACD;4CAAyB,GAAGE,sBAAsB;sDAAGa;;;;;;;;;;IAWxE,OAAOtB,qBAAO,KAAC+B,iBAAeR;AAChC"}
1
+ {"version":3,"sources":["../../src/test/render.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 { ChartsProvider, SnackbarProvider, testChartsTheme } from '@perses-dev/components';\nimport { mockPluginRegistry, PluginRegistry } from '@perses-dev/plugin-system';\nimport { HotkeysProvider } from '@tanstack/react-hotkeys';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { render, RenderOptions, RenderResult } from '@testing-library/react';\nimport { createMemoryHistory, MemoryHistory } from 'history';\nimport { ReactElement, useLayoutEffect, useState } from 'react';\nimport { Router } from 'react-router-dom';\nimport { QueryParamProvider } from 'use-query-params';\nimport { ReactRouter6Adapter } from 'use-query-params/adapters/react-router-6';\nimport { DatasourceStoreProvider } from '../context';\nimport { PanelFocusProvider } from '../keyboard-shortcuts';\nimport { defaultDatasourceProps } from '../test';\nimport { MOCK_PLUGINS } from './plugin-registry';\n\ninterface CustomRouterProps {\n history: MemoryHistory;\n children: React.ReactNode;\n}\n\n/*\n * Workaround for React router upgrade type errors.\n * More details: https://stackoverflow.com/a/69948457/17575201\n */\nconst CustomRouter: React.FC<CustomRouterProps> = ({ history, children }) => {\n const [state, setState] = useState({\n action: history.action,\n location: history.location,\n });\n\n useLayoutEffect(() => history.listen(setState), [history]);\n\n return (\n <Router location={state.location} navigationType={state.action} navigator={history}>\n {children}\n </Router>\n );\n};\n\n/**\n * Test helper to render a React component with some common app-level providers wrapped around it.\n */\nexport function renderWithContext(\n ui: React.ReactElement,\n options?: Omit<RenderOptions, 'queries'>,\n history?: MemoryHistory\n): RenderResult {\n // Create a new QueryClient for each test to avoid caching issues\n const queryClient = new QueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: false, retry: false } } });\n\n const customHistory = history ?? createMemoryHistory();\n\n const mockRegistry = mockPluginRegistry(...MOCK_PLUGINS);\n\n const BaseRender = (): ReactElement => (\n <CustomRouter history={customHistory}>\n <QueryClientProvider client={queryClient}>\n <QueryParamProvider adapter={ReactRouter6Adapter}>\n <SnackbarProvider anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}>\n <ChartsProvider chartsTheme={testChartsTheme}>\n <PluginRegistry\n pluginLoader={mockRegistry.pluginLoader}\n defaultPluginKinds={mockRegistry.defaultPluginKinds}\n >\n <HotkeysProvider\n defaultOptions={{\n hotkey: { preventDefault: true, stopPropagation: true },\n hotkeySequence: { timeout: 1000 },\n }}\n >\n <PanelFocusProvider>\n <DatasourceStoreProvider {...defaultDatasourceProps}>{ui}</DatasourceStoreProvider>\n </PanelFocusProvider>\n </HotkeysProvider>\n </PluginRegistry>\n </ChartsProvider>\n </SnackbarProvider>\n </QueryParamProvider>\n </QueryClientProvider>\n </CustomRouter>\n );\n\n return render(<BaseRender />, options);\n}\n"],"names":["ChartsProvider","SnackbarProvider","testChartsTheme","mockPluginRegistry","PluginRegistry","HotkeysProvider","QueryClient","QueryClientProvider","render","createMemoryHistory","useLayoutEffect","useState","Router","QueryParamProvider","ReactRouter6Adapter","DatasourceStoreProvider","PanelFocusProvider","defaultDatasourceProps","MOCK_PLUGINS","CustomRouter","history","children","state","setState","action","location","listen","navigationType","navigator","renderWithContext","ui","options","queryClient","defaultOptions","queries","refetchOnWindowFocus","retry","customHistory","mockRegistry","BaseRender","client","adapter","anchorOrigin","vertical","horizontal","chartsTheme","pluginLoader","defaultPluginKinds","hotkey","preventDefault","stopPropagation","hotkeySequence","timeout"],"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,cAAc,EAAEC,gBAAgB,EAAEC,eAAe,QAAQ,yBAAyB;AAC3F,SAASC,kBAAkB,EAAEC,cAAc,QAAQ,4BAA4B;AAC/E,SAASC,eAAe,QAAQ,0BAA0B;AAC1D,SAASC,WAAW,EAAEC,mBAAmB,QAAQ,wBAAwB;AACzE,SAASC,MAAM,QAAqC,yBAAyB;AAC7E,SAASC,mBAAmB,QAAuB,UAAU;AAC7D,SAAuBC,eAAe,EAAEC,QAAQ,QAAQ,QAAQ;AAChE,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,kBAAkB,QAAQ,mBAAmB;AACtD,SAASC,mBAAmB,QAAQ,2CAA2C;AAC/E,SAASC,uBAAuB,QAAQ,aAAa;AACrD,SAASC,kBAAkB,QAAQ,wBAAwB;AAC3D,SAASC,sBAAsB,QAAQ,UAAU;AACjD,SAASC,YAAY,QAAQ,oBAAoB;AAOjD;;;CAGC,GACD,MAAMC,eAA4C,CAAC,EAAEC,OAAO,EAAEC,QAAQ,EAAE;IACtE,MAAM,CAACC,OAAOC,SAAS,GAAGZ,SAAS;QACjCa,QAAQJ,QAAQI,MAAM;QACtBC,UAAUL,QAAQK,QAAQ;IAC5B;IAEAf,gBAAgB,IAAMU,QAAQM,MAAM,CAACH,WAAW;QAACH;KAAQ;IAEzD,qBACE,KAACR;QAAOa,UAAUH,MAAMG,QAAQ;QAAEE,gBAAgBL,MAAME,MAAM;QAAEI,WAAWR;kBACxEC;;AAGP;AAEA;;CAEC,GACD,OAAO,SAASQ,kBACdC,EAAsB,EACtBC,OAAwC,EACxCX,OAAuB;IAEvB,iEAAiE;IACjE,MAAMY,cAAc,IAAI1B,YAAY;QAAE2B,gBAAgB;YAAEC,SAAS;gBAAEC,sBAAsB;gBAAOC,OAAO;YAAM;QAAE;IAAE;IAEjH,MAAMC,gBAAgBjB,WAAWX;IAEjC,MAAM6B,eAAenC,sBAAsBe;IAE3C,MAAMqB,aAAa,kBACjB,KAACpB;YAAaC,SAASiB;sBACrB,cAAA,KAAC9B;gBAAoBiC,QAAQR;0BAC3B,cAAA,KAACnB;oBAAmB4B,SAAS3B;8BAC3B,cAAA,KAACb;wBAAiByC,cAAc;4BAAEC,UAAU;4BAAUC,YAAY;wBAAQ;kCACxE,cAAA,KAAC5C;4BAAe6C,aAAa3C;sCAC3B,cAAA,KAACE;gCACC0C,cAAcR,aAAaQ,YAAY;gCACvCC,oBAAoBT,aAAaS,kBAAkB;0CAEnD,cAAA,KAAC1C;oCACC4B,gBAAgB;wCACde,QAAQ;4CAAEC,gBAAgB;4CAAMC,iBAAiB;wCAAK;wCACtDC,gBAAgB;4CAAEC,SAAS;wCAAK;oCAClC;8CAEA,cAAA,KAACpC;kDACC,cAAA,KAACD;4CAAyB,GAAGE,sBAAsB;sDAAGa;;;;;;;;;;IAWxE,OAAOtB,qBAAO,KAAC+B,iBAAeR;AAChC"}
@@ -1,4 +1,4 @@
1
- import { PanelGroupDefinition, PanelGroupItemLayout } from '@perses-dev/core';
1
+ import { PanelGroupDefinition, PanelGroupItemLayout } from '../model';
2
2
  export declare function getYForNewRow(group: PanelGroupDefinition): number;
3
3
  export type UnpositionedPanelGroupItemLayout = Omit<PanelGroupItemLayout, 'x' | 'y'>;
4
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"panelUtils.d.ts","sourceRoot":"","sources":["../../src/utils/panelUtils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAI9E,wBAAgB,aAAa,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CASjE;AA8BD,MAAM,MAAM,gCAAgC,GAAG,IAAI,CAAC,oBAAoB,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;AAErF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,gCAAgC,EAC3C,eAAe,EAAE,oBAAoB,EACrC,WAAW,EAAE,oBAAoB,EAAE,GAClC,oBAAoB,EAAE,CAyExB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAO,MAQnC,CAAC"}
1
+ {"version":3,"file":"panelUtils.d.ts","sourceRoot":"","sources":["../../src/utils/panelUtils.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAGtE,wBAAgB,aAAa,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CASjE;AA8BD,MAAM,MAAM,gCAAgC,GAAG,IAAI,CAAC,oBAAoB,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;AAErF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,gCAAgC,EAC3C,eAAe,EAAE,oBAAoB,EACrC,WAAW,EAAE,oBAAoB,EAAE,GAClC,oBAAoB,EAAE,CAyExB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAO,MAQnC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/panelUtils.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { PanelGroupDefinition, PanelGroupItemLayout } from '@perses-dev/core'; // TODO\nimport { GRID_LAYOUT_SMALL_BREAKPOINT, GRID_LAYOUT_COLS } from '../constants';\n\n// Given a PanelGroup, will find the Y coordinate for adding a new row to the grid, taking into account the items present\nexport function getYForNewRow(group: PanelGroupDefinition): number {\n let newRowY = 0;\n for (const layout of group.itemLayouts) {\n const itemMaxY = layout.y + layout.h;\n if (itemMaxY > newRowY) {\n newRowY = itemMaxY;\n }\n }\n return newRowY;\n}\n\ntype PanelGroupItemBounds = {\n /**\n * Left horizontal position.\n */\n x1: number;\n /**\n * Right horizontal position.\n */\n x2: number;\n /**\n * Top vertical position.\n */\n y1: number;\n /**\n * Bottom vertical position\n */\n y2: number;\n};\n\nfunction getPanelBounds({ x, y, w, h }: PanelGroupItemLayout): PanelGroupItemBounds {\n return {\n x1: x,\n x2: x + w,\n y1: y,\n y2: y + h,\n };\n}\n\nexport type UnpositionedPanelGroupItemLayout = Omit<PanelGroupItemLayout, 'x' | 'y'>;\n\n/**\n * Inserts a new panel into the layout with placement determined by a specified\n * reference panel. The new panel is placed:\n * - To the right of the reference panel if there is space available without\n * moving other panels.\n * - Otherwise, directly below the reference panel. If other panels are below\n * this location, they will also shift downward because the grid uses\n * vertical-based compacting.\n *\n * @param newLayout - Layout for new panel to insert into the grid.\n * @param referenceLayout - Layout for reference panel used to determine the\n * placement of the new panel.\n * @param itemLayouts - Full grid layout.\n * @returns - Item layouts modified to insert the new panel.\n */\nexport function insertPanelInLayout(\n newLayout: UnpositionedPanelGroupItemLayout,\n referenceLayout: PanelGroupItemLayout,\n itemLayouts: PanelGroupItemLayout[]\n): PanelGroupItemLayout[] {\n const MAX_LAYOUT_WIDTH = GRID_LAYOUT_COLS[GRID_LAYOUT_SMALL_BREAKPOINT];\n\n const referenceBounds = getPanelBounds(referenceLayout);\n\n // Organize layouts based on vertical relation to the item being inserted\n // after.\n const aboveInsertRow: PanelGroupItemLayout[] = [];\n const insertRow: PanelGroupItemLayout[] = [];\n const belowInsertRow: PanelGroupItemLayout[] = [];\n itemLayouts.forEach((itemLayout) => {\n const itemBounds = getPanelBounds(itemLayout);\n\n if (itemBounds.y2 <= referenceBounds.y1) {\n aboveInsertRow.push(itemLayout);\n } else if (itemBounds.y1 >= referenceBounds.y2) {\n belowInsertRow.push(itemLayout);\n } else {\n insertRow.push(itemLayout);\n }\n });\n\n // Cannot safely assume that the order of item layouts array is strictly\n // left to right. Sorting the row by horizontal position to more easily find\n // gaps.\n insertRow.sort((a, b) => a.x - b.x);\n const insertAfterIndex = insertRow.findIndex((item) => item.i === referenceLayout.i);\n\n if (insertAfterIndex === insertRow.length - 1) {\n // Insert to the right when space is available and the reference is the last\n // item in the row.\n if (referenceBounds.x2 + newLayout.w <= MAX_LAYOUT_WIDTH) {\n return [\n ...aboveInsertRow,\n ...insertRow,\n {\n ...newLayout,\n x: referenceBounds.x2,\n y: referenceBounds.y1,\n },\n ...belowInsertRow,\n ];\n }\n } else if (insertAfterIndex >= 0) {\n const nextItem = insertRow[insertAfterIndex + 1];\n\n if (nextItem && getPanelBounds(nextItem).x1 - referenceBounds.x2 >= newLayout.w) {\n // Insert to the right when space is available between the reference and\n // the next item in the row.\n insertRow.splice(insertAfterIndex + 1, 0, {\n ...newLayout,\n x: referenceBounds.x2,\n y: referenceBounds.y1,\n });\n\n return [...aboveInsertRow, ...insertRow, ...belowInsertRow];\n }\n }\n\n // Insert the new item below the original and shift the items below the\n // row where the reference is located.\n return [\n ...aboveInsertRow,\n ...insertRow,\n { x: referenceBounds.x1, y: referenceBounds.y2, ...newLayout },\n ...belowInsertRow.map((itemLayout) => {\n // Note: the grid will not necessarily display all of these items shifted\n // all the way down because of vertical compacting, but shifing their\n // y position ensures the new item gets vertical precedence over items\n // below it in that compacting.\n return { ...itemLayout, y: itemLayout.y + newLayout.h };\n }),\n ];\n}\n\n/**\n * This function generates a unique panel key based on UUID or timestamp and random suffix.\n */\nexport const generatePanelKey = (): string => {\n /* crypto.randomUUID() is only available in secure contexts (HTTPS), */\n if (window.isSecureContext) {\n return crypto.randomUUID().replaceAll('-', '');\n }\n const timestamp = String(Date.now());\n const randomSuffix = Math.random().toString(36).substring(2);\n return `${timestamp}${randomSuffix}`;\n};\n"],"names":["GRID_LAYOUT_SMALL_BREAKPOINT","GRID_LAYOUT_COLS","getYForNewRow","group","newRowY","layout","itemLayouts","itemMaxY","y","h","getPanelBounds","x","w","x1","x2","y1","y2","insertPanelInLayout","newLayout","referenceLayout","MAX_LAYOUT_WIDTH","referenceBounds","aboveInsertRow","insertRow","belowInsertRow","forEach","itemLayout","itemBounds","push","sort","a","b","insertAfterIndex","findIndex","item","i","length","nextItem","splice","map","generatePanelKey","window","isSecureContext","crypto","randomUUID","replaceAll","timestamp","String","Date","now","randomSuffix","Math","random","toString","substring"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/utils/panelUtils.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { GRID_LAYOUT_SMALL_BREAKPOINT, GRID_LAYOUT_COLS } from '../constants';\nimport { PanelGroupDefinition, PanelGroupItemLayout } from '../model';\n\n// Given a PanelGroup, will find the Y coordinate for adding a new row to the grid, taking into account the items present\nexport function getYForNewRow(group: PanelGroupDefinition): number {\n let newRowY = 0;\n for (const layout of group.itemLayouts) {\n const itemMaxY = layout.y + layout.h;\n if (itemMaxY > newRowY) {\n newRowY = itemMaxY;\n }\n }\n return newRowY;\n}\n\ntype PanelGroupItemBounds = {\n /**\n * Left horizontal position.\n */\n x1: number;\n /**\n * Right horizontal position.\n */\n x2: number;\n /**\n * Top vertical position.\n */\n y1: number;\n /**\n * Bottom vertical position\n */\n y2: number;\n};\n\nfunction getPanelBounds({ x, y, w, h }: PanelGroupItemLayout): PanelGroupItemBounds {\n return {\n x1: x,\n x2: x + w,\n y1: y,\n y2: y + h,\n };\n}\n\nexport type UnpositionedPanelGroupItemLayout = Omit<PanelGroupItemLayout, 'x' | 'y'>;\n\n/**\n * Inserts a new panel into the layout with placement determined by a specified\n * reference panel. The new panel is placed:\n * - To the right of the reference panel if there is space available without\n * moving other panels.\n * - Otherwise, directly below the reference panel. If other panels are below\n * this location, they will also shift downward because the grid uses\n * vertical-based compacting.\n *\n * @param newLayout - Layout for new panel to insert into the grid.\n * @param referenceLayout - Layout for reference panel used to determine the\n * placement of the new panel.\n * @param itemLayouts - Full grid layout.\n * @returns - Item layouts modified to insert the new panel.\n */\nexport function insertPanelInLayout(\n newLayout: UnpositionedPanelGroupItemLayout,\n referenceLayout: PanelGroupItemLayout,\n itemLayouts: PanelGroupItemLayout[]\n): PanelGroupItemLayout[] {\n const MAX_LAYOUT_WIDTH = GRID_LAYOUT_COLS[GRID_LAYOUT_SMALL_BREAKPOINT];\n\n const referenceBounds = getPanelBounds(referenceLayout);\n\n // Organize layouts based on vertical relation to the item being inserted\n // after.\n const aboveInsertRow: PanelGroupItemLayout[] = [];\n const insertRow: PanelGroupItemLayout[] = [];\n const belowInsertRow: PanelGroupItemLayout[] = [];\n itemLayouts.forEach((itemLayout) => {\n const itemBounds = getPanelBounds(itemLayout);\n\n if (itemBounds.y2 <= referenceBounds.y1) {\n aboveInsertRow.push(itemLayout);\n } else if (itemBounds.y1 >= referenceBounds.y2) {\n belowInsertRow.push(itemLayout);\n } else {\n insertRow.push(itemLayout);\n }\n });\n\n // Cannot safely assume that the order of item layouts array is strictly\n // left to right. Sorting the row by horizontal position to more easily find\n // gaps.\n insertRow.sort((a, b) => a.x - b.x);\n const insertAfterIndex = insertRow.findIndex((item) => item.i === referenceLayout.i);\n\n if (insertAfterIndex === insertRow.length - 1) {\n // Insert to the right when space is available and the reference is the last\n // item in the row.\n if (referenceBounds.x2 + newLayout.w <= MAX_LAYOUT_WIDTH) {\n return [\n ...aboveInsertRow,\n ...insertRow,\n {\n ...newLayout,\n x: referenceBounds.x2,\n y: referenceBounds.y1,\n },\n ...belowInsertRow,\n ];\n }\n } else if (insertAfterIndex >= 0) {\n const nextItem = insertRow[insertAfterIndex + 1];\n\n if (nextItem && getPanelBounds(nextItem).x1 - referenceBounds.x2 >= newLayout.w) {\n // Insert to the right when space is available between the reference and\n // the next item in the row.\n insertRow.splice(insertAfterIndex + 1, 0, {\n ...newLayout,\n x: referenceBounds.x2,\n y: referenceBounds.y1,\n });\n\n return [...aboveInsertRow, ...insertRow, ...belowInsertRow];\n }\n }\n\n // Insert the new item below the original and shift the items below the\n // row where the reference is located.\n return [\n ...aboveInsertRow,\n ...insertRow,\n { x: referenceBounds.x1, y: referenceBounds.y2, ...newLayout },\n ...belowInsertRow.map((itemLayout) => {\n // Note: the grid will not necessarily display all of these items shifted\n // all the way down because of vertical compacting, but shifing their\n // y position ensures the new item gets vertical precedence over items\n // below it in that compacting.\n return { ...itemLayout, y: itemLayout.y + newLayout.h };\n }),\n ];\n}\n\n/**\n * This function generates a unique panel key based on UUID or timestamp and random suffix.\n */\nexport const generatePanelKey = (): string => {\n /* crypto.randomUUID() is only available in secure contexts (HTTPS), */\n if (window.isSecureContext) {\n return crypto.randomUUID().replaceAll('-', '');\n }\n const timestamp = String(Date.now());\n const randomSuffix = Math.random().toString(36).substring(2);\n return `${timestamp}${randomSuffix}`;\n};\n"],"names":["GRID_LAYOUT_SMALL_BREAKPOINT","GRID_LAYOUT_COLS","getYForNewRow","group","newRowY","layout","itemLayouts","itemMaxY","y","h","getPanelBounds","x","w","x1","x2","y1","y2","insertPanelInLayout","newLayout","referenceLayout","MAX_LAYOUT_WIDTH","referenceBounds","aboveInsertRow","insertRow","belowInsertRow","forEach","itemLayout","itemBounds","push","sort","a","b","insertAfterIndex","findIndex","item","i","length","nextItem","splice","map","generatePanelKey","window","isSecureContext","crypto","randomUUID","replaceAll","timestamp","String","Date","now","randomSuffix","Math","random","toString","substring"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
2
  // Copyright The Perses Authors
2
3
  // Licensed under the Apache License, Version 2.0 (the "License");
3
4
  // you may not use this file except in compliance with the License.
@@ -10,7 +11,6 @@
10
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
12
  // See the License for the specific language governing permissions and
12
13
  // limitations under the License.
13
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import { useState } from 'react';
15
15
  import { Box } from '@mui/material';
16
16
  import { ChartsProvider, ErrorAlert, ErrorBoundary, useChartsTheme } from '@perses-dev/components';