@perses-dev/dashboards 0.52.0-rc.1 → 0.53.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/cjs/components/DashboardStickyToolbar/DashboardStickyToolbar.js +0 -2
  2. package/dist/cjs/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +5 -20
  3. package/dist/cjs/components/GridLayout/GridItemContent.js +6 -64
  4. package/dist/cjs/components/LeaveDialog/LeaveDialog.js +10 -1
  5. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +186 -183
  6. package/dist/cjs/components/PanelDrawer/PanelPreview.js +3 -0
  7. package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.js +6 -21
  8. package/dist/cjs/components/QueryViewerDialog/QueryViewerDialog.js +121 -0
  9. package/dist/cjs/components/QueryViewerDialog/index.js +30 -0
  10. package/dist/cjs/components/Variables/ListVariableListBox.js +201 -0
  11. package/dist/cjs/components/Variables/Variable.js +130 -72
  12. package/dist/cjs/components/Variables/index.js +1 -0
  13. package/dist/cjs/components/index.js +2 -1
  14. package/dist/cjs/context/DashboardProvider/DashboardProviderWithQueryParams.js +5 -27
  15. package/dist/cjs/context/DashboardProvider/duplicate-panel-slice.js +1 -1
  16. package/dist/cjs/context/DashboardProvider/panel-editor-slice.js +1 -2
  17. package/dist/cjs/context/PanelEditorProvider/PanelEditorProvider.js +49 -0
  18. package/dist/cjs/context/PanelEditorProvider/index.js +23 -0
  19. package/dist/cjs/context/VariableProvider/query-params.js +14 -12
  20. package/dist/cjs/context/index.js +1 -0
  21. package/dist/cjs/test/render.js +8 -6
  22. package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.d.ts.map +1 -1
  23. package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.js +0 -2
  24. package/dist/components/DashboardStickyToolbar/DashboardStickyToolbar.js.map +1 -1
  25. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.d.ts.map +1 -1
  26. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +5 -15
  27. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
  28. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  29. package/dist/components/GridLayout/GridItemContent.js +8 -66
  30. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  31. package/dist/components/LeaveDialog/LeaveDialog.d.ts +2 -1
  32. package/dist/components/LeaveDialog/LeaveDialog.d.ts.map +1 -1
  33. package/dist/components/LeaveDialog/LeaveDialog.js +10 -1
  34. package/dist/components/LeaveDialog/LeaveDialog.js.map +1 -1
  35. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  36. package/dist/components/PanelDrawer/PanelEditorForm.js +186 -183
  37. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  38. package/dist/components/PanelDrawer/PanelPreview.d.ts.map +1 -1
  39. package/dist/components/PanelDrawer/PanelPreview.js +4 -1
  40. package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
  41. package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts.map +1 -1
  42. package/dist/components/PanelGroupDialog/PanelGroupDialog.js +5 -15
  43. package/dist/components/PanelGroupDialog/PanelGroupDialog.js.map +1 -1
  44. package/dist/components/QueryViewerDialog/QueryViewerDialog.d.ts +9 -0
  45. package/dist/components/QueryViewerDialog/QueryViewerDialog.d.ts.map +1 -0
  46. package/dist/components/QueryViewerDialog/QueryViewerDialog.js +72 -0
  47. package/dist/components/QueryViewerDialog/QueryViewerDialog.js.map +1 -0
  48. package/dist/components/QueryViewerDialog/index.d.ts +2 -0
  49. package/dist/components/QueryViewerDialog/index.d.ts.map +1 -0
  50. package/dist/components/QueryViewerDialog/index.js +15 -0
  51. package/dist/components/QueryViewerDialog/index.js.map +1 -0
  52. package/dist/components/Variables/ListVariableListBox.d.ts +16 -0
  53. package/dist/components/Variables/ListVariableListBox.d.ts.map +1 -0
  54. package/dist/components/Variables/ListVariableListBox.js +141 -0
  55. package/dist/components/Variables/ListVariableListBox.js.map +1 -0
  56. package/dist/components/Variables/Variable.d.ts.map +1 -1
  57. package/dist/components/Variables/Variable.js +134 -76
  58. package/dist/components/Variables/Variable.js.map +1 -1
  59. package/dist/components/Variables/index.d.ts +1 -0
  60. package/dist/components/Variables/index.d.ts.map +1 -1
  61. package/dist/components/Variables/index.js +1 -0
  62. package/dist/components/Variables/index.js.map +1 -1
  63. package/dist/components/index.d.ts +2 -1
  64. package/dist/components/index.d.ts.map +1 -1
  65. package/dist/components/index.js +2 -1
  66. package/dist/components/index.js.map +1 -1
  67. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.d.ts.map +1 -1
  68. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.js +5 -27
  69. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.js.map +1 -1
  70. package/dist/context/DashboardProvider/duplicate-panel-slice.js +2 -2
  71. package/dist/context/DashboardProvider/duplicate-panel-slice.js.map +1 -1
  72. package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -1
  73. package/dist/context/DashboardProvider/panel-editor-slice.js +2 -3
  74. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  75. package/dist/context/PanelEditorProvider/PanelEditorProvider.d.ts +13 -0
  76. package/dist/context/PanelEditorProvider/PanelEditorProvider.d.ts.map +1 -0
  77. package/dist/context/PanelEditorProvider/PanelEditorProvider.js +33 -0
  78. package/dist/context/PanelEditorProvider/PanelEditorProvider.js.map +1 -0
  79. package/dist/context/PanelEditorProvider/index.d.ts +3 -0
  80. package/dist/context/PanelEditorProvider/index.d.ts.map +1 -0
  81. package/dist/context/PanelEditorProvider/index.js +16 -0
  82. package/dist/context/PanelEditorProvider/index.js.map +1 -0
  83. package/dist/context/VariableProvider/query-params.d.ts +3 -4
  84. package/dist/context/VariableProvider/query-params.d.ts.map +1 -1
  85. package/dist/context/VariableProvider/query-params.js +14 -9
  86. package/dist/context/VariableProvider/query-params.js.map +1 -1
  87. package/dist/context/index.d.ts +1 -0
  88. package/dist/context/index.d.ts.map +1 -1
  89. package/dist/context/index.js +1 -0
  90. package/dist/context/index.js.map +1 -1
  91. package/dist/test/render.d.ts.map +1 -1
  92. package/dist/test/render.js +8 -6
  93. package/dist/test/render.js.map +1 -1
  94. package/dist/utils/panelUtils.d.ts +3 -0
  95. package/dist/utils/panelUtils.d.ts.map +1 -1
  96. package/dist/utils/panelUtils.js +3 -0
  97. package/dist/utils/panelUtils.js.map +1 -1
  98. package/package.json +6 -6
@@ -1,4 +1,4 @@
1
- // Copyright 2024 The Perses Authors
1
+ // Copyright 2025 The Perses Authors
2
2
  // Licensed under the Apache License, Version 2.0 (the "License");
3
3
  // you may not use this file except in compliance with the License.
4
4
  // You may obtain a copy of the License at
@@ -21,37 +21,15 @@ Object.defineProperty(exports, "DashboardProviderWithQueryParams", {
21
21
  }
22
22
  });
23
23
  const _jsxruntime = require("react/jsx-runtime");
24
- const _zod = require("zod");
25
- const _react = require("react");
26
- const _nuqs = require("nuqs");
24
+ const _usequeryparams = require("use-query-params");
27
25
  const _DashboardProvider = require("./DashboardProvider");
28
26
  function DashboardProviderWithQueryParams({ children, initialState }) {
29
- const [viewPanelRef, setViewPanelRef] = (0, _nuqs.useQueryState)('viewPanelRef', (0, _nuqs.parseAsJson)(_zod.z.object({
30
- ref: _zod.z.string(),
31
- repeatVariable: _zod.z.tuple([
32
- _zod.z.string(),
33
- _zod.z.string()
34
- ]).optional()
35
- }).optional()));
36
- // nuqs returns null when the query param is not present, but our state expects undefined when not present
37
- const viewPanelRefNotNull = (0, _react.useMemo)(()=>{
38
- return viewPanelRef ?? undefined;
39
- }, [
40
- viewPanelRef
41
- ]);
42
- const handleSetViewPanelRef = (0, _react.useCallback)((panelRef)=>{
43
- if (panelRef) {
44
- return setViewPanelRef(panelRef);
45
- }
46
- return setViewPanelRef(null);
47
- }, [
48
- setViewPanelRef
49
- ]);
27
+ const [viewPanelRef, setViewPanelRef] = (0, _usequeryparams.useQueryParam)('viewPanelRef', _usequeryparams.JsonParam);
50
28
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_DashboardProvider.DashboardProvider, {
51
29
  initialState: {
52
30
  ...initialState,
53
- viewPanelRef: viewPanelRefNotNull,
54
- setViewPanelRef: handleSetViewPanelRef
31
+ viewPanelRef: viewPanelRef ?? undefined,
32
+ setViewPanelRef: setViewPanelRef
55
33
  },
56
34
  children: children
57
35
  });
