@perses-dev/dashboards 0.0.0-snapshot-explorer-plugin-c4a7621 → 0.0.0-snapshot-profile-8090608

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 (136) hide show
  1. package/dist/cjs/components/DashboardToolbar/DashboardToolbar.js +3 -3
  2. package/dist/cjs/components/DeletePanelDialog/DeletePanelDialog.js +2 -0
  3. package/dist/cjs/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +2 -0
  4. package/dist/cjs/components/DownloadButton/DownloadButton.js +135 -29
  5. package/dist/cjs/components/GridLayout/GridItemContent.js +3 -2
  6. package/dist/cjs/components/GridLayout/GridLayout.js +6 -10
  7. package/dist/cjs/components/Panel/Panel.js +6 -2
  8. package/dist/cjs/components/Panel/PanelActions.js +204 -55
  9. package/dist/cjs/components/Panel/PanelContent.js +56 -10
  10. package/dist/cjs/components/Panel/PanelHeader.js +10 -46
  11. package/dist/cjs/components/Panel/PanelPluginLoader.js +56 -0
  12. package/dist/cjs/components/Panel/index.js +1 -0
  13. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +21 -9
  14. package/dist/cjs/components/Variables/Variable.js +10 -1
  15. package/dist/cjs/constants/styles.js +7 -3
  16. package/dist/cjs/constants/user-interface-text.js +1 -2
  17. package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +12 -1
  18. package/dist/cjs/context/VariableProvider/VariableProvider.js +16 -20
  19. package/dist/cjs/test/datasource-provider.js +1 -1
  20. package/dist/cjs/test/plugin-registry.js +4 -1
  21. package/dist/cjs/views/ViewDashboard/DashboardApp.js +4 -1
  22. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +3 -1
  23. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts +2 -0
  24. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
  25. package/dist/components/DashboardToolbar/DashboardToolbar.js +3 -3
  26. package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
  27. package/dist/components/Datasources/DatasourceEditor.js.map +1 -1
  28. package/dist/components/DeletePanelDialog/DeletePanelDialog.js +3 -1
  29. package/dist/components/DeletePanelDialog/DeletePanelDialog.js.map +1 -1
  30. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.d.ts.map +1 -1
  31. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +3 -1
  32. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
  33. package/dist/components/DownloadButton/DownloadButton.d.ts +1 -5
  34. package/dist/components/DownloadButton/DownloadButton.d.ts.map +1 -1
  35. package/dist/components/DownloadButton/DownloadButton.js +94 -29
  36. package/dist/components/DownloadButton/DownloadButton.js.map +1 -1
  37. package/dist/components/GridLayout/GridContainer.js.map +1 -1
  38. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  39. package/dist/components/GridLayout/GridItemContent.js +4 -3
  40. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  41. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  42. package/dist/components/GridLayout/GridLayout.js +8 -12
  43. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  44. package/dist/components/GridLayout/GridTitle.js.map +1 -1
  45. package/dist/components/Panel/HeaderIconButton.d.ts +1 -1
  46. package/dist/components/Panel/HeaderIconButton.d.ts.map +1 -1
  47. package/dist/components/Panel/Panel.d.ts +5 -0
  48. package/dist/components/Panel/Panel.d.ts.map +1 -1
  49. package/dist/components/Panel/Panel.js +11 -2
  50. package/dist/components/Panel/Panel.js.map +1 -1
  51. package/dist/components/Panel/PanelActions.d.ts +8 -2
  52. package/dist/components/Panel/PanelActions.d.ts.map +1 -1
  53. package/dist/components/Panel/PanelActions.js +208 -59
  54. package/dist/components/Panel/PanelActions.js.map +1 -1
  55. package/dist/components/Panel/PanelContent.d.ts +5 -4
  56. package/dist/components/Panel/PanelContent.d.ts.map +1 -1
  57. package/dist/components/Panel/PanelContent.js +58 -12
  58. package/dist/components/Panel/PanelContent.js.map +1 -1
  59. package/dist/components/Panel/PanelHeader.d.ts +3 -1
  60. package/dist/components/Panel/PanelHeader.d.ts.map +1 -1
  61. package/dist/components/Panel/PanelHeader.js +12 -43
  62. package/dist/components/Panel/PanelHeader.js.map +1 -1
  63. package/dist/components/Panel/PanelLinks.js.map +1 -1
  64. package/dist/components/Panel/PanelPluginLoader.d.ts +13 -0
  65. package/dist/components/Panel/PanelPluginLoader.d.ts.map +1 -0
  66. package/dist/components/Panel/PanelPluginLoader.js +51 -0
  67. package/dist/components/Panel/PanelPluginLoader.js.map +1 -0
  68. package/dist/components/Panel/index.d.ts +1 -0
  69. package/dist/components/Panel/index.d.ts.map +1 -1
  70. package/dist/components/Panel/index.js +1 -0
  71. package/dist/components/Panel/index.js.map +1 -1
  72. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  73. package/dist/components/PanelDrawer/PanelEditorForm.js +21 -9
  74. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  75. package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js.map +1 -1
  76. package/dist/components/SaveDashboardButton/SaveDashboardButton.js.map +1 -1
  77. package/dist/components/Variables/BuiltinVariableAccordions.js.map +1 -1
  78. package/dist/components/Variables/Variable.js +10 -1
  79. package/dist/components/Variables/Variable.js.map +1 -1
  80. package/dist/components/Variables/VariableEditor.js.map +1 -1
  81. package/dist/components/Variables/VariableList.js.map +1 -1
  82. package/dist/constants/styles.d.ts +2 -1
  83. package/dist/constants/styles.d.ts.map +1 -1
  84. package/dist/constants/styles.js +2 -1
  85. package/dist/constants/styles.js.map +1 -1
  86. package/dist/constants/user-interface-text.d.ts +0 -1
  87. package/dist/constants/user-interface-text.d.ts.map +1 -1
  88. package/dist/constants/user-interface-text.js +1 -2
  89. package/dist/constants/user-interface-text.js.map +1 -1
  90. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +11 -2
  91. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  92. package/dist/context/DashboardProvider/dashboard-provider-api.js +12 -2
  93. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  94. package/dist/context/DashboardProvider/delete-panel-slice.js.map +1 -1
  95. package/dist/context/DashboardProvider/duplicate-panel-slice.js.map +1 -1
  96. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  97. package/dist/context/DashboardProvider/panel-group-slice.d.ts +1 -1
  98. package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
  99. package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
  100. package/dist/context/DatasourceStoreProvider.js.map +1 -1
  101. package/dist/context/VariableProvider/VariableProvider.d.ts.map +1 -1
  102. package/dist/context/VariableProvider/VariableProvider.js +13 -12
  103. package/dist/context/VariableProvider/VariableProvider.js.map +1 -1
  104. package/dist/context/VariableProvider/query-params.js.map +1 -1
  105. package/dist/context/useDashboard.js.map +1 -1
  106. package/dist/test/datasource-provider.d.ts +1 -1
  107. package/dist/test/datasource-provider.d.ts.map +1 -1
  108. package/dist/test/datasource-provider.js +1 -1
  109. package/dist/test/datasource-provider.js.map +1 -1
  110. package/dist/test/plugin-registry.d.ts.map +1 -1
  111. package/dist/test/plugin-registry.js +4 -1
  112. package/dist/test/plugin-registry.js.map +1 -1
  113. package/dist/utils/panelUtils.js.map +1 -1
  114. package/dist/views/ViewDashboard/DashboardApp.d.ts +2 -0
  115. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  116. package/dist/views/ViewDashboard/DashboardApp.js +4 -1
  117. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  118. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  119. package/dist/views/ViewDashboard/ViewDashboard.js +3 -1
  120. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  121. package/package.json +9 -9
  122. package/dist/cjs/stories/decorators/WithDashboard.js +0 -41
  123. package/dist/cjs/stories/decorators/WithDatasourceStore.js +0 -39
  124. package/dist/cjs/stories/decorators/WithVariables.js +0 -37
  125. package/dist/cjs/stories/decorators/constants.js +0 -39
  126. package/dist/cjs/stories/decorators/index.js +0 -33
  127. package/dist/stories/decorators/WithDashboard.js +0 -33
  128. package/dist/stories/decorators/WithDashboard.js.map +0 -1
  129. package/dist/stories/decorators/WithDatasourceStore.js +0 -31
  130. package/dist/stories/decorators/WithDatasourceStore.js.map +0 -1
  131. package/dist/stories/decorators/WithVariables.js +0 -29
  132. package/dist/stories/decorators/WithVariables.js.map +0 -1
  133. package/dist/stories/decorators/constants.js +0 -31
  134. package/dist/stories/decorators/constants.js.map +0 -1
  135. package/dist/stories/decorators/index.js +0 -18
  136. package/dist/stories/decorators/index.js.map +0 -1
