@perses-dev/dashboards 0.45.0 → 0.46.0-rc0

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 (72) hide show
  1. package/dist/cjs/components/Dashboard/Dashboard.js +10 -1
  2. package/dist/cjs/components/GridLayout/GridContainer.js +15 -10
  3. package/dist/cjs/components/GridLayout/GridItemContent.js +18 -3
  4. package/dist/cjs/components/GridLayout/GridLayout.js +52 -8
  5. package/dist/cjs/components/Panel/Panel.js +3 -2
  6. package/dist/cjs/components/Panel/PanelHeader.js +24 -4
  7. package/dist/cjs/components/PanelDrawer/PanelPreview.js +6 -1
  8. package/dist/cjs/components/Variables/VariableList.js +4 -1
  9. package/dist/cjs/constants/user-interface-text.js +2 -0
  10. package/dist/cjs/context/DashboardProvider/DashboardProvider.js +3 -1
  11. package/dist/cjs/context/DashboardProvider/DashboardProviderWithQueryParams.js +36 -0
  12. package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +13 -4
  13. package/dist/cjs/context/DashboardProvider/panel-group-slice.js +6 -0
  14. package/dist/cjs/context/DashboardProvider/view-panel-slice.js +80 -0
  15. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +2 -1
  16. package/dist/components/Dashboard/Dashboard.d.ts.map +1 -1
  17. package/dist/components/Dashboard/Dashboard.js +10 -1
  18. package/dist/components/Dashboard/Dashboard.js.map +1 -1
  19. package/dist/components/GridLayout/GridContainer.d.ts +4 -2
  20. package/dist/components/GridLayout/GridContainer.d.ts.map +1 -1
  21. package/dist/components/GridLayout/GridContainer.js +15 -10
  22. package/dist/components/GridLayout/GridContainer.js.map +1 -1
  23. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  24. package/dist/components/GridLayout/GridItemContent.js +20 -5
  25. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  26. package/dist/components/GridLayout/GridLayout.d.ts +1 -0
  27. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  28. package/dist/components/GridLayout/GridLayout.js +54 -10
  29. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  30. package/dist/components/Panel/Panel.d.ts +10 -4
  31. package/dist/components/Panel/Panel.d.ts.map +1 -1
  32. package/dist/components/Panel/Panel.js +3 -2
  33. package/dist/components/Panel/Panel.js.map +1 -1
  34. package/dist/components/Panel/PanelHeader.d.ts +5 -1
  35. package/dist/components/Panel/PanelHeader.d.ts.map +1 -1
  36. package/dist/components/Panel/PanelHeader.js +24 -4
  37. package/dist/components/Panel/PanelHeader.js.map +1 -1
  38. package/dist/components/PanelDrawer/PanelPreview.d.ts.map +1 -1
  39. package/dist/components/PanelDrawer/PanelPreview.js +7 -2
  40. package/dist/components/PanelDrawer/PanelPreview.js.map +1 -1
  41. package/dist/components/Variables/VariableList.d.ts +1 -1
  42. package/dist/components/Variables/VariableList.d.ts.map +1 -1
  43. package/dist/components/Variables/VariableList.js +4 -1
  44. package/dist/components/Variables/VariableList.js.map +1 -1
  45. package/dist/constants/user-interface-text.d.ts +2 -0
  46. package/dist/constants/user-interface-text.d.ts.map +1 -1
  47. package/dist/constants/user-interface-text.js +2 -0
  48. package/dist/constants/user-interface-text.js.map +1 -1
  49. package/dist/context/DashboardProvider/DashboardProvider.d.ts +4 -1
  50. package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
  51. package/dist/context/DashboardProvider/DashboardProvider.js +3 -1
  52. package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
  53. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.d.ts +3 -0
  54. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.d.ts.map +1 -0
  55. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.js +28 -0
  56. package/dist/context/DashboardProvider/DashboardProviderWithQueryParams.js.map +1 -0
  57. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +5 -0
  58. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  59. package/dist/context/DashboardProvider/dashboard-provider-api.js +12 -4
  60. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  61. package/dist/context/DashboardProvider/panel-group-slice.d.ts +1 -0
  62. package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
  63. package/dist/context/DashboardProvider/panel-group-slice.js +5 -0
  64. package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
  65. package/dist/context/DashboardProvider/view-panel-slice.d.ts +21 -0
  66. package/dist/context/DashboardProvider/view-panel-slice.d.ts.map +1 -0
  67. package/dist/context/DashboardProvider/view-panel-slice.js +74 -0
  68. package/dist/context/DashboardProvider/view-panel-slice.js.map +1 -0
  69. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  70. package/dist/views/ViewDashboard/ViewDashboard.js +3 -2
  71. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  72. package/package.json +6 -6
