@perses-dev/dashboards 0.16.0 → 0.18.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/DashboardToolbar/DashboardToolbar.js +52 -41
  2. package/dist/cjs/components/GridLayout/GridContainer.js +2 -2
  3. package/dist/cjs/components/GridLayout/GridLayout.js +13 -2
  4. package/dist/cjs/components/GridLayout/GridTitle.js +4 -6
  5. package/dist/cjs/components/Panel/PanelHeader.js +1 -1
  6. package/dist/cjs/components/PanelDrawer/PanelDrawer.js +3 -4
  7. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.js +28 -5
  8. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.test.js +11 -5
  9. package/dist/cjs/components/Variables/Variable.js +2 -46
  10. package/dist/cjs/components/Variables/VariableEditor.js +142 -130
  11. package/dist/cjs/components/Variables/VariableEditorForm/VariableEditorForm.js +318 -167
  12. package/dist/cjs/components/Variables/VariableEditorForm/variable-editor-form-model.js +5 -4
  13. package/dist/cjs/components/Variables/VariableList.js +13 -8
  14. package/dist/cjs/components/Variables/variable-model.js +106 -0
  15. package/dist/cjs/components/Variables/variable-model.test.js +106 -0
  16. package/dist/cjs/context/TemplateVariableProvider/query-params.js +3 -1
  17. package/dist/cjs/context/index.js +0 -1
  18. package/dist/cjs/views/ViewDashboard/DashboardApp.js +2 -1
  19. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +6 -4
  20. package/dist/cjs/views/ViewDashboard/tests/panelGroups.test.js +4 -2
  21. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts +1 -0
  22. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
  23. package/dist/components/DashboardToolbar/DashboardToolbar.js +53 -42
  24. package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
  25. package/dist/components/GridLayout/GridContainer.js +2 -2
  26. package/dist/components/GridLayout/GridContainer.js.map +1 -1
  27. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  28. package/dist/components/GridLayout/GridLayout.js +13 -2
  29. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  30. package/dist/components/GridLayout/GridTitle.d.ts.map +1 -1
  31. package/dist/components/GridLayout/GridTitle.js +4 -6
  32. package/dist/components/GridLayout/GridTitle.js.map +1 -1
  33. package/dist/components/Panel/PanelHeader.js +1 -1
  34. package/dist/components/Panel/PanelHeader.js.map +1 -1
  35. package/dist/components/PanelDrawer/PanelDrawer.js +3 -4
  36. package/dist/components/PanelDrawer/PanelDrawer.js.map +1 -1
  37. package/dist/components/TimeRangeControls/TimeRangeControls.d.ts.map +1 -1
  38. package/dist/components/TimeRangeControls/TimeRangeControls.js +24 -7
  39. package/dist/components/TimeRangeControls/TimeRangeControls.js.map +1 -1
  40. package/dist/components/TimeRangeControls/TimeRangeControls.test.js +11 -5
  41. package/dist/components/TimeRangeControls/TimeRangeControls.test.js.map +1 -1
  42. package/dist/components/Variables/Variable.d.ts.map +1 -1
  43. package/dist/components/Variables/Variable.js +3 -47
  44. package/dist/components/Variables/Variable.js.map +1 -1
  45. package/dist/components/Variables/VariableEditor.d.ts.map +1 -1
  46. package/dist/components/Variables/VariableEditor.js +142 -130
  47. package/dist/components/Variables/VariableEditor.js.map +1 -1
  48. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.d.ts.map +1 -1
  49. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js +315 -169
  50. package/dist/components/Variables/VariableEditorForm/VariableEditorForm.js.map +1 -1
  51. package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.d.ts +1 -0
  52. package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.d.ts.map +1 -1
  53. package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.js +5 -4
  54. package/dist/components/Variables/VariableEditorForm/variable-editor-form-model.js.map +1 -1
  55. package/dist/components/Variables/VariableList.d.ts +2 -0
  56. package/dist/components/Variables/VariableList.d.ts.map +1 -1
  57. package/dist/components/Variables/VariableList.js +13 -8
  58. package/dist/components/Variables/VariableList.js.map +1 -1
  59. package/dist/components/Variables/variable-model.d.ts +9 -0
  60. package/dist/components/Variables/variable-model.d.ts.map +1 -0
  61. package/dist/components/Variables/variable-model.js +95 -0
  62. package/dist/components/Variables/variable-model.js.map +1 -0
  63. package/dist/components/Variables/variable-model.test.d.ts +2 -0
  64. package/dist/components/Variables/variable-model.test.d.ts.map +1 -0
  65. package/dist/components/Variables/variable-model.test.js +104 -0
  66. package/dist/components/Variables/variable-model.test.js.map +1 -0
  67. package/dist/context/TemplateVariableProvider/query-params.js +3 -1
  68. package/dist/context/TemplateVariableProvider/query-params.js.map +1 -1
  69. package/dist/context/index.d.ts +0 -1
  70. package/dist/context/index.d.ts.map +1 -1
  71. package/dist/context/index.js +0 -1
  72. package/dist/context/index.js.map +1 -1
  73. package/dist/views/ViewDashboard/DashboardApp.d.ts +1 -0
  74. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  75. package/dist/views/ViewDashboard/DashboardApp.js +2 -1
  76. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  77. package/dist/views/ViewDashboard/ViewDashboard.d.ts +1 -0
  78. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  79. package/dist/views/ViewDashboard/ViewDashboard.js +5 -3
  80. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  81. package/dist/views/ViewDashboard/tests/panelGroups.test.js +4 -2
  82. package/dist/views/ViewDashboard/tests/panelGroups.test.js.map +1 -1
  83. package/package.json +5 -5
  84. package/dist/cjs/context/TimeRangeProvider/TimeRangeProvider.js +0 -91
  85. package/dist/cjs/context/TimeRangeProvider/index.js +0 -29
  86. package/dist/cjs/context/TimeRangeProvider/query-params.js +0 -157
  87. package/dist/context/TimeRangeProvider/TimeRangeProvider.d.ts +0 -19
  88. package/dist/context/TimeRangeProvider/TimeRangeProvider.d.ts.map +0 -1
  89. package/dist/context/TimeRangeProvider/TimeRangeProvider.js +0 -44
  90. package/dist/context/TimeRangeProvider/TimeRangeProvider.js.map +0 -1
  91. package/dist/context/TimeRangeProvider/index.d.ts +0 -3
  92. package/dist/context/TimeRangeProvider/index.d.ts.map +0 -1
  93. package/dist/context/TimeRangeProvider/index.js +0 -16
  94. package/dist/context/TimeRangeProvider/index.js.map +0 -1
  95. package/dist/context/TimeRangeProvider/query-params.d.ts +0 -25
  96. package/dist/context/TimeRangeProvider/query-params.d.ts.map +0 -1
  97. package/dist/context/TimeRangeProvider/query-params.js +0 -149
  98. package/dist/context/TimeRangeProvider/query-params.js.map +0 -1