@@ -35,7 +35,7 @@ const _EditJsonButton = require("../EditJsonButton");
35
35
  const _SaveDashboardButton = require("../SaveDashboardButton");
36
36
  const _DashboardStickyToolbar = require("../DashboardStickyToolbar");
37
37
  const DashboardToolbar = (props)=>{
38
- const { dashboardName, dashboardTitleComponent, initialVariableIsSticky, isReadonly, onEditButtonClick, onCancelButtonClick, onSave } = props;
38
+ const { dashboardName, dashboardTitleComponent, initialVariableIsSticky, isReadonly, isVariableEnabled, isDatasourceEnabled, onEditButtonClick, onCancelButtonClick, onSave } = props;
39
39
  const { isEditMode } = (0, _context.useEditMode)();
40
40
  const isBiggerThanSm = (0, _material.useMediaQuery)((0, _material.useTheme)().breakpoints.up('sm'));
41
41
  const isBiggerThanMd = (0, _material.useMediaQuery)((0, _material.useTheme)().breakpoints.up('md'));
@@ -76,8 +76,8 @@ const DashboardToolbar = (props)=>{
76
76
  ml: 1,
77
77
  whiteSpace: "nowrap",
78
78
  children: [
79
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_Variables.EditVariablesButton, {}),
80
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_Datasources.EditDatasourcesButton, {}),
79
+ isVariableEnabled && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Variables.EditVariablesButton, {}),
80
+ isDatasourceEnabled && /*#__PURE__*/ (0, _jsxruntime.jsx)(_Datasources.EditDatasourcesButton, {}),
81
81
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_AddPanelButton.AddPanelButton, {}),
82
82
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_AddGroupButton.AddGroupButton, {})
83
83
  ]