@@ -49,7 +49,7 @@ function createDuplicatePanelSlice() {
49
49
  if (matchingLayout === undefined) {
50
50
  throw new Error(`Cannot find layout for Panel with key '${panelKey}'`);
51
51
  }
52
- const dupePanelKey = (0, _panelUtils.getValidPanelKey)(panelKey, panels);
52
+ const dupePanelKey = crypto.randomUUID().replaceAll('-', '');
53
53
  state.panels[dupePanelKey] = panelToDupe;
54
54
  const duplicateLayout = {
55
55
  i: (0, _common.generateId)().toString(),
@@ -110,8 +110,7 @@ function createPanelEditorSlice() {
110
110
  panelDefinition: get().initialValues?.panelDefinition ?? (0, _common.createPanelDefinition)()
111
111
  },
112
112
  applyChanges: (next)=>{
113
- const name = next.panelDefinition.spec.display.name;
114
- const panelKey = (0, _utils.getValidPanelKey)(name, get().panels);
113
+ const panelKey = crypto.randomUUID().replaceAll('-', '');
115
114
  set((state)=>{
116
115
  // Add a panel
117
116
  state.panels[panelKey] = next.panelDefinition;
@@ -0,0 +1,49 @@
1
+ // Copyright 2025 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
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ function _export(target, all) {
18
+ for(var name in all)Object.defineProperty(target, name, {
19
+ enumerable: true,
20
+ get: all[name]
21
+ });
22
+ }
23
+ _export(exports, {
24
+ PanelEditorContext: function() {
25
+ return PanelEditorContext;
26
+ },
27
+ PanelEditorProvider: function() {
28
+ return PanelEditorProvider;
29
+ }
30
+ });
31
+ const _jsxruntime = require("react/jsx-runtime");
32
+ const _react = require("react");
33
+ const PanelEditorContext = /*#__PURE__*/ (0, _react.createContext)(undefined);
34
+ const PanelEditorProvider = ({ children })=>{
35
+ const [previewPanelWidth, setPreviewPanelWidth] = (0, _react.useState)(undefined);
36
+ const ctx = (0, _react.useMemo)(()=>({
37
+ preview: {
38
+ previewPanelWidth,
39
+ setPreviewPanelWidth
40
+ }
41
+ }), [
42
+ previewPanelWidth,
43
+ setPreviewPanelWidth
44
+ ]);
45
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(PanelEditorContext.Provider, {
46
+ value: ctx,
47
+ children: children
48
+ });
49
+ };
@@ -0,0 +1,23 @@
1
+ // Copyright 2025 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
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "PanelEditorContext", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return _PanelEditorProvider.PanelEditorContext;
21
+ }
22
+ });
23
+ const _PanelEditorProvider = require("./PanelEditorProvider");
@@ -33,14 +33,11 @@ _export(exports, {
33
33
  getURLQueryParamName: function() {
34
34
  return getURLQueryParamName;
35
35
  },
36
- parseAsVariableValue: function() {
37
- return parseAsVariableValue;
38
- },
39
36
  useVariableQueryParams: function() {
40
37
  return useVariableQueryParams;
41
38
  }
42
39
  });
43
- const _nuqs = require("nuqs");
40
+ const _usequeryparams = require("use-query-params");
44
41
  const variableQueryParameterPrefix = 'var-';
45
42
  function getURLQueryParamName(name) {
46
43
  return `${variableQueryParameterPrefix}${name}`;
@@ -49,7 +46,7 @@ function encodeVariableValue(value) {
49
46
  if (Array.isArray(value)) {
50
47
  return value.join(',');
51
48
  }
52
- return value ?? '';
49
+ return value;
53
50
  }
54
51
  function decodeVariableValue(value) {
55
52
  if (!value) {
@@ -61,18 +58,23 @@ function decodeVariableValue(value) {
61
58
  }
62
59
  return values;
63
60
  }
64
- const parseAsVariableValue = (0, _nuqs.createParser)({
65
- parse: decodeVariableValue,
66
- serialize: encodeVariableValue
67
- });
61
+ const VariableValueParam = {
62
+ encode: encodeVariableValue,
63
+ decode: (v)=>{
64
+ if (typeof v === 'string') {
65
+ return decodeVariableValue(v);
66
+ }
67
+ return '';
68
+ }
69
+ };
68
70
  function useVariableQueryParams(defs) {
69
71
  const config = {};
70
72
  defs.forEach((def)=>{
71
73
  const name = getURLQueryParamName(def.spec.name);
72
- config[name] = parseAsVariableValue;
74
+ config[name] = VariableValueParam;
73
75
  });
74
- return (0, _nuqs.useQueryStates)(config, {
75
- history: 'replace'
76
+ return (0, _usequeryparams.useQueryParams)(config, {
77
+ updateType: 'replaceIn'
76
78
  });
77
79
  }
78
80
  function getInitalValuesFromQueryParameters(queryParamValues) {
@@ -18,6 +18,7 @@ _export_star(require("./DashboardProvider"), exports);
18
18
  _export_star(require("./DatasourceStoreProvider"), exports);
19
19
  _export_star(require("./VariableProvider"), exports);
20
20
  _export_star(require("./useDashboard"), exports);
21
+ _export_star(require("./PanelEditorProvider"), exports);
21
22
  function _export_star(from, to) {
22
23
  Object.keys(from).forEach(function(k) {
23
24
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -28,7 +28,8 @@ const _react = require("@testing-library/react");
28
28
  const _history = require("history");
29
29
  const _react1 = require("react");
30
30
  const _reactrouterdom = require("react-router-dom");
31
- const _v6 = require("nuqs/adapters/react-router/v6");
31
+ const _usequeryparams = require("use-query-params");
32
+ const _reactrouter6 = require("use-query-params/adapters/react-router-6");
32
33
  const _context = require("../context");
33
34
  const _test = require("../test");
34
35
  const _pluginregistry = require("./plugin-registry");
@@ -62,11 +63,12 @@ function renderWithContext(ui, options, history) {
62
63
  });
63
64
  const customHistory = history ?? (0, _history.createMemoryHistory)();
64
65
  const mockRegistry = (0, _pluginsystem.mockPluginRegistry)(..._pluginregistry.MOCK_PLUGINS);
65
- const BaseRender = ()=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_v6.NuqsAdapter, {
66
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(CustomRouter, {
67
- history: customHistory,
68
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reactquery.QueryClientProvider, {
69
- client: queryClient,
66
+ const BaseRender = ()=>/*#__PURE__*/ (0, _jsxruntime.jsx)(CustomRouter, {
67
+ history: customHistory,
68
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_reactquery.QueryClientProvider, {
69
+ client: queryClient,
70
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_usequeryparams.QueryParamProvider, {
71
+ adapter: _reactrouter6.ReactRouter6Adapter,
70
72
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.SnackbarProvider, {
71
73
  anchorOrigin: {
72
74
  vertical: 'bottom',
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardStickyToolbar.d.ts","sourceRoot":"","sources":["../../../src/components/DashboardStickyToolbar/DashboardStickyToolbar.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAC/C,OAAO,EAKL,OAAO,EACP,KAAK,EAIN,MAAM,eAAe,CAAC;AAMvB,UAAU,2BAA2B;IACnC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,YAAY,CAuEvF"}
1
+ {"version":3,"file":"DashboardStickyToolbar.d.ts","sourceRoot":"","sources":["../../../src/components/DashboardStickyToolbar/DashboardStickyToolbar.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAC/C,OAAO,EAKL,OAAO,EACP,KAAK,EAIN,MAAM,eAAe,CAAC;AAMvB,UAAU,2BAA2B;IACnC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,YAAY,CAsEvF"}
@@ -48,8 +48,6 @@ export function DashboardStickyToolbar(props) {
48
48
  display: "flex",
49
49
  flexWrap: !isSticky && isBiggerThanMd ? 'wrap' : 'nowrap',
50
50
  maxWidth: isSticky || !isBiggerThanMd ? '100vw' : '100%',
51
- maxHeight: "150px" // Limit the vertical space used to ~3 rows of variables
52
- ,
53
51
  pt: 1,
54
52
  pl: isSticky ? 1 : 0,
55
53
  mt: isSticky && isBiggerThanMd ? 0.5 : 0,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/DashboardStickyToolbar/DashboardStickyToolbar.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useState } from 'react';\nimport {\n AppBar,\n Box,\n IconButton,\n Stack,\n SxProps,\n Theme,\n useMediaQuery,\n useScrollTrigger,\n useTheme,\n} from '@mui/material';\nimport PinOutline from 'mdi-material-ui/PinOutline';\nimport PinOffOutline from 'mdi-material-ui/PinOffOutline';\nimport { TimeRangeControls } from '@perses-dev/plugin-system';\nimport { VariableList } from '../Variables';\n\ninterface DashboardStickyToolbarProps {\n initialVariableIsSticky?: boolean;\n sx?: SxProps<Theme>;\n}\n\nexport function DashboardStickyToolbar(props: DashboardStickyToolbarProps): ReactElement {\n const [isPin, setIsPin] = useState(props.initialVariableIsSticky);\n\n const scrollTrigger = useScrollTrigger({ disableHysteresis: true });\n const isSticky = scrollTrigger && props.initialVariableIsSticky && isPin;\n\n const isBiggerThanMd = useMediaQuery(useTheme().breakpoints.up('md'));\n\n return (\n // marginBottom={-1} counteracts the marginBottom={1} on every variable input.\n // The margin on the inputs is for spacing between inputs, but is not meant to add space to bottom of the container.\n <Box marginBottom={-1} data-testid=\"variable-list\">\n <AppBar\n color=\"inherit\"\n position={isSticky ? 'fixed' : 'static'}\n elevation={isSticky ? 4 : 0}\n sx={{ backgroundColor: 'inherit', ...props.sx }}\n >\n <Box\n display=\"flex\"\n justifyContent=\"space-between\"\n sx={{\n flexDirection: isBiggerThanMd ? 'row' : 'column',\n }}\n >\n <Box\n display=\"flex\"\n flexWrap={!isSticky && isBiggerThanMd ? 'wrap' : 'nowrap'}\n maxWidth={isSticky || !isBiggerThanMd ? '100vw' : '100%'}\n maxHeight=\"150px\" // Limit the vertical space used to ~3 rows of variables\n pt={1}\n pl={isSticky ? 1 : 0}\n mt={isSticky && isBiggerThanMd ? 0.5 : 0}\n ml={isSticky && isBiggerThanMd ? 0.5 : 0}\n sx={{\n overflowX: !isSticky && isBiggerThanMd ? 'hidden' : 'auto',\n // Firefox:\n scrollbarWidth: 'thin',\n // Safari and Chrome:\n '&::-webkit-scrollbar': {\n height: '8px',\n backgroundColor: (theme) => theme.palette.grey['300'],\n },\n '&::-webkit-scrollbar-thumb': {\n background: (theme) => theme.palette.grey['600'],\n },\n }}\n gap={1}\n >\n <VariableList />\n {props.initialVariableIsSticky && (\n <IconButton style={{ width: 'fit-content', height: 'fit-content' }} onClick={() => setIsPin(!isPin)}>\n {isPin ? <PinOutline /> : <PinOffOutline />}\n </IconButton>\n )}\n </Box>\n {isSticky && (\n <Stack\n m={isBiggerThanMd ? 1.5 : 1}\n mt={isBiggerThanMd ? 1.5 : 0}\n ml={isBiggerThanMd ? 1.5 : 'auto'}\n direction=\"row\"\n justifyContent=\"end\"\n >\n <TimeRangeControls />\n </Stack>\n )}\n </Box>\n </AppBar>\n </Box>\n );\n}\n"],"names":["useState","AppBar","Box","IconButton","Stack","useMediaQuery","useScrollTrigger","useTheme","PinOutline","PinOffOutline","TimeRangeControls","VariableList","DashboardStickyToolbar","props","isPin","setIsPin","initialVariableIsSticky","scrollTrigger","disableHysteresis","isSticky","isBiggerThanMd","breakpoints","up","marginBottom","data-testid","color","position","elevation","sx","backgroundColor","display","justifyContent","flexDirection","flexWrap","maxWidth","maxHeight","pt","pl","mt","ml","overflowX","scrollbarWidth","height","theme","palette","grey","background","gap","style","width","onClick","m","direction"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAAuBA,QAAQ,QAAQ,QAAQ;AAC/C,SACEC,MAAM,EACNC,GAAG,EACHC,UAAU,EACVC,KAAK,EAGLC,aAAa,EACbC,gBAAgB,EAChBC,QAAQ,QACH,gBAAgB;AACvB,OAAOC,gBAAgB,6BAA6B;AACpD,OAAOC,mBAAmB,gCAAgC;AAC1D,SAASC,iBAAiB,QAAQ,4BAA4B;AAC9D,SAASC,YAAY,QAAQ,eAAe;AAO5C,OAAO,SAASC,uBAAuBC,KAAkC;IACvE,MAAM,CAACC,OAAOC,SAAS,GAAGf,SAASa,MAAMG,uBAAuB;IAEhE,MAAMC,gBAAgBX,iBAAiB;QAAEY,mBAAmB;IAAK;IACjE,MAAMC,WAAWF,iBAAiBJ,MAAMG,uBAAuB,IAAIF;IAEnE,MAAMM,iBAAiBf,cAAcE,WAAWc,WAAW,CAACC,EAAE,CAAC;IAE/D,OACE,8EAA8E;IAC9E,oHAAoH;kBACpH,KAACpB;QAAIqB,cAAc,CAAC;QAAGC,eAAY;kBACjC,cAAA,KAACvB;YACCwB,OAAM;YACNC,UAAUP,WAAW,UAAU;YAC/BQ,WAAWR,WAAW,IAAI;YAC1BS,IAAI;gBAAEC,iBAAiB;gBAAW,GAAGhB,MAAMe,EAAE;YAAC;sBAE9C,cAAA,MAAC1B;gBACC4B,SAAQ;gBACRC,gBAAe;gBACfH,IAAI;oBACFI,eAAeZ,iBAAiB,QAAQ;gBAC1C;;kCAEA,MAAClB;wBACC4B,SAAQ;wBACRG,UAAU,CAACd,YAAYC,iBAAiB,SAAS;wBACjDc,UAAUf,YAAY,CAACC,iBAAiB,UAAU;wBAClDe,WAAU,QAAQ,wDAAwD;;wBAC1EC,IAAI;wBACJC,IAAIlB,WAAW,IAAI;wBACnBmB,IAAInB,YAAYC,iBAAiB,MAAM;wBACvCmB,IAAIpB,YAAYC,iBAAiB,MAAM;wBACvCQ,IAAI;4BACFY,WAAW,CAACrB,YAAYC,iBAAiB,WAAW;4BACpD,WAAW;4BACXqB,gBAAgB;4BAChB,qBAAqB;4BACrB,wBAAwB;gCACtBC,QAAQ;gCACRb,iBAAiB,CAACc,QAAUA,MAAMC,OAAO,CAACC,IAAI,CAAC,MAAM;4BACvD;4BACA,8BAA8B;gCAC5BC,YAAY,CAACH,QAAUA,MAAMC,OAAO,CAACC,IAAI,CAAC,MAAM;4BAClD;wBACF;wBACAE,KAAK;;0CAEL,KAACpC;4BACAE,MAAMG,uBAAuB,kBAC5B,KAACb;gCAAW6C,OAAO;oCAAEC,OAAO;oCAAeP,QAAQ;gCAAc;gCAAGQ,SAAS,IAAMnC,SAAS,CAACD;0CAC1FA,sBAAQ,KAACN,gCAAgB,KAACC;;;;oBAIhCU,0BACC,KAACf;wBACC+C,GAAG/B,iBAAiB,MAAM;wBAC1BkB,IAAIlB,iBAAiB,MAAM;wBAC3BmB,IAAInB,iBAAiB,MAAM;wBAC3BgC,WAAU;wBACVrB,gBAAe;kCAEf,cAAA,KAACrB;;;;;;AAOf"}
1
+ {"version":3,"sources":["../../../src/components/DashboardStickyToolbar/DashboardStickyToolbar.tsx"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useState } from 'react';\nimport {\n AppBar,\n Box,\n IconButton,\n Stack,\n SxProps,\n Theme,\n useMediaQuery,\n useScrollTrigger,\n useTheme,\n} from '@mui/material';\nimport PinOutline from 'mdi-material-ui/PinOutline';\nimport PinOffOutline from 'mdi-material-ui/PinOffOutline';\nimport { TimeRangeControls } from '@perses-dev/plugin-system';\nimport { VariableList } from '../Variables';\n\ninterface DashboardStickyToolbarProps {\n initialVariableIsSticky?: boolean;\n sx?: SxProps<Theme>;\n}\n\nexport function DashboardStickyToolbar(props: DashboardStickyToolbarProps): ReactElement {\n const [isPin, setIsPin] = useState(props.initialVariableIsSticky);\n\n const scrollTrigger = useScrollTrigger({ disableHysteresis: true });\n const isSticky = scrollTrigger && props.initialVariableIsSticky && isPin;\n\n const isBiggerThanMd = useMediaQuery(useTheme().breakpoints.up('md'));\n\n return (\n // marginBottom={-1} counteracts the marginBottom={1} on every variable input.\n // The margin on the inputs is for spacing between inputs, but is not meant to add space to bottom of the container.\n <Box marginBottom={-1} data-testid=\"variable-list\">\n <AppBar\n color=\"inherit\"\n position={isSticky ? 'fixed' : 'static'}\n elevation={isSticky ? 4 : 0}\n sx={{ backgroundColor: 'inherit', ...props.sx }}\n >\n <Box\n display=\"flex\"\n justifyContent=\"space-between\"\n sx={{\n flexDirection: isBiggerThanMd ? 'row' : 'column',\n }}\n >\n <Box\n display=\"flex\"\n flexWrap={!isSticky && isBiggerThanMd ? 'wrap' : 'nowrap'}\n maxWidth={isSticky || !isBiggerThanMd ? '100vw' : '100%'}\n pt={1}\n pl={isSticky ? 1 : 0}\n mt={isSticky && isBiggerThanMd ? 0.5 : 0}\n ml={isSticky && isBiggerThanMd ? 0.5 : 0}\n sx={{\n overflowX: !isSticky && isBiggerThanMd ? 'hidden' : 'auto',\n // Firefox:\n scrollbarWidth: 'thin',\n // Safari and Chrome:\n '&::-webkit-scrollbar': {\n height: '8px',\n backgroundColor: (theme) => theme.palette.grey['300'],\n },\n '&::-webkit-scrollbar-thumb': {\n background: (theme) => theme.palette.grey['600'],\n },\n }}\n gap={1}\n >\n <VariableList />\n {props.initialVariableIsSticky && (\n <IconButton style={{ width: 'fit-content', height: 'fit-content' }} onClick={() => setIsPin(!isPin)}>\n {isPin ? <PinOutline /> : <PinOffOutline />}\n </IconButton>\n )}\n </Box>\n {isSticky && (\n <Stack\n m={isBiggerThanMd ? 1.5 : 1}\n mt={isBiggerThanMd ? 1.5 : 0}\n ml={isBiggerThanMd ? 1.5 : 'auto'}\n direction=\"row\"\n justifyContent=\"end\"\n >\n <TimeRangeControls />\n </Stack>\n )}\n </Box>\n </AppBar>\n </Box>\n );\n}\n"],"names":["useState","AppBar","Box","IconButton","Stack","useMediaQuery","useScrollTrigger","useTheme","PinOutline","PinOffOutline","TimeRangeControls","VariableList","DashboardStickyToolbar","props","isPin","setIsPin","initialVariableIsSticky","scrollTrigger","disableHysteresis","isSticky","isBiggerThanMd","breakpoints","up","marginBottom","data-testid","color","position","elevation","sx","backgroundColor","display","justifyContent","flexDirection","flexWrap","maxWidth","pt","pl","mt","ml","overflowX","scrollbarWidth","height","theme","palette","grey","background","gap","style","width","onClick","m","direction"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAAuBA,QAAQ,QAAQ,QAAQ;AAC/C,SACEC,MAAM,EACNC,GAAG,EACHC,UAAU,EACVC,KAAK,EAGLC,aAAa,EACbC,gBAAgB,EAChBC,QAAQ,QACH,gBAAgB;AACvB,OAAOC,gBAAgB,6BAA6B;AACpD,OAAOC,mBAAmB,gCAAgC;AAC1D,SAASC,iBAAiB,QAAQ,4BAA4B;AAC9D,SAASC,YAAY,QAAQ,eAAe;AAO5C,OAAO,SAASC,uBAAuBC,KAAkC;IACvE,MAAM,CAACC,OAAOC,SAAS,GAAGf,SAASa,MAAMG,uBAAuB;IAEhE,MAAMC,gBAAgBX,iBAAiB;QAAEY,mBAAmB;IAAK;IACjE,MAAMC,WAAWF,iBAAiBJ,MAAMG,uBAAuB,IAAIF;IAEnE,MAAMM,iBAAiBf,cAAcE,WAAWc,WAAW,CAACC,EAAE,CAAC;IAE/D,OACE,8EAA8E;IAC9E,oHAAoH;kBACpH,KAACpB;QAAIqB,cAAc,CAAC;QAAGC,eAAY;kBACjC,cAAA,KAACvB;YACCwB,OAAM;YACNC,UAAUP,WAAW,UAAU;YAC/BQ,WAAWR,WAAW,IAAI;YAC1BS,IAAI;gBAAEC,iBAAiB;gBAAW,GAAGhB,MAAMe,EAAE;YAAC;sBAE9C,cAAA,MAAC1B;gBACC4B,SAAQ;gBACRC,gBAAe;gBACfH,IAAI;oBACFI,eAAeZ,iBAAiB,QAAQ;gBAC1C;;kCAEA,MAAClB;wBACC4B,SAAQ;wBACRG,UAAU,CAACd,YAAYC,iBAAiB,SAAS;wBACjDc,UAAUf,YAAY,CAACC,iBAAiB,UAAU;wBAClDe,IAAI;wBACJC,IAAIjB,WAAW,IAAI;wBACnBkB,IAAIlB,YAAYC,iBAAiB,MAAM;wBACvCkB,IAAInB,YAAYC,iBAAiB,MAAM;wBACvCQ,IAAI;4BACFW,WAAW,CAACpB,YAAYC,iBAAiB,WAAW;4BACpD,WAAW;4BACXoB,gBAAgB;4BAChB,qBAAqB;4BACrB,wBAAwB;gCACtBC,QAAQ;gCACRZ,iBAAiB,CAACa,QAAUA,MAAMC,OAAO,CAACC,IAAI,CAAC,MAAM;4BACvD;4BACA,8BAA8B;gCAC5BC,YAAY,CAACH,QAAUA,MAAMC,OAAO,CAACC,IAAI,CAAC,MAAM;4BAClD;wBACF;wBACAE,KAAK;;0CAEL,KAACnC;4BACAE,MAAMG,uBAAuB,kBAC5B,KAACb;gCAAW4C,OAAO;oCAAEC,OAAO;oCAAeP,QAAQ;gCAAc;gCAAGQ,SAAS,IAAMlC,SAAS,CAACD;0CAC1FA,sBAAQ,KAACN,gCAAgB,KAACC;;;;oBAIhCU,0BACC,KAACf;wBACC8C,GAAG9B,iBAAiB,MAAM;wBAC1BiB,IAAIjB,iBAAiB,MAAM;wBAC3BkB,IAAIlB,iBAAiB,MAAM;wBAC3B+B,WAAU;wBACVpB,gBAAe;kCAEf,cAAA,KAACrB;;;;;;AAOf"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeletePanelGroupDialog.d.ts","sourceRoot":"","sources":["../../../src/components/DeletePanelGroupDialog/DeletePanelGroupDialog.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAa,YAAY,EAAE,MAAM,OAAO,CAAC;AAKhD,eAAO,MAAM,sBAAsB,QAAO,YA6CzC,CAAC"}
1
+ {"version":3,"file":"DeletePanelGroupDialog.d.ts","sourceRoot":"","sources":["../../../src/components/DeletePanelGroupDialog/DeletePanelGroupDialog.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAa,YAAY,EAAE,MAAM,OAAO,CAAC;AAKhD,eAAO,MAAM,sBAAsB,QAAO,YAmCzC,CAAC"}
@@ -11,8 +11,8 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
- import { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';
15
- import CloseIcon from 'mdi-material-ui/Close';
14
+ import { Dialog } from '@perses-dev/components';
15
+ import { Button } from '@mui/material';
16
16
  import { useDeletePanelGroupDialog, useViewPanel } from '../../context';
17
17
  export const DeletePanelGroupDialog = ()=>{
18
18
  const { deletePanelGroupDialog, closeDeletePanelGroupDialog, deletePanelGroup } = useDeletePanelGroupDialog();
@@ -30,23 +30,13 @@ export const DeletePanelGroupDialog = ()=>{
30
30
  return /*#__PURE__*/ _jsxs(Dialog, {
31
31
  open: deletePanelGroupDialog !== undefined,
32
32
  children: [
33
- /*#__PURE__*/ _jsx(DialogTitle, {
33
+ /*#__PURE__*/ _jsx(Dialog.Header, {
34
34
  children: "Delete Panel Group"
35
35
  }),
36
- /*#__PURE__*/ _jsx(IconButton, {
37
- "aria-label": "Close",
38
- onClick: ()=>closeDeletePanelGroupDialog(),
39
- sx: (theme)=>({
40
- position: 'absolute',
41
- top: theme.spacing(0.5),
42
- right: theme.spacing(0.5)
43
- }),
44
- children: /*#__PURE__*/ _jsx(CloseIcon, {})
45
- }),
46
36
  /*#__PURE__*/ _jsxs("form", {
47
37
  onSubmit: handleDelete,
48
38
  children: [
49
- /*#__PURE__*/ _jsxs(DialogContent, {
39
+ /*#__PURE__*/ _jsxs(Dialog.Content, {
50
40
  dividers: true,
51
41
  sx: {
52
42
  width: '500px'
@@ -57,7 +47,7 @@ export const DeletePanelGroupDialog = ()=>{
57
47
  "? This will delete all the panels within the group."
58
48
  ]
59
49
  }),
60
- /*#__PURE__*/ _jsxs(DialogActions, {
50
+ /*#__PURE__*/ _jsxs(Dialog.Actions, {
61
51
  children: [
62
52
  /*#__PURE__*/ _jsx(Button, {
63
53
  variant: "contained",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/DeletePanelGroupDialog/DeletePanelGroupDialog.tsx"],"sourcesContent":["// Copyright 2023 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 { FormEvent, ReactElement } from 'react';\nimport { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { useDeletePanelGroupDialog, useViewPanel } from '../../context';\n\nexport const DeletePanelGroupDialog = (): ReactElement => {\n const { deletePanelGroupDialog, closeDeletePanelGroupDialog, deletePanelGroup } = useDeletePanelGroupDialog();\n const { setViewPanel } = useViewPanel();\n const panelGroupId = deletePanelGroupDialog?.panelGroupId;\n\n const handleDelete = (e: FormEvent): void => {\n e.preventDefault();\n if (panelGroupId === undefined) {\n throw new Error('group index is undefined');\n }\n deletePanelGroup(panelGroupId);\n closeDeletePanelGroupDialog();\n setViewPanel(undefined);\n };\n\n return (\n <Dialog open={deletePanelGroupDialog !== undefined}>\n <DialogTitle>Delete Panel Group</DialogTitle>\n <IconButton\n aria-label=\"Close\"\n onClick={() => closeDeletePanelGroupDialog()}\n sx={(theme) => ({\n position: 'absolute',\n top: theme.spacing(0.5),\n right: theme.spacing(0.5),\n })}\n >\n <CloseIcon />\n </IconButton>\n <form onSubmit={handleDelete}>\n <DialogContent dividers sx={{ width: '500px' }}>\n Are you sure you want to delete {deletePanelGroupDialog?.panelGroupName ?? 'panel group'}? This will delete\n all the panels within the group.\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" type=\"submit\">\n Delete\n </Button>\n <Button variant=\"outlined\" color=\"secondary\" onClick={() => closeDeletePanelGroupDialog()}>\n Cancel\n </Button>\n </DialogActions>\n </form>\n </Dialog>\n );\n};\n"],"names":["IconButton","Dialog","DialogTitle","DialogContent","DialogActions","Button","CloseIcon","useDeletePanelGroupDialog","useViewPanel","DeletePanelGroupDialog","deletePanelGroupDialog","closeDeletePanelGroupDialog","deletePanelGroup","setViewPanel","panelGroupId","handleDelete","e","preventDefault","undefined","Error","open","aria-label","onClick","sx","theme","position","top","spacing","right","form","onSubmit","dividers","width","panelGroupName","variant","type","color"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,UAAU,EAAEC,MAAM,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,MAAM,QAAQ,gBAAgB;AACtG,OAAOC,eAAe,wBAAwB;AAC9C,SAASC,yBAAyB,EAAEC,YAAY,QAAQ,gBAAgB;AAExE,OAAO,MAAMC,yBAAyB;IACpC,MAAM,EAAEC,sBAAsB,EAAEC,2BAA2B,EAAEC,gBAAgB,EAAE,GAAGL;IAClF,MAAM,EAAEM,YAAY,EAAE,GAAGL;IACzB,MAAMM,eAAeJ,wBAAwBI;IAE7C,MAAMC,eAAe,CAACC;QACpBA,EAAEC,cAAc;QAChB,IAAIH,iBAAiBI,WAAW;YAC9B,MAAM,IAAIC,MAAM;QAClB;QACAP,iBAAiBE;QACjBH;QACAE,aAAaK;IACf;IAEA,qBACE,MAACjB;QAAOmB,MAAMV,2BAA2BQ;;0BACvC,KAAChB;0BAAY;;0BACb,KAACF;gBACCqB,cAAW;gBACXC,SAAS,IAAMX;gBACfY,IAAI,CAACC,QAAW,CAAA;wBACdC,UAAU;wBACVC,KAAKF,MAAMG,OAAO,CAAC;wBACnBC,OAAOJ,MAAMG,OAAO,CAAC;oBACvB,CAAA;0BAEA,cAAA,KAACrB;;0BAEH,MAACuB;gBAAKC,UAAUf;;kCACd,MAACZ;wBAAc4B,QAAQ;wBAACR,IAAI;4BAAES,OAAO;wBAAQ;;4BAAG;4BACbtB,wBAAwBuB,kBAAkB;4BAAc;;;kCAG3F,MAAC7B;;0CACC,KAACC;gCAAO6B,SAAQ;gCAAYC,MAAK;0CAAS;;0CAG1C,KAAC9B;gCAAO6B,SAAQ;gCAAWE,OAAM;gCAAYd,SAAS,IAAMX;0CAA+B;;;;;;;;AAOrG,EAAE"}
1
+ {"version":3,"sources":["../../../src/components/DeletePanelGroupDialog/DeletePanelGroupDialog.tsx"],"sourcesContent":["// Copyright 2023 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 { FormEvent, ReactElement } from 'react';\nimport { Dialog } from '@perses-dev/components';\nimport { Button } from '@mui/material';\nimport { useDeletePanelGroupDialog, useViewPanel } from '../../context';\n\nexport const DeletePanelGroupDialog = (): ReactElement => {\n const { deletePanelGroupDialog, closeDeletePanelGroupDialog, deletePanelGroup } = useDeletePanelGroupDialog();\n const { setViewPanel } = useViewPanel();\n const panelGroupId = deletePanelGroupDialog?.panelGroupId;\n\n const handleDelete = (e: FormEvent): void => {\n e.preventDefault();\n if (panelGroupId === undefined) {\n throw new Error('group index is undefined');\n }\n deletePanelGroup(panelGroupId);\n closeDeletePanelGroupDialog();\n setViewPanel(undefined);\n };\n\n return (\n <Dialog open={deletePanelGroupDialog !== undefined}>\n <Dialog.Header>Delete Panel Group</Dialog.Header>\n\n <form onSubmit={handleDelete}>\n <Dialog.Content dividers sx={{ width: '500px' }}>\n Are you sure you want to delete {deletePanelGroupDialog?.panelGroupName ?? 'panel group'}? This will delete\n all the panels within the group.\n </Dialog.Content>\n <Dialog.Actions>\n <Button variant=\"contained\" type=\"submit\">\n Delete\n </Button>\n <Button variant=\"outlined\" color=\"secondary\" onClick={() => closeDeletePanelGroupDialog()}>\n Cancel\n </Button>\n </Dialog.Actions>\n </form>\n </Dialog>\n );\n};\n"],"names":["Dialog","Button","useDeletePanelGroupDialog","useViewPanel","DeletePanelGroupDialog","deletePanelGroupDialog","closeDeletePanelGroupDialog","deletePanelGroup","setViewPanel","panelGroupId","handleDelete","e","preventDefault","undefined","Error","open","Header","form","onSubmit","Content","dividers","sx","width","panelGroupName","Actions","variant","type","color","onClick"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAASA,MAAM,QAAQ,yBAAyB;AAChD,SAASC,MAAM,QAAQ,gBAAgB;AACvC,SAASC,yBAAyB,EAAEC,YAAY,QAAQ,gBAAgB;AAExE,OAAO,MAAMC,yBAAyB;IACpC,MAAM,EAAEC,sBAAsB,EAAEC,2BAA2B,EAAEC,gBAAgB,EAAE,GAAGL;IAClF,MAAM,EAAEM,YAAY,EAAE,GAAGL;IACzB,MAAMM,eAAeJ,wBAAwBI;IAE7C,MAAMC,eAAe,CAACC;QACpBA,EAAEC,cAAc;QAChB,IAAIH,iBAAiBI,WAAW;YAC9B,MAAM,IAAIC,MAAM;QAClB;QACAP,iBAAiBE;QACjBH;QACAE,aAAaK;IACf;IAEA,qBACE,MAACb;QAAOe,MAAMV,2BAA2BQ;;0BACvC,KAACb,OAAOgB,MAAM;0BAAC;;0BAEf,MAACC;gBAAKC,UAAUR;;kCACd,MAACV,OAAOmB,OAAO;wBAACC,QAAQ;wBAACC,IAAI;4BAAEC,OAAO;wBAAQ;;4BAAG;4BACdjB,wBAAwBkB,kBAAkB;4BAAc;;;kCAG3F,MAACvB,OAAOwB,OAAO;;0CACb,KAACvB;gCAAOwB,SAAQ;gCAAYC,MAAK;0CAAS;;0CAG1C,KAACzB;gCAAOwB,SAAQ;gCAAWE,OAAM;gCAAYC,SAAS,IAAMtB;0CAA+B;;;;;;;;AAOrG,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"GridItemContent.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"names":[],"mappings":"AAgBA,OAAc,EAAE,YAAY,EAAqB,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAA6D,MAAM,eAAe,CAAC;AAC5G,OAAO,EAAqB,YAAY,EAAE,MAAM,UAAU,CAAC;AAG3D,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CA8IzE"}
1
+ {"version":3,"file":"GridItemContent.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"names":[],"mappings":"AAgBA,OAAc,EAAE,YAAY,EAAqB,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAA6D,MAAM,eAAe,CAAC;AAC5G,OAAO,EAAqB,YAAY,EAAE,MAAM,UAAU,CAAC;AAI3D,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CAmGzE"}
@@ -11,13 +11,14 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
- import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Divider } from '@mui/material';
14
+ import { Box } from '@mui/material';
15
15
  import { useInView } from 'react-intersection-observer';
16
- import { DataQueriesProvider, PluginSpecEditor, usePlugin, useSuggestedStepMs } from '@perses-dev/plugin-system';
16
+ import { DataQueriesProvider, usePlugin, useSuggestedStepMs } from '@perses-dev/plugin-system';
17
17
  import React, { useMemo, useState } from 'react';
18
18
  import { useEditMode, usePanel, usePanelActions, useViewPanelGroup } from '../../context';
19
19
  import { Panel } from '../Panel';
20
20
  import { isPanelGroupItemIdEqual } from '../../context/DashboardProvider/panel-group-slice';
21
+ import { QueryViewerDialog } from '../QueryViewerDialog';
21
22
  /**
22
23
  * Resolves the reference to panel content in a GridItemDefinition and renders the panel.
23
24
  */ export function GridItemContent(props) {
@@ -73,38 +74,6 @@ import { isPanelGroupItemIdEqual } from '../../context/DashboardProvider/panel-g
73
74
  };
74
75
  });
75
76
  const pluginQueryOptions = typeof plugin?.queryOptions === 'function' ? plugin?.queryOptions(panelDefinition.spec.plugin.spec) : plugin?.queryOptions;
76
- const queryRows = useMemo(()=>{
77
- if (!queries?.length) return null;
78
- const queryItems = [];
79
- queries.forEach((query, index)=>{
80
- if (query?.spec?.plugin?.kind && query?.kind) {
81
- queryItems.push(/*#__PURE__*/ _jsxs(React.Fragment, {
82
- children: [
83
- /*#__PURE__*/ _jsx(PluginSpecEditor, {
84
- value: query.spec.plugin.spec,
85
- pluginSelection: {
86
- kind: query.spec.plugin.kind,
87
- type: query.kind
88
- },
89
- onChange: ()=>{},
90
- isReadonly: true
91
- }),
92
- index < queries.length - 1 && /*#__PURE__*/ _jsx(Divider, {
93
- sx: {
94
- my: 2
95
- }
96
- })
97
- ]
98
- }, `query-${index}`));
99
- }
100
- });
101
- return queryItems;
102
- }, [
103
- queries
104
- ]);
105
- const onCloseHandler = ()=>{
106
- setOpenQueryViewer(false);
107
- };
108
77
  return /*#__PURE__*/ _jsxs(Box, {
109
78
  ref: ref,
110
79
  sx: {
@@ -112,38 +81,6 @@ import { isPanelGroupItemIdEqual } from '../../context/DashboardProvider/panel-g
112
81
  height: '100%'
113
82
  },
114
83
  children: [
115
- /*#__PURE__*/ _jsxs(Dialog, {
116
- fullWidth: true,
117
- PaperProps: {
118
- sx: {
119
- margin: '10px',
120
- width: 'calc(100% - 20px)'
121
- }
122
- },
123
- maxWidth: "lg",
124
- open: openQueryViewer,
125
- children: [
126
- /*#__PURE__*/ _jsx(DialogTitle, {
127
- children: "Query Viewer"
128
- }),
129
- /*#__PURE__*/ _jsx(DialogContent, {
130
- children: /*#__PURE__*/ _jsx(Box, {
131
- sx: {
132
- padding: '5px'
133
- },
134
- children: queryRows
135
- })
136
- }),
137
- /*#__PURE__*/ _jsx(DialogActions, {
138
- children: /*#__PURE__*/ _jsx(Button, {
139
- variant: "outlined",
140
- onClick: onCloseHandler,
141
- color: "primary",
142
- children: "Close"
143
- })
144
- })
145
- ]
146
- }),
147
84
  /*#__PURE__*/ _jsx(DataQueriesProvider, {
148
85
  definitions: definitions,
149
86
  options: {
@@ -161,6 +98,11 @@ import { isPanelGroupItemIdEqual } from '../../context/DashboardProvider/panel-g
161
98
  panelOptions: props.panelOptions,
162
99
  panelGroupItemId: panelGroupItemId
163
100
  })
101
+ }),
102
+ /*#__PURE__*/ _jsx(QueryViewerDialog, {
103
+ open: openQueryViewer,
104
+ queryDefinitions: queryDefinitions,
105
+ onClose: ()=>setOpenQueryViewer(false)
164
106
  })
165
107
  ]
166
108
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"sourcesContent":["// Copyright 2023 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 { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Divider } from '@mui/material';\nimport { useInView } from 'react-intersection-observer';\nimport { DataQueriesProvider, PluginSpecEditor, usePlugin, useSuggestedStepMs } from '@perses-dev/plugin-system';\nimport React, { ReactElement, useMemo, useState } from 'react';\nimport { PanelGroupItemId, useEditMode, usePanel, usePanelActions, useViewPanelGroup } from '../../context';\nimport { Panel, PanelProps, PanelOptions } from '../Panel';\nimport { isPanelGroupItemIdEqual } from '../../context/DashboardProvider/panel-group-slice';\n\nexport interface GridItemContentProps {\n panelGroupItemId: PanelGroupItemId;\n width: number; // necessary for determining the suggested step ms\n panelOptions?: PanelOptions;\n}\n\n/**\n * Resolves the reference to panel content in a GridItemDefinition and renders the panel.\n */\nexport function GridItemContent(props: GridItemContentProps): ReactElement {\n const { panelGroupItemId, width } = props;\n const panelDefinition = usePanel(panelGroupItemId);\n\n const {\n spec: { queries },\n } = panelDefinition;\n\n const { isEditMode } = useEditMode();\n const { openEditPanel, openDeletePanelDialog, duplicatePanel, viewPanel } = usePanelActions(panelGroupItemId);\n const viewPanelGroupItemId = useViewPanelGroup();\n const { ref, inView } = useInView({\n threshold: 0.2, // we have the flexibility to adjust this threshold to trigger queries slightly earlier or later based on performance\n initialInView: false,\n triggerOnce: true,\n });\n\n const [openQueryViewer, setOpenQueryViewer] = useState(false);\n\n const viewQueriesHandler = useMemo(() => {\n return isEditMode || !queries?.length\n ? undefined\n : {\n onClick: (): void => {\n setOpenQueryViewer(true);\n },\n };\n }, [isEditMode, queries]);\n\n const readHandlers = {\n isPanelViewed: isPanelGroupItemIdEqual(viewPanelGroupItemId, panelGroupItemId),\n onViewPanelClick: function (): void {\n if (viewPanelGroupItemId === undefined) {\n viewPanel(panelGroupItemId);\n } else {\n viewPanel(undefined);\n }\n },\n };\n\n // Provide actions to the panel when in edit mode\n let editHandlers: PanelProps['editHandlers'] = undefined;\n if (isEditMode) {\n editHandlers = {\n onEditPanelClick: openEditPanel,\n onDuplicatePanelClick: duplicatePanel,\n onDeletePanelClick: openDeletePanelDialog,\n };\n }\n\n // map TimeSeriesQueryDefinition to Definition<UnknownSpec>\n const suggestedStepMs = useSuggestedStepMs(width);\n\n const { data: plugin } = usePlugin('Panel', panelDefinition.spec.plugin.kind);\n\n const queryDefinitions = queries ?? [];\n const definitions = queryDefinitions.map((query) => {\n return {\n kind: query.spec.plugin.kind,\n spec: query.spec.plugin.spec,\n };\n });\n\n const pluginQueryOptions =\n typeof plugin?.queryOptions === 'function'\n ? plugin?.queryOptions(panelDefinition.spec.plugin.spec)\n : plugin?.queryOptions;\n\n const queryRows = useMemo(() => {\n if (!queries?.length) return null;\n\n const queryItems: ReactElement[] = [];\n queries.forEach((query, index) => {\n if (query?.spec?.plugin?.kind && query?.kind) {\n queryItems.push(\n <React.Fragment key={`query-${index}`}>\n <PluginSpecEditor\n value={query.spec.plugin.spec}\n pluginSelection={{ kind: query.spec.plugin.kind, type: query.kind }}\n onChange={(): void => {}}\n isReadonly\n />\n {index < queries.length - 1 && <Divider sx={{ my: 2 }} />}\n </React.Fragment>\n );\n }\n });\n\n return queryItems;\n }, [queries]);\n\n const onCloseHandler = (): void => {\n setOpenQueryViewer(false);\n };\n\n return (\n <Box\n ref={ref}\n sx={{\n width: '100%',\n height: '100%',\n }}\n >\n <Dialog\n fullWidth\n PaperProps={{\n sx: {\n margin: '10px',\n width: 'calc(100% - 20px)',\n },\n }}\n maxWidth=\"lg\"\n open={openQueryViewer}\n >\n <DialogTitle>Query Viewer</DialogTitle>\n <DialogContent>\n <Box sx={{ padding: '5px' }}>{queryRows}</Box>\n </DialogContent>\n <DialogActions>\n <Button variant=\"outlined\" onClick={onCloseHandler} color=\"primary\">\n Close\n </Button>\n </DialogActions>\n </Dialog>\n <DataQueriesProvider\n definitions={definitions}\n options={{ suggestedStepMs, ...pluginQueryOptions }}\n queryOptions={{ enabled: inView }}\n >\n {inView && (\n <Panel\n definition={panelDefinition}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n viewQueriesHandler={viewQueriesHandler}\n panelOptions={props.panelOptions}\n panelGroupItemId={panelGroupItemId}\n />\n )}\n </DataQueriesProvider>\n </Box>\n );\n}\n"],"names":["Box","Button","Dialog","DialogActions","DialogContent","DialogTitle","Divider","useInView","DataQueriesProvider","PluginSpecEditor","usePlugin","useSuggestedStepMs","React","useMemo","useState","useEditMode","usePanel","usePanelActions","useViewPanelGroup","Panel","isPanelGroupItemIdEqual","GridItemContent","props","panelGroupItemId","width","panelDefinition","spec","queries","isEditMode","openEditPanel","openDeletePanelDialog","duplicatePanel","viewPanel","viewPanelGroupItemId","ref","inView","threshold","initialInView","triggerOnce","openQueryViewer","setOpenQueryViewer","viewQueriesHandler","length","undefined","onClick","readHandlers","isPanelViewed","onViewPanelClick","editHandlers","onEditPanelClick","onDuplicatePanelClick","onDeletePanelClick","suggestedStepMs","data","plugin","kind","queryDefinitions","definitions","map","query","pluginQueryOptions","queryOptions","queryRows","queryItems","forEach","index","push","Fragment","value","pluginSelection","type","onChange","isReadonly","sx","my","onCloseHandler","height","fullWidth","PaperProps","margin","maxWidth","open","padding","variant","color","options","enabled","definition","panelOptions"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"sourcesContent":["// Copyright 2023 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 { Box } from '@mui/material';\nimport { useInView } from 'react-intersection-observer';\nimport { DataQueriesProvider, usePlugin, useSuggestedStepMs } from '@perses-dev/plugin-system';\nimport React, { ReactElement, useMemo, useState } from 'react';\nimport { PanelGroupItemId, useEditMode, usePanel, usePanelActions, useViewPanelGroup } from '../../context';\nimport { Panel, PanelProps, PanelOptions } from '../Panel';\nimport { isPanelGroupItemIdEqual } from '../../context/DashboardProvider/panel-group-slice';\nimport { QueryViewerDialog } from '../QueryViewerDialog';\n\nexport interface GridItemContentProps {\n panelGroupItemId: PanelGroupItemId;\n width: number; // necessary for determining the suggested step ms\n panelOptions?: PanelOptions;\n}\n\n/**\n * Resolves the reference to panel content in a GridItemDefinition and renders the panel.\n */\nexport function GridItemContent(props: GridItemContentProps): ReactElement {\n const { panelGroupItemId, width } = props;\n const panelDefinition = usePanel(panelGroupItemId);\n\n const {\n spec: { queries },\n } = panelDefinition;\n\n const { isEditMode } = useEditMode();\n const { openEditPanel, openDeletePanelDialog, duplicatePanel, viewPanel } = usePanelActions(panelGroupItemId);\n const viewPanelGroupItemId = useViewPanelGroup();\n const { ref, inView } = useInView({\n threshold: 0.2, // we have the flexibility to adjust this threshold to trigger queries slightly earlier or later based on performance\n initialInView: false,\n triggerOnce: true,\n });\n\n const [openQueryViewer, setOpenQueryViewer] = useState(false);\n\n const viewQueriesHandler = useMemo(() => {\n return isEditMode || !queries?.length\n ? undefined\n : {\n onClick: (): void => {\n setOpenQueryViewer(true);\n },\n };\n }, [isEditMode, queries]);\n\n const readHandlers = {\n isPanelViewed: isPanelGroupItemIdEqual(viewPanelGroupItemId, panelGroupItemId),\n onViewPanelClick: function (): void {\n if (viewPanelGroupItemId === undefined) {\n viewPanel(panelGroupItemId);\n } else {\n viewPanel(undefined);\n }\n },\n };\n\n // Provide actions to the panel when in edit mode\n let editHandlers: PanelProps['editHandlers'] = undefined;\n if (isEditMode) {\n editHandlers = {\n onEditPanelClick: openEditPanel,\n onDuplicatePanelClick: duplicatePanel,\n onDeletePanelClick: openDeletePanelDialog,\n };\n }\n\n // map TimeSeriesQueryDefinition to Definition<UnknownSpec>\n const suggestedStepMs = useSuggestedStepMs(width);\n\n const { data: plugin } = usePlugin('Panel', panelDefinition.spec.plugin.kind);\n\n const queryDefinitions = queries ?? [];\n const definitions = queryDefinitions.map((query) => {\n return {\n kind: query.spec.plugin.kind,\n spec: query.spec.plugin.spec,\n };\n });\n\n const pluginQueryOptions =\n typeof plugin?.queryOptions === 'function'\n ? plugin?.queryOptions(panelDefinition.spec.plugin.spec)\n : plugin?.queryOptions;\n\n return (\n <Box\n ref={ref}\n sx={{\n width: '100%',\n height: '100%',\n }}\n >\n <DataQueriesProvider\n definitions={definitions}\n options={{ suggestedStepMs, ...pluginQueryOptions }}\n queryOptions={{ enabled: inView }}\n >\n {inView && (\n <Panel\n definition={panelDefinition}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n viewQueriesHandler={viewQueriesHandler}\n panelOptions={props.panelOptions}\n panelGroupItemId={panelGroupItemId}\n />\n )}\n </DataQueriesProvider>\n <QueryViewerDialog\n open={openQueryViewer}\n queryDefinitions={queryDefinitions}\n onClose={() => setOpenQueryViewer(false)}\n />\n </Box>\n );\n}\n"],"names":["Box","useInView","DataQueriesProvider","usePlugin","useSuggestedStepMs","React","useMemo","useState","useEditMode","usePanel","usePanelActions","useViewPanelGroup","Panel","isPanelGroupItemIdEqual","QueryViewerDialog","GridItemContent","props","panelGroupItemId","width","panelDefinition","spec","queries","isEditMode","openEditPanel","openDeletePanelDialog","duplicatePanel","viewPanel","viewPanelGroupItemId","ref","inView","threshold","initialInView","triggerOnce","openQueryViewer","setOpenQueryViewer","viewQueriesHandler","length","undefined","onClick","readHandlers","isPanelViewed","onViewPanelClick","editHandlers","onEditPanelClick","onDuplicatePanelClick","onDeletePanelClick","suggestedStepMs","data","plugin","kind","queryDefinitions","definitions","map","query","pluginQueryOptions","queryOptions","sx","height","options","enabled","definition","panelOptions","open","onClose"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import { DashboardResource, EphemeralDashboardResource } from '@perses-dev/core';
2
2
  import { ReactElement, ReactNode } from 'react';
3
+ import type { BlockerFunction } from '@remix-run/router';
3
4
  export interface LeaveDialogProps {
4
- isBlocked: boolean;
5
+ isBlocked: BlockerFunction | boolean;
5
6
  message: string;
6
7
  }
7
8
  export declare function Prompt({ isBlocked, message }: LeaveDialogProps): ReactElement;
@@ -1 +1 @@
1
- {"version":3,"file":"LeaveDialog.d.ts","sourceRoot":"","sources":["../../../src/components/LeaveDialog/LeaveDialog.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAa,MAAM,OAAO,CAAC;AAU3D,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,gBAAgB,GAAG,YAAY,CA4B7E;AAKD,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,iBAAiB,GAAG,0BAA0B,GAAG,SAAS,CAAC;IACrE,OAAO,EAAE,iBAAiB,GAAG,0BAA0B,CAAC;CACzD,GAAG,SAAS,CAOZ"}
1
+ {"version":3,"file":"LeaveDialog.d.ts","sourceRoot":"","sources":["../../../src/components/LeaveDialog/LeaveDialog.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAa,MAAM,OAAO,CAAC;AAG3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAQzD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,gBAAgB,GAAG,YAAY,CA4B7E;AAKD,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,iBAAiB,GAAG,0BAA0B,GAAG,SAAS,CAAC;IACrE,OAAO,EAAE,iBAAiB,GAAG,0BAA0B,CAAC;CACzD,GAAG,SAAS,CAYZ"}
@@ -52,8 +52,17 @@ const handleRouteChange = (event)=>{
52
52
  /*
53
53
  * LeaveDialog prompts the user with a confirmation dialog when they attempt to leave the page with unsaved changes.
54
54
  */ export function LeaveDialog({ original, current }) {
55
+ const handleIsBlocked = (ctx)=>{
56
+ if (JSON.stringify(original) !== JSON.stringify(current)) {
57
+ // Only block navigation if the pathname is changing (=> ignore search params changes)
58
+ if (ctx.currentLocation.pathname !== ctx.nextLocation.pathname) {
59
+ return true;
60
+ }
61
+ }
62
+ return false;
63
+ };
55
64
  return /*#__PURE__*/ _jsx(Prompt, {
56
- isBlocked: JSON.stringify(original) !== JSON.stringify(current),
65
+ isBlocked: handleIsBlocked,
57
66
  message: "You have unsaved changes, are you sure you want to leave?"
58
67
  });
59
68
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/LeaveDialog/LeaveDialog.tsx"],"sourcesContent":["// Copyright 2025 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 { DashboardResource, EphemeralDashboardResource } from '@perses-dev/core';\nimport { ReactElement, ReactNode, useEffect } from 'react';\nimport { useBlocker } from 'react-router-dom';\nimport { DiscardChangesConfirmationDialog } from '@perses-dev/components';\n\nconst handleRouteChange = (event: BeforeUnloadEvent): string => {\n event.preventDefault();\n event.returnValue = ''; // Required for Chrome\n return ''; // Required for other browsers\n};\n\nexport interface LeaveDialogProps {\n isBlocked: boolean;\n message: string;\n}\n\n/*\n * Prompt component uses the useBlocker hook to block react-router navigation when there are unsaved changes.\n * It also listens to the beforeunload event to show a browser confirmation dialog when the user tries to close the tab, refresh the page or change url manually.\n */\nexport function Prompt({ isBlocked, message }: LeaveDialogProps): ReactElement {\n const blocker = useBlocker(isBlocked);\n const isBlockedState = blocker.state === 'blocked';\n const isProceedingState = blocker.state === 'proceeding';\n\n useEffect(() => {\n if (isBlocked) {\n window.addEventListener('beforeunload', handleRouteChange);\n } else {\n window.removeEventListener('beforeunload', handleRouteChange);\n }\n\n return (): void => {\n window.removeEventListener('beforeunload', handleRouteChange);\n };\n }, [blocker, isBlocked, isBlockedState]);\n\n const handleDiscardChanges = (): void => blocker.proceed?.();\n const handleCancel = (): void => blocker.reset?.();\n\n return (\n <DiscardChangesConfirmationDialog\n description={message}\n isOpen={isBlockedState || isProceedingState}\n onDiscardChanges={handleDiscardChanges}\n onCancel={handleCancel}\n />\n );\n}\n\n/*\n * LeaveDialog prompts the user with a confirmation dialog when they attempt to leave the page with unsaved changes.\n */\nexport function LeaveDialog({\n original,\n current,\n}: {\n original: DashboardResource | EphemeralDashboardResource | undefined;\n current: DashboardResource | EphemeralDashboardResource;\n}): ReactNode {\n return (\n <Prompt\n isBlocked={JSON.stringify(original) !== JSON.stringify(current)}\n message=\"You have unsaved changes, are you sure you want to leave?\"\n />\n );\n}\n"],"names":["useEffect","useBlocker","DiscardChangesConfirmationDialog","handleRouteChange","event","preventDefault","returnValue","Prompt","isBlocked","message","blocker","isBlockedState","state","isProceedingState","window","addEventListener","removeEventListener","handleDiscardChanges","proceed","handleCancel","reset","description","isOpen","onDiscardChanges","onCancel","LeaveDialog","original","current","JSON","stringify"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAAkCA,SAAS,QAAQ,QAAQ;AAC3D,SAASC,UAAU,QAAQ,mBAAmB;AAC9C,SAASC,gCAAgC,QAAQ,yBAAyB;AAE1E,MAAMC,oBAAoB,CAACC;IACzBA,MAAMC,cAAc;IACpBD,MAAME,WAAW,GAAG,IAAI,sBAAsB;IAC9C,OAAO,IAAI,8BAA8B;AAC3C;AAOA;;;CAGC,GACD,OAAO,SAASC,OAAO,EAAEC,SAAS,EAAEC,OAAO,EAAoB;IAC7D,MAAMC,UAAUT,WAAWO;IAC3B,MAAMG,iBAAiBD,QAAQE,KAAK,KAAK;IACzC,MAAMC,oBAAoBH,QAAQE,KAAK,KAAK;IAE5CZ,UAAU;QACR,IAAIQ,WAAW;YACbM,OAAOC,gBAAgB,CAAC,gBAAgBZ;QAC1C,OAAO;YACLW,OAAOE,mBAAmB,CAAC,gBAAgBb;QAC7C;QAEA,OAAO;YACLW,OAAOE,mBAAmB,CAAC,gBAAgBb;QAC7C;IACF,GAAG;QAACO;QAASF;QAAWG;KAAe;IAEvC,MAAMM,uBAAuB,IAAYP,QAAQQ,OAAO;IACxD,MAAMC,eAAe,IAAYT,QAAQU,KAAK;IAE9C,qBACE,KAAClB;QACCmB,aAAaZ;QACba,QAAQX,kBAAkBE;QAC1BU,kBAAkBN;QAClBO,UAAUL;;AAGhB;AAEA;;CAEC,GACD,OAAO,SAASM,YAAY,EAC1BC,QAAQ,EACRC,OAAO,EAIR;IACC,qBACE,KAACpB;QACCC,WAAWoB,KAAKC,SAAS,CAACH,cAAcE,KAAKC,SAAS,CAACF;QACvDlB,SAAQ;;AAGd"}
1
+ {"version":3,"sources":["../../../src/components/LeaveDialog/LeaveDialog.tsx"],"sourcesContent":["// Copyright 2025 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 { DashboardResource, EphemeralDashboardResource } from '@perses-dev/core';\nimport { ReactElement, ReactNode, useEffect } from 'react';\nimport { useBlocker } from 'react-router-dom';\nimport { DiscardChangesConfirmationDialog } from '@perses-dev/components';\nimport type { BlockerFunction } from '@remix-run/router';\n\nconst handleRouteChange = (event: BeforeUnloadEvent): string => {\n event.preventDefault();\n event.returnValue = ''; // Required for Chrome\n return ''; // Required for other browsers\n};\n\nexport interface LeaveDialogProps {\n isBlocked: BlockerFunction | boolean;\n message: string;\n}\n\n/*\n * Prompt component uses the useBlocker hook to block react-router navigation when there are unsaved changes.\n * It also listens to the beforeunload event to show a browser confirmation dialog when the user tries to close the tab, refresh the page or change url manually.\n */\nexport function Prompt({ isBlocked, message }: LeaveDialogProps): ReactElement {\n const blocker = useBlocker(isBlocked);\n const isBlockedState = blocker.state === 'blocked';\n const isProceedingState = blocker.state === 'proceeding';\n\n useEffect(() => {\n if (isBlocked) {\n window.addEventListener('beforeunload', handleRouteChange);\n } else {\n window.removeEventListener('beforeunload', handleRouteChange);\n }\n\n return (): void => {\n window.removeEventListener('beforeunload', handleRouteChange);\n };\n }, [blocker, isBlocked, isBlockedState]);\n\n const handleDiscardChanges = (): void => blocker.proceed?.();\n const handleCancel = (): void => blocker.reset?.();\n\n return (\n <DiscardChangesConfirmationDialog\n description={message}\n isOpen={isBlockedState || isProceedingState}\n onDiscardChanges={handleDiscardChanges}\n onCancel={handleCancel}\n />\n );\n}\n\n/*\n * LeaveDialog prompts the user with a confirmation dialog when they attempt to leave the page with unsaved changes.\n */\nexport function LeaveDialog({\n original,\n current,\n}: {\n original: DashboardResource | EphemeralDashboardResource | undefined;\n current: DashboardResource | EphemeralDashboardResource;\n}): ReactNode {\n const handleIsBlocked: BlockerFunction = (ctx) => {\n if (JSON.stringify(original) !== JSON.stringify(current)) {\n // Only block navigation if the pathname is changing (=> ignore search params changes)\n if (ctx.currentLocation.pathname !== ctx.nextLocation.pathname) {\n return true;\n }\n }\n return false;\n };\n\n return <Prompt isBlocked={handleIsBlocked} message=\"You have unsaved changes, are you sure you want to leave?\" />;\n}\n"],"names":["useEffect","useBlocker","DiscardChangesConfirmationDialog","handleRouteChange","event","preventDefault","returnValue","Prompt","isBlocked","message","blocker","isBlockedState","state","isProceedingState","window","addEventListener","removeEventListener","handleDiscardChanges","proceed","handleCancel","reset","description","isOpen","onDiscardChanges","onCancel","LeaveDialog","original","current","handleIsBlocked","ctx","JSON","stringify","currentLocation","pathname","nextLocation"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAGjC,SAAkCA,SAAS,QAAQ,QAAQ;AAC3D,SAASC,UAAU,QAAQ,mBAAmB;AAC9C,SAASC,gCAAgC,QAAQ,yBAAyB;AAG1E,MAAMC,oBAAoB,CAACC;IACzBA,MAAMC,cAAc;IACpBD,MAAME,WAAW,GAAG,IAAI,sBAAsB;IAC9C,OAAO,IAAI,8BAA8B;AAC3C;AAOA;;;CAGC,GACD,OAAO,SAASC,OAAO,EAAEC,SAAS,EAAEC,OAAO,EAAoB;IAC7D,MAAMC,UAAUT,WAAWO;IAC3B,MAAMG,iBAAiBD,QAAQE,KAAK,KAAK;IACzC,MAAMC,oBAAoBH,QAAQE,KAAK,KAAK;IAE5CZ,UAAU;QACR,IAAIQ,WAAW;YACbM,OAAOC,gBAAgB,CAAC,gBAAgBZ;QAC1C,OAAO;YACLW,OAAOE,mBAAmB,CAAC,gBAAgBb;QAC7C;QAEA,OAAO;YACLW,OAAOE,mBAAmB,CAAC,gBAAgBb;QAC7C;IACF,GAAG;QAACO;QAASF;QAAWG;KAAe;IAEvC,MAAMM,uBAAuB,IAAYP,QAAQQ,OAAO;IACxD,MAAMC,eAAe,IAAYT,QAAQU,KAAK;IAE9C,qBACE,KAAClB;QACCmB,aAAaZ;QACba,QAAQX,kBAAkBE;QAC1BU,kBAAkBN;QAClBO,UAAUL;;AAGhB;AAEA;;CAEC,GACD,OAAO,SAASM,YAAY,EAC1BC,QAAQ,EACRC,OAAO,EAIR;IACC,MAAMC,kBAAmC,CAACC;QACxC,IAAIC,KAAKC,SAAS,CAACL,cAAcI,KAAKC,SAAS,CAACJ,UAAU;YACxD,sFAAsF;YACtF,IAAIE,IAAIG,eAAe,CAACC,QAAQ,KAAKJ,IAAIK,YAAY,CAACD,QAAQ,EAAE;gBAC9D,OAAO;YACT;QACF;QACA,OAAO;IACT;IAEA,qBAAO,KAAC1B;QAAOC,WAAWoB;QAAiBnB,SAAQ;;AACrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"PanelEditorForm.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelEditorForm.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAA4C,MAAM,OAAO,CAAC;AAE/E,OAAO,EAAE,MAAM,EAA+C,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAoB1G,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,iBAAiB,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CA+OzE;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC"}
1
+ {"version":3,"file":"PanelEditorForm.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelEditorForm.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAA4C,MAAM,OAAO,CAAC;AAE/E,OAAO,EAAE,MAAM,EAA+C,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAqB1G,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,iBAAiB,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CAkPzE;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC"}