@@ -34,7 +34,7 @@ function _interopRequireDefault(obj) {
34
34
  };
35
35
  }
36
36
  const DashboardToolbar = (props)=>{
37
- const { dashboardName , dashboardTitleComponent , initialVariableIsSticky , onEditButtonClick , onCancelButtonClick } = props;
37
+ const { dashboardName , dashboardTitleComponent , initialVariableIsSticky , isReadonly , onEditButtonClick , onCancelButtonClick , } = props;
38
38
  const { isEditMode , setEditMode } = (0, _context.useEditMode)();
39
39
  const { openAddPanelGroup , openAddPanel } = (0, _context.useDashboardActions)();
40
40
  const isLaptopSize = (0, _material.useMediaQuery)((0, _material.useTheme)().breakpoints.up('sm'));
@@ -47,58 +47,67 @@ const DashboardToolbar = (props)=>{
47
47
  };
48
48
  return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
49
49
  children: isEditMode ? /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
50
- spacing: 2,
50
+ spacing: 1,
51
51
  children: [
52
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Box, {
52
+ /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Box, {
53
+ p: 2,
54
+ display: "flex",
53
55
  sx: {
54
- backgroundColor: (theme)=>theme.palette.primary.light + '20'
56
+ backgroundColor: (theme)=>theme.palette.primary.main + '30'
55
57
  },
56
- children: /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Box, {
57
- padding: 2,
58
- display: "flex",
59
- children: [
60
- dashboardTitle,
61
- /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
62
- direction: "row",
63
- spacing: 1,
64
- sx: {
65
- marginLeft: 'auto'
66
- },
67
- children: [
68
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
69
- variant: "contained",
70
- onClick: onSave,
71
- children: "Save"
72
- }),
73
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
74
- variant: "outlined",
75
- onClick: onCancelButtonClick,
76
- children: "Cancel"
77
- })
78
- ]
79
- })
80
- ]
81
- })
58
+ children: [
59
+ dashboardTitle,
60
+ /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
61
+ direction: "row",
62
+ spacing: 1,
63
+ marginLeft: "auto",
64
+ children: [
65
+ isReadonly && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Alert, {
66
+ severity: 'warning',
67
+ sx: {
68
+ backgroundColor: 'transparent',
69
+ padding: 0
70
+ },
71
+ children: "Dashboard managed via code only. Download JSON and commit changes to save."
72
+ }),
73
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
74
+ variant: "contained",
75
+ onClick: onSave,
76
+ disabled: isReadonly,
77
+ children: "Save"
78
+ }),
79
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
80
+ variant: "outlined",
81
+ onClick: onCancelButtonClick,
82
+ children: "Cancel"
83
+ })
84
+ ]
85
+ })
86
+ ]
82
87
  }),