@@ -40,11 +40,13 @@ const DeletePanelDialog = ()=>{
40
40
  };
41
41
  const DeletePanelForm = ({ deletePanelDialog })=>{
42
42
  const { deletePanel, closeDeletePanelDialog } = (0, _context.useDeletePanelDialog)();
43
+ const { setViewPanel } = (0, _context.useViewPanel)();
43
44
  const handleDelete = (e)=>{
44
45
  e.preventDefault();
45
46
  const { panelGroupItemId } = deletePanelDialog;
46
47
  deletePanel(panelGroupItemId);
47
48
  closeDeletePanelDialog();
49
+ setViewPanel(undefined);
48
50
  };
49
51
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)("form", {
50
52
  onSubmit: handleDelete,
@@ -31,6 +31,7 @@ function _interop_require_default(obj) {
31
31
  }
32
32
  const DeletePanelGroupDialog = ()=>{
33
33
  const { deletePanelGroupDialog, closeDeletePanelGroupDialog, deletePanelGroup } = (0, _context.useDeletePanelGroupDialog)();
34
+ const { setViewPanel } = (0, _context.useViewPanel)();
34
35
  const panelGroupId = deletePanelGroupDialog?.panelGroupId;
35
36
  const handleDelete = (e)=>{
36
37
  e.preventDefault();
@@ -39,6 +40,7 @@ const DeletePanelGroupDialog = ()=>{
39
40
  }
40
41
  deletePanelGroup(panelGroupId);
41
42
  closeDeletePanelGroupDialog();
43
+ setViewPanel(undefined);
42
44
  };
43
45
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Dialog, {
44
46
  open: deletePanelGroupDialog !== undefined,
@@ -21,53 +21,159 @@ Object.defineProperty(exports, "DownloadButton", {
21
21
  }
22
22
  });
23
23
  const _jsxruntime = require("react/jsx-runtime");
24
- const _react = require("react");
25
- const _DownloadOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/DownloadOutline"));
24
+ const _material = require("@mui/material");
26
25
  const _components = require("@perses-dev/components");
27
- const _constants = require("../../constants");
26
+ const _DownloadOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/DownloadOutline"));
27
+ const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
28
+ const _yaml = require("yaml");
28
29
  const _context = require("../../context");
29
30
  function _interop_require_default(obj) {
30
31
  return obj && obj.__esModule ? obj : {
31
32
  default: obj
32
33
  };
33
34
  }
34
- function DownloadButton({ heightPx }) {
35
+ function _getRequireWildcardCache(nodeInterop) {
36
+ if (typeof WeakMap !== "function") return null;
37
+ var cacheBabelInterop = new WeakMap();
38
+ var cacheNodeInterop = new WeakMap();
39
+ return (_getRequireWildcardCache = function(nodeInterop) {
40
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
41
+ })(nodeInterop);
42
+ }
43
+ function _interop_require_wildcard(obj, nodeInterop) {
44
+ if (!nodeInterop && obj && obj.__esModule) {
45
+ return obj;
46
+ }
47
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
48
+ return {
49
+ default: obj
50
+ };
51
+ }
52
+ var cache = _getRequireWildcardCache(nodeInterop);
53
+ if (cache && cache.has(obj)) {
54
+ return cache.get(obj);
55
+ }
56
+ var newObj = {
57
+ __proto__: null
58
+ };
59
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
60
+ for(var key in obj){
61
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
62
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
63
+ if (desc && (desc.get || desc.set)) {
64
+ Object.defineProperty(newObj, key, desc);
65
+ } else {
66
+ newObj[key] = obj[key];
67
+ }
68
+ }
69
+ }
70
+ newObj.default = obj;
71
+ if (cache) {
72
+ cache.set(obj, newObj);
73
+ }
74
+ return newObj;
75
+ }
76
+ function DownloadButton() {
35
77
  const { dashboard } = (0, _context.useDashboard)();
36
78
  const hiddenLinkRef = (0, _react.useRef)(null);
37
- const height = heightPx === undefined ? undefined : `${heightPx}px`;
38
- const onDownloadButtonClick = ()=>{
39
- if (!hiddenLinkRef || !hiddenLinkRef.current) return;
40
- // Create blob URL
41
- const hiddenLinkUrl = URL.createObjectURL(new Blob([
42
- JSON.stringify(dashboard)
43
- ], {
44
- type: 'application/json'
45
- }));
46
- // Simulate click
47
- hiddenLinkRef.current.href = hiddenLinkUrl;
48
- hiddenLinkRef.current.click();
49
- // Remove blob URL (for memory management)
50
- URL.revokeObjectURL(hiddenLinkUrl);
79
+ const [anchorEl, setAnchorEl] = _react.default.useState(null);
80
+ const open = Boolean(anchorEl);
81
+ const handleClick = (event)=>{
82
+ setAnchorEl(event.currentTarget);
51
83
  };
84
+ const handleItemClick = (format, shape)=>()=>{
85
+ setAnchorEl(null);
86
+ let type, content = '';
87
+ switch(format){
88
+ case 'json':
89
+ type = 'application/json';
90
+ content = JSON.stringify(dashboard, null, 2);
91
+ break;
92
+ case 'yaml':
93
+ {
94
+ type = 'application/yaml';
95
+ if (shape === 'cr') {
96
+ const name = dashboard.metadata.name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
97
+ content = (0, _yaml.stringify)({
98
+ apiVersion: 'perses.dev/v1alpha1',
99
+ kind: 'PersesDashboard',
100
+ metadata: {
101
+ labels: {
102
+ 'app.kubernetes.io/name': 'perses-dashboard',
103
+ 'app.kubernetes.io/instance': name,
104
+ 'app.kubernetes.io/part-of': 'perses-operator'
105
+ },
106
+ name
107
+ },
108
+ namespace: dashboard.metadata.project,
109
+ spec: dashboard.spec
110
+ });
111
+ } else {
112
+ content = (0, _yaml.stringify)(dashboard);
113
+ }
114
+ }
115
+ break;
116
+ }
117
+ if (!hiddenLinkRef || !hiddenLinkRef.current) return;
118
+ // Create blob URL
119
+ const hiddenLinkUrl = URL.createObjectURL(new Blob([
120
+ content
121
+ ], {
122
+ type
123
+ }));
124
+ // Simulate click
125
+ hiddenLinkRef.current.download = `${dashboard.metadata.name}${shape === 'cr' ? '-cr' : ''}.${format}`;
126
+ hiddenLinkRef.current.href = hiddenLinkUrl;
127
+ hiddenLinkRef.current.click();
128
+ // Remove blob URL (for memory management)
129
+ URL.revokeObjectURL(hiddenLinkUrl);
130
+ };
52
131
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
53
132
  children: [
54
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
55
- description: _constants.TOOLTIP_TEXT.downloadDashboard,
56
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ToolbarIconButton, {
57
- "aria-label": _constants.TOOLTIP_TEXT.downloadDashboard,
58
- onClick: onDownloadButtonClick,
59
- sx: {
60
- height
61
- },
62
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_DownloadOutline.default, {})
133
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.ToolbarIconButton, {
134
+ id: "download-dashboard-button",
135
+ "aria-controls": open ? 'basic-menu' : undefined,
136
+ "aria-haspopup": "true",
137
+ "aria-expanded": open ? 'true' : undefined,
138
+ onClick: handleClick,
139
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_DownloadOutline.default, {})
140
+ }),
141
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Menu, {
142
+ id: "download-dashboard-formats",
143
+ anchorEl: anchorEl,
144
+ open: open,
145
+ hideBackdrop: true,
146
+ onClose: ()=>setAnchorEl(null),
147
+ MenuListProps: {
148
+ 'aria-labelledby': 'download-dashboard-button'
149
+ },
150
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
151
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.ClickAwayListener, {
152
+ onClickAway: ()=>setAnchorEl(null),
153
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.MenuList, {
154
+ children: [
155
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
156
+ onClick: handleItemClick('json'),
157
+ children: "JSON"
158
+ }),
159
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
160
+ onClick: handleItemClick('yaml'),
161
+ children: "YAML"
162
+ }),
163
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.MenuItem, {
164
+ onClick: handleItemClick('yaml', 'cr'),
165
+ children: "YAML (CR)"
166
+ })
167
+ ]
168
+ })
169
+ })
63
170
  })