@@ -23,17 +23,25 @@ Object.defineProperty(exports, "Dashboard", {
23
23
  const _jsxruntime = require("react/jsx-runtime");
24
24
  const _material = require("@mui/material");
25
25
  const _components = require("@perses-dev/components");
26
+ const _react = require("react");
26
27
  const _context = require("../../context");
27
28
  const _GridLayout = require("../GridLayout");
28
29
  const _EmptyDashboard = require("../EmptyDashboard");
30
+ const HEADER_HEIGHT = 165; // Approximate height of the header in dashboard view (including the navbar and variables toolbar)
29
31
  function Dashboard({ emptyDashboardProps, panelOptions, ...boxProps }) {
32
+ var _boxRef_current;
30
33
  const panelGroupIds = (0, _context.usePanelGroupIds)();
34
+ const boxRef = (0, _react.useRef)(null);
31
35
  const isEmpty = !panelGroupIds.length;
36
+ var _boxRef_current_getBoundingClientRect_top;
37
+ const dashboardTopPosition = (_boxRef_current_getBoundingClientRect_top = (_boxRef_current = boxRef.current) === null || _boxRef_current === void 0 ? void 0 : _boxRef_current.getBoundingClientRect().top) !== null && _boxRef_current_getBoundingClientRect_top !== void 0 ? _boxRef_current_getBoundingClientRect_top : HEADER_HEIGHT;
38
+ const panelFullHeight = window.innerHeight - dashboardTopPosition - window.scrollY;
32
39
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
33
40
  ...boxProps,
34
41
  sx: {
35
42
  height: '100%'
36
43
  },
44
+ ref: boxRef,
37
45
  children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_components.ErrorBoundary, {
38
46
  FallbackComponent: _components.ErrorAlert,
39
47
  children: [
@@ -49,7 +57,8 @@ function Dashboard({ emptyDashboardProps, panelOptions, ...boxProps }) {
49
57
  }),
50
58
  !isEmpty && panelGroupIds.map((panelGroupId)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_GridLayout.GridLayout, {
51
59
  panelGroupId: panelGroupId,
52
- panelOptions: panelOptions
60
+ panelOptions: panelOptions,
61
+ panelFullHeight: panelFullHeight
53
62
  }, panelGroupId))
54
63
  ]
55
64
  })
@@ -33,17 +33,22 @@ function GridContainer(props) {
33
33
  isFirstRender
34
34
  ]);