83
88
  /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Box, {
84
89
  sx: {
85
90
  display: 'flex',
86
91
  width: '100%',
87
92
  alignItems: 'flex-start',
88
- padding: (theme)=>theme.spacing(2)
93
+ padding: (theme)=>theme.spacing(0, 2, 2, 2)
89
94
  },
90
95
  children: [
91
96
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ErrorBoundary, {
92
97
  FallbackComponent: _components.ErrorAlert,
93
98
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_variables.TemplateVariableList, {
94
- initialVariableIsSticky: initialVariableIsSticky
99
+ initialVariableIsSticky: initialVariableIsSticky,
100
+ sx: {
101
+ backgroundColor: ({ palette })=>palette.mode === 'dark' ? palette.background.default : palette.background.paper
102
+ }
95
103
  })
96
104
  }),
97
105
  /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
98
- direction: 'row',
106
+ direction: "row",
99
107
  spacing: 1,
108
+ marginLeft: "auto",
100
109
  sx: {
101
- marginLeft: 'auto'
110
+ whiteSpace: 'nowrap'
102
111
  },
103
112
  children: [
104
113
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
@@ -111,14 +120,15 @@ const DashboardToolbar = (props)=>{
111
120
  onClick: openAddPanel,
112
121
  children: "Add Panel"
113
122
  }),
114
- /*#__PURE__*/ (0, _jsxRuntime.jsx)(_timeRangeControls.TimeRangeControls, {})
123
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_timeRangeControls.TimeRangeControls, {}),
124
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_downloadButton.DownloadButton, {})
115
125
  ]
116
126
  })
117
127
  ]
118
128
  })
119
129
  ]
120
130
  }) : /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
121
- spacing: 2,
131
+ spacing: 1,
122
132
  padding: 2,
123
133
  children: [
124
134
  /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Box, {
@@ -130,10 +140,8 @@ const DashboardToolbar = (props)=>{
130
140
  dashboardTitle,
131
141
  /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
132
142
  direction: "row",
133
- spacing: 2,
134
- sx: {
135
- marginLeft: 'auto'
136
- },
143
+ spacing: 1,
144
+ marginLeft: "auto",
137
145
  children: [
138
146
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_timeRangeControls.TimeRangeControls, {}),
139
147
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_downloadButton.DownloadButton, {}),
@@ -155,7 +163,10 @@ const DashboardToolbar = (props)=>{
155
163
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ErrorBoundary, {
156
164
  FallbackComponent: _components.ErrorAlert,
157
165
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_variables.TemplateVariableList, {
158
- initialVariableIsSticky: initialVariableIsSticky
166
+ initialVariableIsSticky: initialVariableIsSticky,
167
+ sx: {
168
+ backgroundColor: ({ palette })=>palette.mode === 'dark' ? palette.background.default : palette.background.paper
169
+ }
159
170
  })
160
171
  })
161
172
  })