64
171
  }),
65
172
  /*#__PURE__*/ (0, _jsxruntime.jsx)("a", {
66
173
  ref: hiddenLinkRef,
67
174
  style: {
68
175
  display: 'none'
69
- },
70
- download: `${dashboard.metadata.name}.json`
176
+ }
71
177
  })
72
178
  ]
73
179
  });
@@ -33,7 +33,7 @@ function GridItemContent(props) {
33
33
  const { spec: { queries } } = panelDefinition;
34
34
  const { isEditMode } = (0, _context.useEditMode)();
35
35
  const { openEditPanel, openDeletePanelDialog, duplicatePanel, viewPanel } = (0, _context.usePanelActions)(panelGroupItemId);
36
- const viewPanelGroupItemId = (0, _context.useViewPanel)();
36
+ const viewPanelGroupItemId = (0, _context.useViewPanelGroup)();
37
37
  const { ref, inView } = (0, _reactintersectionobserver.useInView)({
38
38
  threshold: 0.2,
39
39
  initialInView: false,
@@ -68,6 +68,7 @@ function GridItemContent(props) {
68
68
  spec: query.spec.plugin.spec
69
69
  };
70
70
  });
71
+ const pluginQueryOptions = typeof plugin?.queryOptions === 'function' ? plugin?.queryOptions(panelDefinition.spec.plugin.spec) : plugin?.queryOptions;
71
72
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
72
73
  ref: ref,
73
74
  sx: {
@@ -78,7 +79,7 @@ function GridItemContent(props) {
78
79
  definitions: definitions,
79
80
  options: {
80
81
  suggestedStepMs,
81
- ...plugin?.queryOptions
82
+ ...pluginQueryOptions
82
83
  },
83
84
  queryOptions: {
84
85
  enabled: inView
@@ -37,25 +37,21 @@ function GridLayout(props) {
37
37
  const theme = (0, _material.useTheme)();
38
38
  const groupDefinition = (0, _context.usePanelGroup)(panelGroupId);
39
39
  const { updatePanelGroupLayouts } = (0, _context.usePanelGroupActions)(panelGroupId);
40
- const [isOpen, setIsOpen] = (0, _react.useState)(!groupDefinition.isCollapsed ?? true);
40
+ const [isOpen, setIsOpen] = (0, _react.useState)(!groupDefinition.isCollapsed);
41
41
  const { isEditMode } = (0, _context.useEditMode)();
42
42
  const [gridColWidth, setGridColWidth] = (0, _react.useState)(0);
43
- const viewPanelItemId = (0, _context.useViewPanel)();
43
+ const viewPanelItemId = (0, _context.useViewPanelGroup)();
44
44
  const hasViewPanel = viewPanelItemId?.panelGroupId === panelGroupId; // current panelGroup contains the panel extended?
45
45
  const itemLayoutViewed = viewPanelItemId?.panelGroupItemLayoutId;
46
- // If there is a panel in view mode, we should hide the grid if the panel is not in the current group.
47
- const isGridDisplayed = (0, _react.useMemo)(()=>{
48
- if (viewPanelItemId === undefined) {
49
- return true;
50
- }
46
+ (0, _react.useEffect)(()=>{
51
47
  if (hasViewPanel) {
52
48
  setIsOpen(true);
53
49
  }
54
- return hasViewPanel;
55
50
  }, [
56
- hasViewPanel,
57
- viewPanelItemId
51
+ hasViewPanel
58
52
  ]);
53
+ // If there is a panel in view mode, we should hide the grid if the panel is not in the current group.
54
+ const isGridDisplayed = viewPanelItemId === undefined || hasViewPanel;
59
55
  // Item layout is override if there is a panel in view mode
60
56
  const itemLayouts = (0, _react.useMemo)(()=>{
61
57
  if (itemLayoutViewed) {
@@ -23,6 +23,7 @@ Object.defineProperty(exports, "Panel", {
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 _pluginsystem = require("@perses-dev/plugin-system");
26
27
  const _react = require("react");
27
28
  const _useresizeobserver = /*#__PURE__*/ _interop_require_default(require("use-resize-observer"));
28
29
  const _PanelContent = require("./PanelContent");
@@ -52,6 +53,7 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
52
53
  height
53
54
  ]);
54
55
  const chartsTheme = (0, _components.useChartsTheme)();
56
+ const { queryResults } = (0, _pluginsystem.useDataQueriesContext)();
55
57
  const handleMouseEnter = (e)=>{
56
58
  onMouseEnter?.(e);
57
59
  };
@@ -66,7 +68,7 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
66
68
  display: 'flex',
67
69
  flexFlow: 'column nowrap',
68
70
  ':hover': {
69
- '--panel-hover': 'true'
71
+ '--panel-hover': 'block'
70
72
  }
71
73
  }, sx),
72
74
  variant: "outlined",
@@ -85,6 +87,7 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
85
87
  id: headerId,
86
88
  title: definition.spec.display.name,
87
89
  description: definition.spec.display.description,
90
+ queryResults: queryResults,
88
91
  readHandlers: readHandlers,
89
92
  editHandlers: editHandlers,
90
93
  links: definition.spec.links,
@@ -115,7 +118,8 @@ const Panel = /*#__PURE__*/ (0, _react.memo)(function Panel(props) {
115
118
  definition: definition,
116
119
  panelPluginKind: definition.spec.plugin.kind,
117
120
  spec: definition.spec.plugin.spec,
118
- contentDimensions: contentDimensions
121
+ contentDimensions: contentDimensions,
122
+ queryResults: queryResults
119
123
  })
120
124
  })
121
125
  })
@@ -31,14 +31,80 @@ const _DeleteOutline = /*#__PURE__*/ _interop_require_default(require("mdi-mater
31
31
  const _DragVertical = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/DragVertical"));
32
32
  const _ContentCopy = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ContentCopy"));
33
33
  const _Menu = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Menu"));
34
+ const _Alert = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/Alert"));
35
+ const _InformationOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/InformationOutline"));
34
36
  const _constants = require("../../constants");
35
37
  const _HeaderIconButton = require("./HeaderIconButton");
38
+ const _PanelLinks = require("./PanelLinks");
36
39
  function _interop_require_default(obj) {
37
40
  return obj && obj.__esModule ? obj : {
38
41
  default: obj
39
42
  };
40
43
  }
41
- const PanelActions = ({ editHandlers, readHandlers, extra, title })=>{
44
+ const ConditionalBox = (0, _material.styled)(_material.Box)({
45
+ display: 'none',
46
+ alignItems: 'center',
47
+ flexGrow: 1,
48
+ justifyContent: 'flex-end'
49
+ });
50
+ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, descriptionTooltipId, links, queryResults })=>{
51
+ const descriptionAction = (0, _react.useMemo)(()=>{
52
+ if (description && description.trim().length > 0) {
53
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
54
+ id: descriptionTooltipId,
55
+ description: description,
56
+ enterDelay: 100,
57
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_HeaderIconButton.HeaderIconButton, {
58
+ "aria-label": "panel description",
59
+ size: "small",
60
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_InformationOutline.default, {
61
+ "aria-describedby": "info-tooltip",
62
+ "aria-hidden": false,
63
+ fontSize: "inherit",
64
+ sx: {
65
+ color: (theme)=>theme.palette.text.secondary
66
+ }
67
+ })
68
+ })
69
+ });
70
+ }
71
+ return undefined;
72
+ }, [
73
+ descriptionTooltipId,
74
+ description
75
+ ]);
76
+ const linksAction = links && links.length > 0 && /*#__PURE__*/ (0, _jsxruntime.jsx)(_PanelLinks.PanelLinks, {
77
+ links: links
78
+ });
79
+ const extraActions = editHandlers === undefined && extra;
80
+ const queryStateIndicator = (0, _react.useMemo)(()=>{
81
+ const hasData = queryResults.some((q)=>q.data);
82
+ const isFetching = queryResults.some((q)=>q.isFetching);
83
+ const queryErrors = queryResults.filter((q)=>q.error);
84
+ if (isFetching && hasData) {
85
+ // If the panel has no data, the panel content will show the loading overlay.
86
+ // Therefore, show the circular loading indicator only in case the panel doesn't display the loading overlay already.
87
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.CircularProgress, {
88
+ "aria-label": "loading",
89
+ size: "1.125rem"
90
+ });
91
+ } else if (queryErrors.length > 0) {
92
+ const errorTexts = queryErrors.map((q)=>q.error).map((e)=>e?.message ?? e?.toString() ?? 'Unknown error') // eslint-disable-line @typescript-eslint/no-explicit-any
93
+ .join('\n');
94
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
95
+ description: errorTexts,
96
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_HeaderIconButton.HeaderIconButton, {
97
+ "aria-label": "panel errors",
98
+ size: "small",
99
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Alert.default, {
100
+ fontSize: "inherit"
101
+ })
102
+ })
103
+ });
104
+ }
105
+ }, [
106
+ queryResults
107
+ ]);
42
108
  const readActions = (0, _react.useMemo)(()=>{
43
109
  if (readHandlers !== undefined) {
44
110
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
@@ -111,43 +177,9 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title })=>{
111
177
  editHandlers,
112
178
  title
113
179
  ]);