35
35
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(ReactGridLayoutContainer, {
36
- sx: {
37
- // This adds spcing between grids (rows) in the overall dashboard
38
- '& + &': {
39
- marginTop: (theme)=>theme.spacing(1)
36
+ sx: [
37
+ {
38
+ // This adds spacing between grids (rows) in the overall dashboard
39
+ '& + &': {
40
+ marginTop: 1
41
+ },
42
+ // This disables the animation of grid items when a grid is first rendered
43
+ // (see https://github.com/react-grid-layout/react-grid-layout/issues/103)
44
+ '& .react-grid-item.cssTransforms': {
45
+ transitionProperty: isFirstRender ? 'none' : 'transform'
46
+ }
40
47
  },
41
- // This disables the animation of grid items when a grid is first rendered
42
- // (see https://github.com/react-grid-layout/react-grid-layout/issues/103)
43
- '& .react-grid-item.cssTransforms': {
44
- transitionProperty: isFirstRender ? 'none' : 'transform'
45
- }
46
- },
48
+ ...Array.isArray(props.sx) ? props.sx : [
49
+ props.sx
50
+ ]
51
+ ],
47
52
  "data-testid": "panel-group",
48
53
  children: props.children
49
54
  });
@@ -25,18 +25,30 @@ const _material = require("@mui/material");
25
25
  const _reactintersectionobserver = require("react-intersection-observer");
26
26
  const _pluginsystem = require("@perses-dev/plugin-system");
27
27
  const _context = require("../../context");
28
- const _Panel = require("../Panel/Panel");
28
+ const _Panel = require("../Panel");
29
+ const _panelgroupslice = require("../../context/DashboardProvider/panel-group-slice");
29
30
  function GridItemContent(props) {
30
31
  const { panelGroupItemId, width } = props;
31
32
  const panelDefinition = (0, _context.usePanel)(panelGroupItemId);
32
33
  const { spec: { queries } } = panelDefinition;
33
34
  const { isEditMode } = (0, _context.useEditMode)();
34
- const { openEditPanel, openDeletePanelDialog, duplicatePanel } = (0, _context.usePanelActions)(panelGroupItemId);
35
+ const { openEditPanel, openDeletePanelDialog, duplicatePanel, viewPanel } = (0, _context.usePanelActions)(panelGroupItemId);
36
+ const viewPanelGroupItemId = (0, _context.useViewPanel)();
35
37
  const { ref, inView } = (0, _reactintersectionobserver.useInView)({
36
38
  threshold: 0.2,
37
39
  initialInView: false,
38
40
  triggerOnce: true
39
41
  });
42
+ const readHandlers = {
43
+ isPanelViewed: (0, _panelgroupslice.isPanelGroupItemIdEqual)(viewPanelGroupItemId, panelGroupItemId),
44
+ onViewPanelClick: function() {
45
+ if (viewPanelGroupItemId === undefined) {
46
+ viewPanel(panelGroupItemId);
47
+ } else {
48
+ viewPanel(undefined);
49
+ }
50
+ }
51
+ };
40
52
  // Provide actions to the panel when in edit mode
41
53
  let editHandlers = undefined;
42
54
  if (isEditMode) {
@@ -48,6 +60,7 @@ function GridItemContent(props) {
48
60
  }
49
61
  // map TimeSeriesQueryDefinition to Definition<UnknownSpec>
50
62
  const suggestedStepMs = (0, _pluginsystem.useSuggestedStepMs)(width);
63
+ const { data: plugin } = (0, _pluginsystem.usePlugin)('Panel', panelDefinition.spec.plugin.kind);
51
64
  const queryDefinitions = queries !== null && queries !== void 0 ? queries : [];
52
65
  const definitions = queryDefinitions.map((query)=>{
53
66
  return {
@@ -64,13 +77,15 @@ function GridItemContent(props) {
64
77
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.DataQueriesProvider, {
65
78
  definitions: definitions,
66
79
  options: {
67
- suggestedStepMs
80
+ suggestedStepMs,
81
+ ...plugin === null || plugin === void 0 ? void 0 : plugin.queryOptions
68
82
  },
69
83
  queryOptions: {
70
84
  enabled: inView
71
85
  },
72
86
  children: inView && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Panel.Panel, {
73
87
  definition: panelDefinition,
88
+ readHandlers: readHandlers,
74
89
  editHandlers: editHandlers,
75
90
  panelOptions: props.panelOptions,
76
91
  panelGroupItemId: panelGroupItemId
@@ -31,9 +31,10 @@ const _GridTitle = require("./GridTitle");
31
31
  const _GridItemContent = require("./GridItemContent");
32
32
  const _GridContainer = require("./GridContainer");
33
33
  const DEFAULT_MARGIN = 10;
34
+ const ROW_HEIGHT = 30;
34
35
  const ResponsiveGridLayout = (0, _reactgridlayout.WidthProvider)(_reactgridlayout.Responsive);
35
36
  function GridLayout(props) {
36
- const { panelGroupId/*...others */ } = props;
37
+ const { panelGroupId, panelOptions, panelFullHeight } = props;
37
38
  const theme = (0, _material.useTheme)();
38
39
  const groupDefinition = (0, _context.usePanelGroup)(panelGroupId);
39
40
  const { updatePanelGroupLayouts } = (0, _context.usePanelGroupActions)(panelGroupId);
@@ -41,13 +42,49 @@ function GridLayout(props) {
41
42
  const [isOpen, setIsOpen] = (0, _react.useState)((_ref = !groupDefinition.isCollapsed) !== null && _ref !== void 0 ? _ref : true);
42
43
  const { isEditMode } = (0, _context.useEditMode)();
43
44
  const [gridColWidth, setGridColWidth] = (0, _react.useState)(0);
45
+ const viewPanelItemId = (0, _context.useViewPanel)();
46
+ const hasViewPanel = (viewPanelItemId === null || viewPanelItemId === void 0 ? void 0 : viewPanelItemId.panelGroupId) === panelGroupId; // current panelGroup contains the panel extended?
47
+ const itemLayoutViewed = viewPanelItemId === null || viewPanelItemId === void 0 ? void 0 : viewPanelItemId.panelGroupItemLayoutId;
48
+ // If there is a panel in view mode, we should hide the grid if the panel is not in the current group.
49
+ const isGridDisplayed = (0, _react.useMemo)(()=>{
50
+ if (viewPanelItemId === undefined) {
51
+ return true;
52
+ }
53
+ return hasViewPanel;
54
+ }, [
55
+ hasViewPanel,
56
+ viewPanelItemId
57
+ ]);
58
+ // Item layout is override if there is a panel in view mode
59
+ const itemLayouts = (0, _react.useMemo)(()=>{
60
+ if (itemLayoutViewed) {
61
+ return groupDefinition.itemLayouts.map((itemLayout)=>{
62
+ if (itemLayout.i === itemLayoutViewed) {
63
+ const rowTitleHeight = 40 + 8; // 40 is the height of the row title and 8 is the margin height
64
+ return {
65
+ h: Math.round(((panelFullHeight !== null && panelFullHeight !== void 0 ? panelFullHeight : window.innerHeight) - rowTitleHeight) / (ROW_HEIGHT + DEFAULT_MARGIN)),
66
+ i: itemLayoutViewed,
67
+ w: 48,
68
+ x: 0,
69
+ y: 0
70
+ };
71
+ }
72
+ return itemLayout;
73
+ });
74
+ }
75
+ return groupDefinition.itemLayouts;
76
+ }, [
77
+ groupDefinition.itemLayouts,
78
+ itemLayoutViewed,
79
+ panelFullHeight
80
+ ]);
44
81
  const handleLayoutChange = (currentLayout, allLayouts)=>{
45
82
  // Using the value from `allLayouts` instead of `currentLayout` because of
46
83
  // a bug in react-layout-grid where `currentLayout` does not adjust properly
47
84
  // when going to a smaller breakpoint and then back to a larger breakpoint.
48
85
  // https://github.com/react-grid-layout/react-grid-layout/issues/1663
49
86
  const smallLayout = allLayouts[_constants.GRID_LAYOUT_SMALL_BREAKPOINT];
50
- if (smallLayout) {
87
+ if (smallLayout && !hasViewPanel) {
51
88
  updatePanelGroupLayouts(smallLayout);
52
89
  }
53
90
  };
@@ -62,6 +99,9 @@ function GridLayout(props) {
62
99
  setGridColWidth((containerWidth - marginWidth - containerPaddingWidth) / cols);
63
100
  };
64
101
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_GridContainer.GridContainer, {
102
+ sx: {
103
+ display: isGridDisplayed ? 'block' : 'none'
104
+ },
65
105
  children: [
66
106
  groupDefinition.title !== undefined && /*#__PURE__*/ (0, _jsxruntime.jsx)(_GridTitle.GridTitle, {
67
107
  panelGroupId: panelGroupId,
@@ -83,13 +123,13 @@ function GridLayout(props) {
83
123
  xxs: 0
84
124
  },
85
125
  cols: _constants.GRID_LAYOUT_COLS,
86
- rowHeight: 30,
126
+ rowHeight: ROW_HEIGHT,
87
127
  draggableHandle: ".drag-handle",
88
128
  resizeHandles: [
89
129
  'se'
90
130
  ],
91
- isDraggable: isEditMode,
92
- isResizable: isEditMode,
131
+ isDraggable: isEditMode && !hasViewPanel,
132
+ isResizable: isEditMode && !hasViewPanel,
93
133
  margin: [
94
134
  DEFAULT_MARGIN,
95
135
  DEFAULT_MARGIN
@@ -99,15 +139,19 @@ function GridLayout(props) {
99
139
  10
100
140
  ],
101
141
  layouts: {
102
- [_constants.GRID_LAYOUT_SMALL_BREAKPOINT]: groupDefinition.itemLayouts
142
+ [_constants.GRID_LAYOUT_SMALL_BREAKPOINT]: itemLayouts
103
143
  },
104
144
  onLayoutChange: handleLayoutChange,
105
145
  onWidthChange: handleWidthChange,
106
- children: groupDefinition.itemLayouts.map(({ i, w })=>/*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
146
+ allowOverlap: hasViewPanel,
147
+ children: itemLayouts.map(({ i, w })=>/*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
148
+ style: {
149
+ display: itemLayoutViewed !== undefined ? itemLayoutViewed === i ? 'unset' : 'none' : 'unset'
150
+ },
107
151
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ErrorBoundary, {
108
152
  FallbackComponent: _components.ErrorAlert,
109
153
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_GridItemContent.GridItemContent, {
110
- panelOptions: props.panelOptions,
154
+ panelOptions: panelOptions,
111
155
  panelGroupItemId: {
112
156
  panelGroupId,
113
157
  panelGroupItemLayoutId: i
@@ -34,7 +34,7 @@ function _interop_require_default(obj) {
34
34
  }
35
35
  const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
36
36
  var _panelOptions_extra;
37
- const { definition, editHandlers, onMouseEnter, onMouseLeave, sx, panelOptions, panelGroupItemId, ...others } = props;
37
+ const { definition, readHandlers, editHandlers, onMouseEnter, onMouseLeave, sx, panelOptions, panelGroupItemId, ...others } = props;
38
38
  // Make sure we have an ID we can use for aria attributes
39
39
  const generatedPanelId = (0, _components.useId)('Panel');
40
40
  const headerId = `${generatedPanelId}-header`;
@@ -75,7 +75,7 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
75
75
  "data-testid": "panel",
76
76
  ...others,
77
77
  children: [
78
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelHeader.PanelHeader, {
78
+ !(panelOptions === null || panelOptions === void 0 ? void 0 : panelOptions.hideHeader) && /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelHeader.PanelHeader, {
79
79
  extra: panelOptions === null || panelOptions === void 0 ? void 0 : (_panelOptions_extra = panelOptions.extra) === null || _panelOptions_extra === void 0 ? void 0 : _panelOptions_extra.call(panelOptions, {
80
80
  panelDefinition: definition,
81
81
  panelGroupItemId
@@ -83,6 +83,7 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
83
83
  id: headerId,
84
84
  title: definition.spec.display.name,
85
85
  description: definition.spec.display.description,
86
+ readHandlers: readHandlers,
86
87
  editHandlers: editHandlers,
87
88
  links: definition.spec.links,
88
89
  sx: {
@@ -27,6 +27,8 @@ const _InformationOutline = /*#__PURE__*/ _interop_require_default(require("mdi-
27
27
  const _PencilOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/PencilOutline"));
28
28
  const _DeleteOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/DeleteOutline"));
29
29
  const _DragVertical = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/DragVertical"));
30
+ const _ArrowExpand = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowExpand"));
31
+ const _ArrowCollapse = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowCollapse"));
30
32
  const _ContentCopy = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ContentCopy"));
31
33
  const _pluginsystem = require("@perses-dev/plugin-system");
32
34
  const _constants = require("../../constants");
@@ -36,15 +38,31 @@ function _interop_require_default(obj) {
36
38
  default: obj
37
39
  };
38
40
  }
39
- function PanelHeader({ id, title: rawTitle, description: rawDescription, links, editHandlers, sx, extra, ...rest }) {
41
+ function PanelHeader({ id, title: rawTitle, description: rawDescription, links, readHandlers, editHandlers, sx, extra, ...rest }) {
40
42
  const titleElementId = `${id}-title`;
41
43
  const descriptionTooltipId = `${id}-description`;
42
44
  const title = (0, _pluginsystem.useReplaceVariablesInString)(rawTitle);
43
45
  const description = (0, _pluginsystem.useReplaceVariablesInString)(rawDescription);
44
- let actions = undefined;
46
+ let readActions = undefined;
47
+ if (readHandlers !== undefined) {
48
+ readActions = /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
49
+ description: _constants.TOOLTIP_TEXT.viewPanel,
50
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(HeaderIconButton, {
51
+ "aria-label": _constants.ARIA_LABEL_TEXT.viewPanel(title),
52
+ size: "small",
53
+ onClick: readHandlers.onViewPanelClick,
54
+ children: readHandlers.isPanelViewed ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_ArrowCollapse.default, {
55
+ fontSize: "inherit"
56
+ }) : /*#__PURE__*/ (0, _jsxruntime.jsx)(_ArrowExpand.default, {
57
+ fontSize: "inherit"
58
+ })
59
+ })
60
+ });
61
+ }
62
+ let editActions = undefined;
45
63
  if (editHandlers !== undefined) {
46
64
  // If there are edit handlers, always just show the edit buttons
47
- actions = /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
65
+ editActions = /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
48
66
  children: [
49
67
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
50
68
  description: _constants.TOOLTIP_TEXT.editPanel,
@@ -153,7 +171,9 @@ function PanelHeader({ id, title: rawTitle, description: rawDescription, links,
153
171
  children: [
154
172
  editHandlers === undefined && extra,
155
173
  " ",
156
- actions
174
+ readActions,
175
+ " ",
176
+ editActions
157
177
  ]
158
178
  }),
159
179
  sx: (0, _components.combineSx)((theme)=>({
@@ -34,6 +34,10 @@ function PanelPreview({ panelDefinition }) {
34
34
  width = boxRef.current.getBoundingClientRect().width;
35
35
  }
36
36
  const suggestedStepMs = (0, _pluginsystem.useSuggestedStepMs)(width);
37
+ const { data: plugin, isLoading } = (0, _pluginsystem.usePlugin)('Panel', panelDefinition.spec.plugin.kind);
38
+ if (isLoading) {
39
+ return null;
40
+ }
37
41
  if (panelDefinition.spec.plugin.kind === '') {
38
42
  return null;
39
43
  }
@@ -52,7 +56,8 @@ function PanelPreview({ panelDefinition }) {
52
56
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_pluginsystem.DataQueriesProvider, {
53
57
  definitions: definitions,
54
58
  options: {
55
- suggestedStepMs
59
+ suggestedStepMs,
60
+ ...plugin === null || plugin === void 0 ? void 0 : plugin.queryOptions
56
61
  },
57
62
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Panel.Panel, {
58
63
  definition: panelDefinition
@@ -52,9 +52,12 @@ function TemplateVariableList() {
52
52
  function TemplateVariableListItem({ spec, source }) {
53
53
  var _ctx_state, _spec_display;
54
54
  const ctx = (0, _context.useTemplateVariable)(spec.name, source);
55
+ if ((_ctx_state = ctx.state) === null || _ctx_state === void 0 ? void 0 : _ctx_state.overridden) {
56
+ return null;
57
+ }
55
58
  var _ref, _ref1;
56
59
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
57
- display: ((_ctx_state = ctx.state) === null || _ctx_state === void 0 ? void 0 : _ctx_state.overridden) || ((_spec_display = spec.display) === null || _spec_display === void 0 ? void 0 : _spec_display.hidden) ? 'none' : undefined,
60
+ display: ((_spec_display = spec.display) === null || _spec_display === void 0 ? void 0 : _spec_display.hidden) ? 'none' : undefined,
58
61
  minWidth: `${_constants.MIN_TEMPLATE_VARIABLE_WIDTH}px`,
59
62
  maxWidth: `${_constants.MAX_TEMPLATE_VARIABLE_WIDTH}px`,
60
63
  flexShrink: 0,
@@ -44,6 +44,7 @@ const TOOLTIP_TEXT = {
44
44
  moveGroupDown: 'Move group down',
45
45
  moveGroupUp: 'Move group up',
46
46
  // Panel buttons
47
+ viewPanel: 'Toggle View Mode',
47
48
  editPanel: 'Edit',
48
49
  duplicatePanel: 'Duplicate',
49
50
  deletePanel: 'Delete',
@@ -60,6 +61,7 @@ const ARIA_LABEL_TEXT = {
60
61
  moveGroupDown: (groupName)=>`move group ${groupName} down`,
61
62
  moveGroupUp: (groupName)=>`move group ${groupName} up`,
62
63
  // Panel buttons
64
+ viewPanel: (panelName)=>`toggle panel ${panelName} view mode`,
63
65
  editPanel: (panelName)=>`edit panel ${panelName}`,
64
66
  duplicatePanel: (panelName)=>`duplicate panel ${panelName}`,
65
67
  deletePanel: (panelName)=>`delete panel ${panelName}`,
@@ -50,6 +50,7 @@ const _savechangesdialogslice = require("./save-changes-dialog-slice");
50
50
  const _duplicatepanelslice = require("./duplicate-panel-slice");
51
51
  const _editjsondialogslice = require("./edit-json-dialog-slice");
52
52
  const _common = require("./common");
53
+ const _viewpanelslice = require("./view-panel-slice");
53
54
  const DashboardContext = /*#__PURE__*/ (0, _react.createContext)(undefined);
54
55
  function useDashboardStore(selector) {
55
56
  const store = (0, _react.useContext)(DashboardContext);
@@ -88,7 +89,7 @@ function DashboardProvider(props) {
88
89
  });
89
90
  }
90
91
  function initStore(props) {
91
- const { initialState: { dashboardResource, isEditMode } } = props;
92
+ const { initialState: { dashboardResource, isEditMode, viewPanelRef, setViewPanelRef } } = props;
92
93
  const { kind, metadata, spec: { display, duration, refreshInterval = _core.DEFAULT_REFRESH_INTERVAL, datasources } } = dashboardResource;
93
94
  const ttl = 'ttl' in dashboardResource.spec ? dashboardResource.spec.ttl : undefined;
94
95
  let { spec: { layouts, panels } } = dashboardResource;
@@ -105,6 +106,7 @@ function initStore(props) {
105
106
  ...(0, _paneleditorslice.createPanelEditorSlice)()(...args),
106
107
  ...(0, _deletepanelslice.createDeletePanelSlice)()(...args),
107
108
  ...(0, _duplicatepanelslice.createDuplicatePanelSlice)()(...args),
109
+ ...(0, _viewpanelslice.createViewPanelSlice)(viewPanelRef, setViewPanelRef)(...args),
108
110
  /* General */ ...(0, _discardchangesdialogslice.createDiscardChangesDialogSlice)(...args),
109
111
  ...(0, _editjsondialogslice.createEditJsonDialogSlice)(...args),
110
112
  ...(0, _savechangesdialogslice.createSaveChangesDialogSlice)(...args),
@@ -0,0 +1,36 @@
1
+ // Copyright 2024 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, "DashboardProviderWithQueryParams", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return DashboardProviderWithQueryParams;
21
+ }
22
+ });
23
+ const _jsxruntime = require("react/jsx-runtime");
24
+ const _usequeryparams = require("use-query-params");
25
+ const _DashboardProvider = require("./DashboardProvider");
26
+ function DashboardProviderWithQueryParams({ children, initialState }) {
27
+ const [viewPanelRef, setViewPanelRef] = (0, _usequeryparams.useQueryParam)('viewPanelRef', _usequeryparams.StringParam);
28
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_DashboardProvider.DashboardProvider, {
29
+ initialState: {
30
+ viewPanelRef: viewPanelRef !== null && viewPanelRef !== void 0 ? viewPanelRef : undefined,
31
+ setViewPanelRef: setViewPanelRef,
32
+ ...initialState
33
+ },
34
+ children: children
35
+ });
36
+ }
@@ -68,6 +68,9 @@ _export(exports, {
68
68
  },
69
69
  useSaveChangesConfirmationDialog: function() {
70
70
  return useSaveChangesConfirmationDialog;
71
+ },
72
+ useViewPanel: function() {
73
+ return useViewPanel;
71
74
  }
72
75
  });
73
76
  const _react = require("react");
@@ -196,17 +199,19 @@ function usePanel(panelGroupItemId) {
196
199
  }
197
200
  return panel;
198
201
  }
199
- const selectPanelActions = ({ openEditPanel, openDeletePanelDialog, duplicatePanel })=>({
202
+ const selectPanelActions = ({ openEditPanel, openDeletePanelDialog, duplicatePanel, setViewPanel })=>({
200
203
  openEditPanel,
201
204
  openDeletePanelDialog,
202
- duplicatePanel
205
+ duplicatePanel,
206
+ setViewPanel
203
207
  });
204
208
  function usePanelActions(panelGroupItemId) {
205
- const { openEditPanel, openDeletePanelDialog, duplicatePanel } = (0, _DashboardProvider.useDashboardStore)(selectPanelActions);
209
+ const { openEditPanel, openDeletePanelDialog, duplicatePanel, setViewPanel } = (0, _DashboardProvider.useDashboardStore)(selectPanelActions);
206
210
  return {
207
211
  openEditPanel: ()=>openEditPanel(panelGroupItemId),
208
212
  openDeletePanelDialog: ()=>openDeletePanelDialog(panelGroupItemId),
209
- duplicatePanel: ()=>duplicatePanel(panelGroupItemId)
213
+ duplicatePanel: ()=>duplicatePanel(panelGroupItemId),
214
+ viewPanel: (panelGroupItemId)=>setViewPanel(panelGroupItemId)
210
215
  };
211
216
  }
212
217
  const selectPanelEditor = (state)=>state.panelEditor;
@@ -226,6 +231,10 @@ const selectDashboardDuration = (state)=>state.duration;
226
231
  function useDashboardDuration() {
227
232
  return (0, _DashboardProvider.useDashboardStore)(selectDashboardDuration);
228
233
  }
234
+ const selectViewPanel = (state)=>state.getViewPanel();
235
+ function useViewPanel() {
236
+ return (0, _DashboardProvider.useDashboardStore)(selectViewPanel);
237
+ }
229
238
  const selectSaveChangesConfirmationDialog = ({ saveChangesConfirmationDialog, openSaveChangesConfirmationDialog, closeSaveChangesConfirmationDialog })=>({
230
239
  saveChangesConfirmationDialog,
231
240
  openSaveChangesConfirmationDialog,
@@ -32,10 +32,16 @@ _export(exports, {
32
32
  },
33
33
  createPanelGroupSlice: function() {
34
34
  return createPanelGroupSlice;
35
+ },
36
+ isPanelGroupItemIdEqual: function() {
37
+ return isPanelGroupItemIdEqual;
35
38
  }
36
39
  });
37
40
  const _core = require("@perses-dev/core");
38
41
  const _common = require("./common");
42
+ function isPanelGroupItemIdEqual(a, b) {
43
+ return (a === null || a === void 0 ? void 0 : a.panelGroupId) === (b === null || b === void 0 ? void 0 : b.panelGroupId) && (a === null || a === void 0 ? void 0 : a.panelGroupItemLayoutId) === (b === null || b === void 0 ? void 0 : b.panelGroupItemLayoutId);
44
+ }
39
45
  function createPanelGroupSlice(layouts) {
40
46
  const { panelGroups, panelGroupOrder } = convertLayoutsToPanelGroups(layouts);
41
47
  // Return the state creator function for Zustand
@@ -0,0 +1,80 @@
1
+ // Copyright 2023 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, "createViewPanelSlice", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return createViewPanelSlice;
21
+ }
22
+ });
23
+ function createViewPanelSlice(viewPanelRef, setViewPanelRef) {
24
+ return (set, get)=>({
25
+ viewPanel: {
26
+ panelGroupItemId: undefined,
27
+ panelRef: viewPanelRef
28
+ },
29
+ getViewPanel () {
30
+ return getViewPanelGroupId(get().panelGroups, get().viewPanel.panelGroupItemId, get().viewPanel.panelRef);
31
+ },
32
+ setViewPanel (panelGroupItemId) {
33
+ set((state)=>{
34
+ state.viewPanel = {
35
+ panelRef: undefined,
36
+ panelGroupItemId: panelGroupItemId
37
+ };
38
+ const panelRef = findPanelRefOfPanelGroupItemId(get().panelGroups, panelGroupItemId);
39
+ if (setViewPanelRef) {
40
+ setViewPanelRef(panelRef);
41
+ }
42
+ });
43
+ }
44
+ });
45
+ }
46
+ function getViewPanelGroupId(panelGroups, panelGroupItemId, panelRef) {
47
+ if (panelGroupItemId) {
48
+ return panelGroupItemId;
49
+ }
50
+ if (panelRef) {
51
+ return findPanelGroupItemIdOfPanelRef(panelGroups, panelRef);
52
+ }
53
+ return undefined;
54
+ }
55
+ // Find the PanelGroupItemId of a Panel from a PanelRef
56
+ function findPanelGroupItemIdOfPanelRef(panelGroups, panelRef) {
57
+ for (const panelGroup of Object.values(panelGroups)){
58
+ var _panelGroup_itemPanelKeys;
59
+ const itemPanel = Object.entries((_panelGroup_itemPanelKeys = panelGroup.itemPanelKeys) !== null && _panelGroup_itemPanelKeys !== void 0 ? _panelGroup_itemPanelKeys : []).find(([_, value])=>value === panelRef);
60
+ if (itemPanel) {
61
+ const [key] = itemPanel;
62
+ return {
63
+ panelGroupId: panelGroup.id,
64
+ panelGroupItemLayoutId: key
65
+ };
66
+ }
67
+ }
68
+ return undefined;
69
+ }
70
+ // Find the PanelRef from a PanelGroupItemId
71
+ function findPanelRefOfPanelGroupItemId(panelGroups, panelGroupItemId) {
72
+ if (!panelGroupItemId) {
73
+ return undefined;
74
+ }
75
+ const panelGroup = panelGroups[panelGroupItemId.panelGroupId];
76
+ if (panelGroup) {
77
+ return panelGroup.itemPanelKeys[panelGroupItemId.panelGroupItemLayoutId];
78
+ }
79
+ return undefined;
80
+ }
@@ -27,6 +27,7 @@ const _components = require("@perses-dev/components");
27
27
  const _pluginsystem = require("@perses-dev/plugin-system");
28
28
  const _react = require("react");
29
29
  const _context = require("../../context");
30
+ const _DashboardProviderWithQueryParams = require("../../context/DashboardProvider/DashboardProviderWithQueryParams");
30
31
  const _DashboardApp = require("./DashboardApp");
31
32
  function ViewDashboard(props) {
32
33
  const { dashboardResource, datasourceApi, externalVariableDefinitions, dashboardTitleComponent, emptyDashboardProps, onSave, onDiscard, initialVariableIsSticky, isReadonly, isEditing, isCreating, sx, ...others } = props;
@@ -79,7 +80,7 @@ function ViewDashboard(props) {
79
80
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_context.DatasourceStoreProvider, {
80
81
  dashboardResource: dashboardResource,
81
82
  datasourceApi: datasourceApi,
82
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_context.DashboardProvider, {
83
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_DashboardProviderWithQueryParams.DashboardProviderWithQueryParams, {
83
84
  initialState: {
84
85
  dashboardResource,
85
86
  isEditMode: !!isEditing
@@ -1 +1 @@
1
- {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../../../src/components/Dashboard/Dashboard.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAO,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9C,OAAO,EAAkB,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG;IACtC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,mBAAmB,EAAE,YAAY,EAAE,GAAG,QAAQ,EAAE,EAAE,cAAc,2CAmB3F"}
1
+ {"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../../../src/components/Dashboard/Dashboard.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAO,QAAQ,EAAE,MAAM,eAAe,CAAC;AAK9C,OAAO,EAAkB,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG;IACtC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAGF;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,mBAAmB,EAAE,YAAY,EAAE,GAAG,QAAQ,EAAE,EAAE,cAAc,2CA2B3F"}
@@ -13,19 +13,27 @@
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import { Box } from '@mui/material';
15
15
  import { ErrorBoundary, ErrorAlert } from '@perses-dev/components';
16
+ import { useRef } from 'react';
16
17
  import { usePanelGroupIds } from '../../context';
17
18
  import { GridLayout } from '../GridLayout';
18
19
  import { EmptyDashboard } from '../EmptyDashboard';
20
+ const HEADER_HEIGHT = 165; // Approximate height of the header in dashboard view (including the navbar and variables toolbar)
19
21
  /**
20
22
  * Renders a Dashboard for the provided Dashboard spec.
21
23
  */ export function Dashboard({ emptyDashboardProps, panelOptions, ...boxProps }) {
24
+ var _boxRef_current;
22
25
  const panelGroupIds = usePanelGroupIds();
26
+ const boxRef = useRef(null);
23
27
  const isEmpty = !panelGroupIds.length;
28
+ var _boxRef_current_getBoundingClientRect_top;
29
+ const dashboardTopPosition = (_boxRef_current_getBoundingClientRect_top = (_boxRef_current = boxRef.current) === null || _boxRef_current === void 0 ? void 0 : _boxRef_current.getBoundingClientRect().top) !== null && _boxRef_current_getBoundingClientRect_top !== void 0 ? _boxRef_current_getBoundingClientRect_top : HEADER_HEIGHT;
30
+ const panelFullHeight = window.innerHeight - dashboardTopPosition - window.scrollY;
24
31
  return /*#__PURE__*/ _jsx(Box, {
25
32
  ...boxProps,
26
33
  sx: {
27
34
  height: '100%'
28
35
  },
36
+ ref: boxRef,
29
37
  children: /*#__PURE__*/ _jsxs(ErrorBoundary, {
30
38
  FallbackComponent: ErrorAlert,
31
39
  children: [
@@ -41,7 +49,8 @@ import { EmptyDashboard } from '../EmptyDashboard';
41
49
  }),
42
50
  !isEmpty && panelGroupIds.map((panelGroupId)=>/*#__PURE__*/ _jsx(GridLayout, {
43
51
  panelGroupId: panelGroupId,
44
- panelOptions: panelOptions
52
+ panelOptions: panelOptions,
53
+ panelFullHeight: panelFullHeight
45
54
  }, panelGroupId))
46
55
  ]
47
56
  })