@@ -98,8 +98,8 @@ function GridContainer(props) {
98
98
  bottom: '3px',
99
99
  width: '5px',
100
100
  height: '5px',
101
- borderRight: '2px solid rgba(0, 0, 0, 0.4)',
102
- borderBottom: '2px solid rgba(0, 0, 0, 0.4)'
101
+ borderRight: `2px solid ${theme.palette.text.secondary}`,
102
+ borderBottom: `2px solid ${theme.palette.text.secondary}`
103
103
  },
104
104
  '& .react-resizable-hide > .react-resizable-handle': {
105
105
  display: 'none'
@@ -28,6 +28,7 @@ const _gridTitle = require("./GridTitle");
28
28
  const _gridItemContent = require("./GridItemContent");
29
29
  const _gridContainer = require("./GridContainer");
30
30
  const ResponsiveGridLayout = (0, _reactGridLayout.WidthProvider)(_reactGridLayout.Responsive);
31
+ const SMALL_LAYOUT_BREAKPOINT = 'sm';
31
32
  function GridLayout(props) {
32
33
  const { panelGroupId /*...others */ } = props;
33
34
  const theme = (0, _material.useTheme)();
@@ -36,6 +37,16 @@ function GridLayout(props) {
36
37
  var ref;
37
38
  const [isOpen, setIsOpen] = (0, _react.useState)((ref = !groupDefinition.isCollapsed) !== null && ref !== void 0 ? ref : true);
38
39
  const { isEditMode } = (0, _context.useEditMode)();
40
+ const handleLayoutChange = (currentLayout, allLayouts)=>{
41
+ // Using the value from `allLayouts` instead of `currentLayout` because of
42
+ // a bug in react-layout-grid where `currentLayout` does not adjust properly
43
+ // when going to a smaller breakpoint and then back to a larger breakpoint.
44
+ // https://github.com/react-grid-layout/react-grid-layout/issues/1663
45
+ const smallLayout = allLayouts[SMALL_LAYOUT_BREAKPOINT];
46
+ if (smallLayout) {
47
+ updatePanelGroupLayouts(smallLayout);
48
+ }
49
+ };
39
50
  return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_gridContainer.GridContainer, {
40
51
  children: [
41
52
  groupDefinition.title !== undefined && /*#__PURE__*/ (0, _jsxRuntime.jsx)(_gridTitle.GridTitle, {
@@ -72,9 +83,9 @@ function GridLayout(props) {
72
83
  10
73
84
  ],
74
85
  layouts: {
75
- sm: groupDefinition.itemLayouts
86
+ [SMALL_LAYOUT_BREAKPOINT]: groupDefinition.itemLayouts
76
87
  },
77
- onLayoutChange: updatePanelGroupLayouts,
88
+ onLayoutChange: handleLayoutChange,
78
89
  children: groupDefinition.itemLayouts.map(({ i })=>/*#__PURE__*/ (0, _jsxRuntime.jsx)("div", {
79
90
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.ErrorBoundary, {
80
91
  FallbackComponent: _components.ErrorAlert,
@@ -20,8 +20,8 @@ Object.defineProperty(exports, "GridTitle", {
20
20
  });
21
21
  const _jsxRuntime = require("react/jsx-runtime");
22
22
  const _material = require("@mui/material");
23
- const _chevronUp = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ChevronUp"));
24
23
  const _chevronDown = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ChevronDown"));
24
+ const _chevronRight = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ChevronRight"));
25
25
  const _chartBoxPlusOutline = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ChartBoxPlusOutline"));
26
26
  const _pencilOutline = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/PencilOutline"));
27
27
  const _arrowUp = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/ArrowUp"));
@@ -51,20 +51,18 @@ function GridTitle(props) {
51
51
  justifyContent: 'start',
52
52
  alignItems: 'center',
53
53
  padding: (theme)=>theme.spacing(1),
54
- backgroundColor: (theme)=>theme.palette.background.default
54
+ backgroundColor: ({ palette })=>palette.mode === 'dark' ? palette.background.paper : palette.background.default
55
55
  },
56
56
  children: collapse ? /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
57
57
  children: [
58
58
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.IconButton, {
59
59
  onClick: collapse.onToggleOpen,
60
- children: collapse.isOpen ? /*#__PURE__*/ (0, _jsxRuntime.jsx)(_chevronUp.default, {}) : /*#__PURE__*/ (0, _jsxRuntime.jsx)(_chevronDown.default, {})
60
+ children: collapse.isOpen ? /*#__PURE__*/ (0, _jsxRuntime.jsx)(_chevronDown.default, {}) : /*#__PURE__*/ (0, _jsxRuntime.jsx)(_chevronRight.default, {})
61
61
  }),
62
62
  text,
63
63
  isEditMode && /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
64
64
  direction: "row",
65
- sx: {
66
- marginLeft: 'auto'
67
- },
65
+ marginLeft: "auto",
68
66
  children: [
69
67
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.IconButton, {
70
68
  "aria-label": `add panel to group ${title}`,
@@ -38,8 +38,8 @@ function PanelHeader({ id , title , description , editHandlers , isHovered , sx
38
38
  // If there are edit handlers, always just show the edit buttons
39
39
  action = /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
40
40
  direction: "row",
41
- alignItems: "center",
42
41
  spacing: 0.5,
42
+ alignItems: "center",
43
43
  children: [
44
44
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(HeaderIconButton, {
45
45
  "aria-label": `edit panel ${title}`,
@@ -57,7 +57,7 @@ const PanelDrawer = ()=>{
57
57
  display: 'flex',
58
58
  alignItems: 'center',
59
59
  padding: (theme)=>theme.spacing(1, 2),
60
- borderBottom: (theme)=>`1px solid ${theme.palette.grey[100]}`
60
+ borderBottom: (theme)=>`1px solid ${theme.palette.divider}`
61
61
  },
62
62
  children: [
63
63
  /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Typography, {
@@ -70,9 +70,7 @@ const PanelDrawer = ()=>{
70
70
  /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_material.Stack, {
71
71
  direction: "row",
72
72
  spacing: 1,
73
- sx: {
74
- marginLeft: 'auto'
75
- },
73
+ marginLeft: "auto",
76
74
  children: [
77
75
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
78
76
  type: "submit",
@@ -81,6 +79,7 @@ const PanelDrawer = ()=>{
81
79
  children: panelEditor.mode === 'Add' ? 'Add' : 'Apply'
82
80
  }),
83
81
  /*#__PURE__*/ (0, _jsxRuntime.jsx)(_material.Button, {
82
+ color: "secondary",
84
83
  variant: "outlined",
85
84
  onClick: handleClose,
86
85
  children: "Cancel"
@@ -25,9 +25,17 @@ _export(exports, {
25
25
  TimeRangeControls: ()=>TimeRangeControls
26
26
  });
27
27
  const _jsxRuntime = require("react/jsx-runtime");
28
+ const _refresh = /*#__PURE__*/ _interopRequireDefault(require("mdi-material-ui/Refresh"));
29
+ const _material = require("@mui/material");
28
30
  const _components = require("@perses-dev/components");
31
+ const _pluginSystem = require("@perses-dev/plugin-system");
29
32
  const _core = require("@perses-dev/core");
30
33
  const _context = require("../../context");
34
+ function _interopRequireDefault(obj) {
35
+ return obj && obj.__esModule ? obj : {
36
+ default: obj
37
+ };
38
+ }
31
39
  const TIME_OPTIONS = [
32
40
  {
33
41
  value: {
@@ -85,7 +93,7 @@ const TIME_OPTIONS = [
85
93
  }
86
94
  ];
87
95
  function TimeRangeControls() {
88
- const { timeRange , setTimeRange } = (0, _context.useDashboardTimeRange)();
96
+ const { timeRange , setTimeRange , refresh } = (0, _pluginSystem.useTimeRange)();
89
97
  const defaultTimeRange = (0, _context.useDefaultTimeRange)();
90
98
  // add time shortcut if one does not match duration from dashboard JSON
91
99
  if (!TIME_OPTIONS.some((option)=>option.value.pastDuration === defaultTimeRange.pastDuration)) {
@@ -98,9 +106,24 @@ function TimeRangeControls() {
98
106
  });
99
107
  }
100
108
  }
101
- return /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.DateTimeRangePicker, {
102
- timeOptions: TIME_OPTIONS,
103
- value: timeRange,
104
- onChange: setTimeRange
109
+ return /*#__PURE__*/ (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
110
+ children: [
111
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(_components.DateTimeRangePicker, {
112
+ timeOptions: TIME_OPTIONS,
113
+ value: timeRange,
114
+ onChange: setTimeRange
115
+ }),
116
+ /*#__PURE__*/ (0, _jsxRuntime.jsx)(RefreshIconButton, {
117
+ "aria-label": "Refresh Dashboard",
118
+ onClick: refresh,
119
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_refresh.default, {})
120
+ })
121
+ ]
105
122
  });
106
123
  }
124
+ const RefreshIconButton = (0, _material.styled)(_material.IconButton)(({ theme })=>({
125
+ border: `1px solid ${theme.palette.grey[300]}`,
126
+ borderRadius: theme.shape.borderRadius,
127
+ padding: theme.spacing(0.5),
128
+ color: theme.palette.grey[900]
129
+ }));
@@ -19,6 +19,7 @@ const _reactRouter = require("react-router");
19
19
  const _history = require("history");
20
20
  const _userEvent = /*#__PURE__*/ _interopRequireDefault(require("@testing-library/user-event"));
21
21
  const _react = require("@testing-library/react");
22
+ const _pluginSystem = require("@perses-dev/plugin-system");
22
23
  const _test = require("../../test");
23
24
  const _testDashboard = /*#__PURE__*/ _interopRequireDefault(require("../../test/testDashboard"));
24
25
  const _context = require("../../context");
@@ -30,6 +31,7 @@ function _interopRequireDefault(obj) {
30
31
  }
31
32
  const history = (0, _history.createMemoryHistory)({
32
33
  initialEntries: [
34
+ (0, _reactRouter.generatePath)('/home'),
33
35
  (0, _reactRouter.generatePath)('/dashboards/:id', {
34
36
  id: 'test'
35
37
  })
@@ -48,7 +50,7 @@ describe('TimeRangeControls', ()=>{
48
50
  const renderTimeRangeControls = (testURLParams)=>{
49
51
  (0, _test.renderWithContext)(/*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.DashboardProvider, {
50
52
  initialState: initialState,
51
- children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_context.TimeRangeProvider, {
53
+ children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_pluginSystem.TimeRangeProvider, {
52
54
  initialTimeRange: testDefaultTimeRange,
53
55
  enabledURLParams: testURLParams,
54
56
  children: /*#__PURE__*/ (0, _jsxRuntime.jsx)(_timeRangeControls.TimeRangeControls, {})
@@ -58,7 +60,9 @@ describe('TimeRangeControls', ()=>{
58
60
  it('should default to dashboard duration and update selected time option when clicked', async ()=>{
59
61
  renderTimeRangeControls(false);
60
62
  expect(_react.screen.getByText('Last 30 minutes')).toBeInTheDocument();
61
- const dateButton = _react.screen.getByRole('button');
63
+ const dateButton = _react.screen.getByRole('button', {
64
+ name: /last/i
65
+ });
62
66
  _userEvent.default.click(dateButton);
63
67
  const firstSelected = _react.screen.getByRole('option', {
64
68
  name: 'Last 5 minutes'
@@ -68,7 +72,9 @@ describe('TimeRangeControls', ()=>{
68
72
  });
69
73
  it('should update URL params with correct time range values', ()=>{
70
74
  renderTimeRangeControls(true);
71
- const dateButton = _react.screen.getByRole('button');
75
+ const dateButton = _react.screen.getByRole('button', {
76
+ name: /last/i
77
+ });
72
78
  _userEvent.default.click(dateButton);
73
79
  const firstSelected = _react.screen.getByRole('option', {
74
80
  name: 'Last 5 minutes'
@@ -79,11 +85,11 @@ describe('TimeRangeControls', ()=>{
79
85
  const secondSelected = _react.screen.getByText('Last 12 hours');
80
86
  _userEvent.default.click(secondSelected);
81
87
  expect(history.location.search).toEqual('?start=12h');
82
- // back button should return to first option selected
88
+ // back button should return to previous page selected
83
89
  (0, _react.act)(()=>{
84
90
  history.back();
85
91
  });
86
- expect(history.location.search).toEqual('?start=5m');
92
+ expect(history.location.pathname).toEqual('/home');
87
93
  });
88
94
  // TODO: add additional tests for absolute time selection, other inputs, form validation, etc.
89
95
  });
@@ -22,8 +22,8 @@ const _jsxRuntime = require("react/jsx-runtime");
22
22
  const _react = require("react");
23
23
  const _material = require("@mui/material");
24
24
  const _pluginSystem = require("@perses-dev/plugin-system");
25
- const _reactQuery = require("@tanstack/react-query");
26
25
  const _context = require("../../context");
26
+ const _variableModel = require("./variable-model");
27
27
  function TemplateVariable({ name }) {
28
28
  var ref;
29
29
  const ctx = (0, _context.useTemplateVariable)(name);
@@ -45,60 +45,16 @@ function TemplateVariable({ name }) {
45
45
  ]
46
46
  });
47
47
  }
48
- /**
49
- * Returns a serialized string of the current state of variable values.
50
- */ function getVariableValuesKey(v) {
51
- return Object.values(v).map((v)=>JSON.stringify(v.value)).join(',');
52
- }
53
48
  function ListVariable({ name }) {
54
49
  var ref, ref1, ref2, ref3;
55
50
  const ctx = (0, _context.useTemplateVariable)(name);
56
51
  const definition = ctx.definition;
57
- const { data: variablePlugin } = (0, _pluginSystem.usePlugin)('Variable', definition.spec.plugin.kind);
52
+ const variablesOptionsQuery = (0, _variableModel.useListVariablePluginValues)(definition);
58
53
  const { setVariableValue , setVariableLoading , setVariableOptions } = (0, _context.useTemplateVariableActions)();
59
- const datasourceStore = (0, _pluginSystem.useDatasourceStore)();
60
- const allVariables = (0, _pluginSystem.useTemplateVariableValues)();
61
- const { timeRange } = (0, _pluginSystem.useTimeRange)();
62
- const variablePluginCtx = {
63
- timeRange,
64
- datasourceStore,
65
- variables: allVariables
66
- };
67
- const spec = definition.spec.plugin.spec;
68
- let dependsOnVariables;
69
- if (variablePlugin === null || variablePlugin === void 0 ? void 0 : variablePlugin.dependsOn) {
70
- const dependencies = variablePlugin.dependsOn(spec, variablePluginCtx);
71
- dependsOnVariables = dependencies.variables;
72
- }
73
- const variables = (0, _pluginSystem.useTemplateVariableValues)(dependsOnVariables);
74
54
  const allowMultiple = (definition === null || definition === void 0 ? void 0 : definition.spec.allow_multiple) === true;
75
55
  const allowAllValue = (definition === null || definition === void 0 ? void 0 : definition.spec.allow_all_value) === true;
76
56
  var ref4;
77
57
  const title = (ref4 = (ref = definition === null || definition === void 0 ? void 0 : definition.spec.display) === null || ref === void 0 ? void 0 : ref.name) !== null && ref4 !== void 0 ? ref4 : name;
78
- let waitToLoad = false;
79
- if (dependsOnVariables) {
80
- waitToLoad = dependsOnVariables.some((v)=>{
81
- var ref;
82
- return (ref = variables[v]) === null || ref === void 0 ? void 0 : ref.loading;
83
- });
84
- }
85
- const variablesValueKey = getVariableValuesKey(variables);
86
- const variablesOptionsQuery = (0, _reactQuery.useQuery)([
87
- name,
88
- definition,
89
- variablesValueKey,
90
- timeRange
91
- ], async ()=>{
92
- const resp = await (variablePlugin === null || variablePlugin === void 0 ? void 0 : variablePlugin.getVariableOptions(spec, {
93
- datasourceStore,
94
- variables,
95
- timeRange
96
- }));
97
- var ref;
98
- return (ref = resp === null || resp === void 0 ? void 0 : resp.data) !== null && ref !== void 0 ? ref : [];
99
- }, {
100
- enabled: !!variablePlugin || waitToLoad
101
- });
102
58
  (0, _react.useEffect)(()=>{
103
59
  setVariableLoading(name, variablesOptionsQuery.isFetching);
104
60
  if (variablesOptionsQuery.data) {