114
- return /*#__PURE__*/ (0, _jsxruntime.jsxs)(HeaderActionWrapper, {
115
- direction: "row",
116
- spacing: 0.25,
117
- alignItems: "center",
118
- sx: {
119
- display: editHandlers !== undefined || readHandlers?.isPanelViewed ? 'flex' : 'var(--panel-hover, none)'
120
- },
121
- children: [
122
- editHandlers === undefined && extra,
123
- " ",
124
- readActions,
125
- editActions && /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
126
- children: [
127
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
128
- sx: (0, _components.combineSx)((theme)=>({
129
- display: 'block',
130
- [theme.containerQueries(_constants.HEADER_ACTIONS_CONTAINER_NAME).down(_constants.HEADER_ACTIONS_MIN_WIDTH)]: {
131
- display: 'none'
132
- }
133
- })),
134
- children: editActions
135
- }),
136
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
137
- sx: (0, _components.combineSx)((theme)=>({
138
- display: 'block',
139
- [theme.containerQueries(_constants.HEADER_ACTIONS_CONTAINER_NAME).up(_constants.HEADER_ACTIONS_MIN_WIDTH)]: {
140
- display: 'none'
141
- }
142
- })),
143
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(ShowAction, {
144
- title: title,
145
- children: editActions
146
- })
147
- })
148
- ]
149
- }),
150
- editActions && /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
180
+ const moveAction = (0, _react.useMemo)(()=>{
181
+ if (editActions && !readHandlers?.isPanelViewed) {
182
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
151
183
  description: _constants.TOOLTIP_TEXT.movePanel,
152
184
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_HeaderIconButton.HeaderIconButton, {
153
185
  "aria-label": _constants.ARIA_LABEL_TEXT.movePanel(title),
@@ -160,28 +192,142 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title })=>{
160
192
  fontSize: "inherit"
161
193
  })
162
194
  })
195
+ });
196
+ }
197
+ return undefined;
198
+ }, [
199
+ editActions,
200
+ readHandlers,
201
+ title
202
+ ]);
203
+ const divider = /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
204
+ sx: {
205
+ flexGrow: 1
206
+ }
207
+ });
208
+ // if the panel is in non-editing, non-fullscreen mode, show certain icons only on hover
209
+ const OnHover = ({ children })=>editHandlers === undefined && !readHandlers?.isPanelViewed ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
210
+ sx: {
211
+ display: 'var(--panel-hover, none)'
212
+ },
213
+ children: children
214
+ }) : /*#__PURE__*/ (0, _jsxruntime.jsx)(_jsxruntime.Fragment, {
215
+ children: children
216
+ });
217
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
218
+ children: [
219
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(ConditionalBox, {
220
+ sx: (theme)=>({
221
+ [theme.containerQueries(_constants.HEADER_ACTIONS_CONTAINER_NAME).between(0, _constants.HEADER_SMALL_WIDTH)]: {
222
+ display: 'flex'
223
+ }
224
+ }),
225
+ children: [
226
+ divider,
227
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(OnHover, {
228
+ children: [
229
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(OverflowMenu, {
230
+ title: title,
231
+ children: [
232
+ descriptionAction,
233
+ " ",
234
+ linksAction,
235
+ " ",
236
+ queryStateIndicator,
237
+ " ",
238
+ extraActions,
239
+ " ",
240
+ readActions,
241
+ " ",
242
+ editActions
243
+ ]
244
+ }),
245
+ moveAction
246
+ ]
247
+ })
248
+ ]
249
+ }),
250
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(ConditionalBox, {
251
+ sx: (theme)=>({
252
+ [theme.containerQueries(_constants.HEADER_ACTIONS_CONTAINER_NAME).between(_constants.HEADER_SMALL_WIDTH, _constants.HEADER_MEDIUM_WIDTH)]: {
253
+ display: 'flex'
254
+ }
255
+ }),
256
+ children: [
257
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(OnHover, {
258
+ children: [
259
+ descriptionAction,
260
+ " ",
261
+ linksAction
262
+ ]
263
+ }),
264
+ divider,
265
+ " ",
266
+ queryStateIndicator,
267
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(OnHover, {
268
+ children: [
269
+ extraActions,
270
+ " ",
271
+ readActions,
272
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(OverflowMenu, {
273
+ title: title,
274
+ children: editActions
275
+ }),
276
+ moveAction
277
+ ]
278
+ })
279
+ ]
280
+ }),
281
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(ConditionalBox, {
282
+ sx: (theme)=>({
283
+ // flip the logic here; if the browser (or jsdom) does not support container queries, always show all icons
284
+ display: 'flex',
285
+ [theme.containerQueries(_constants.HEADER_ACTIONS_CONTAINER_NAME).down(_constants.HEADER_MEDIUM_WIDTH)]: {
286
+ display: 'none'
287
+ }
288
+ }),
289
+ children: [
290
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(OnHover, {
291
+ children: [
292
+ descriptionAction,
293
+ " ",
294
+ linksAction
295
+ ]
296
+ }),
297
+ divider,
298
+ " ",
299
+ queryStateIndicator,
300
+ /*#__PURE__*/ (0, _jsxruntime.jsxs)(OnHover, {
301
+ children: [
302
+ extraActions,
303
+ " ",
304
+ readActions,
305
+ " ",
306
+ editActions,
307
+ " ",
308
+ moveAction
309
+ ]
310
+ })
311
+ ]
163
312
  })
164
313
  ]
165
314
  });
166
315
  };
167
- const HeaderActionWrapper = (0, _material.styled)(_material.Stack)(()=>({
168
- // Adding back the negative margins from MUI's defaults for actions, so we
169
- // avoid increasing the header size when actions are present while also being
170
- // able to vertically center the actions.
171
- // https://github.com/mui/material-ui/blob/master/packages/mui-material/src/CardHeader/CardHeader.js#L56-L58
172
- marginTop: -4,
173
- marginBottom: -4
174
- }));
175
- const ShowAction = ({ children, title })=>{
176
- const [anchorEl, setAnchorEl] = (0, _react.useState)(null);
316
+ const OverflowMenu = ({ children, title })=>{
317
+ const [anchorPosition, setAnchorPosition] = (0, _react.useState)();
318
+ // do not show overflow menu if there is no content (for example, edit actions are hidden)
319
+ const hasContent = /*#__PURE__*/ (0, _react.isValidElement)(children) || Array.isArray(children) && children.some(_react.isValidElement);
320
+ if (!hasContent) {
321
+ return undefined;
322
+ }
177
323
  const handleClick = (event)=>{
178
- setAnchorEl(event.currentTarget);
324
+ setAnchorPosition(event.currentTarget.getBoundingClientRect());
179
325
  };
180
326
  const handleClose = ()=>{
181
- setAnchorEl(null);
327
+ setAnchorPosition(undefined);
182
328
  };
183
- const open = Boolean(anchorEl);
184
- const id = open ? 'actions-popover' : undefined;
329
+ const open = Boolean(anchorPosition);
330
+ const id = open ? 'actions-menu' : undefined;
185
331
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
186
332
  children: [
187
333
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_HeaderIconButton.HeaderIconButton, {
@@ -197,15 +343,18 @@ const ShowAction = ({ children, title })=>{
197
343
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Popover, {
198
344
  id: id,
199
345
  open: open,
200
- anchorEl: anchorEl,
346
+ anchorReference: "anchorPosition",
347
+ anchorPosition: anchorPosition,
201
348
  onClose: handleClose,
202
349
  anchorOrigin: {
203
350
  vertical: 'bottom',
204
351
  horizontal: 'left'
205
352
  },
206
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Box, {
353
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Stack, {
354
+ direction: "row",
355
+ alignItems: "center",
207
356
  sx: {
208
- padding: '8px'
357
+ padding: 1
209
358
  },
210
359
  onClick: handleClose,
211
360
  children: children