@perses-dev/dashboards 0.7.1 → 0.8.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 (161) hide show
  1. package/dist/cjs/components/Dashboard.js +1 -1
  2. package/dist/cjs/components/DashboardToolbar.js +3 -18
  3. package/dist/cjs/components/GridLayout/GridItemContent.js +3 -3
  4. package/dist/cjs/components/GridLayout/GridLayout.js +6 -9
  5. package/dist/cjs/components/GridLayout/GridTitle.js +15 -9
  6. package/dist/cjs/components/Panel/Panel.js +11 -6
  7. package/dist/cjs/components/Panel/Panel.test.js +17 -13
  8. package/dist/cjs/components/Panel/PanelContent.js +15 -0
  9. package/dist/cjs/components/Panel/index.js +29 -0
  10. package/dist/cjs/components/PanelDrawer/PanelDrawer.js +124 -0
  11. package/dist/cjs/components/PanelDrawer/PanelDrawer.test.js +111 -0
  12. package/dist/cjs/components/PanelDrawer/PanelOptionsEditor.js +19 -0
  13. package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.js +60 -0
  14. package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.test.js +95 -0
  15. package/dist/cjs/components/{TimeRangeControls.js → TimeRangeControls/TimeRangeControls.js} +20 -31
  16. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.test.js +51 -0
  17. package/dist/cjs/components/TimeRangeControls/index.js +29 -0
  18. package/dist/cjs/components/Variables/Variable.js +57 -0
  19. package/dist/cjs/components/Variables/VariableList.js +27 -0
  20. package/dist/cjs/components/{VariableList → Variables}/index.js +1 -0
  21. package/dist/cjs/components/index.js +2 -3
  22. package/dist/cjs/context/DashboardAppSlice.js +45 -0
  23. package/dist/cjs/context/DashboardProvider.js +54 -36
  24. package/dist/cjs/context/LayoutsSlice.js +42 -0
  25. package/dist/cjs/context/QueryStringProvider.js +35 -0
  26. package/dist/cjs/context/TemplateVariableProvider.js +216 -0
  27. package/dist/cjs/context/TimeRangeProvider.js +66 -0
  28. package/dist/cjs/context/index.js +6 -3
  29. package/dist/cjs/css/styles.js +173 -169
  30. package/dist/cjs/test/plugin-registry.js +24 -17
  31. package/dist/cjs/test/render.js +11 -2
  32. package/dist/cjs/test/testDashboard.js +14 -37
  33. package/dist/cjs/views/DashboardApp.js +4 -4
  34. package/dist/cjs/views/ViewDashboard.js +30 -2
  35. package/dist/cjs/views/index.js +1 -1
  36. package/dist/components/Dashboard.d.ts.map +1 -1
  37. package/dist/components/Dashboard.js +1 -1
  38. package/dist/components/DashboardToolbar.d.ts +0 -1
  39. package/dist/components/DashboardToolbar.d.ts.map +1 -1
  40. package/dist/components/DashboardToolbar.js +1 -1
  41. package/dist/components/GridLayout/GridItemContent.d.ts +1 -0
  42. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  43. package/dist/components/GridLayout/GridItemContent.js +1 -1
  44. package/dist/components/GridLayout/GridLayout.d.ts +2 -1
  45. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  46. package/dist/components/GridLayout/GridLayout.js +1 -1
  47. package/dist/components/GridLayout/GridTitle.d.ts +1 -0
  48. package/dist/components/GridLayout/GridTitle.d.ts.map +1 -1
  49. package/dist/components/GridLayout/GridTitle.js +1 -1
  50. package/dist/components/Panel/Panel.d.ts +2 -0
  51. package/dist/components/Panel/Panel.d.ts.map +1 -1
  52. package/dist/components/Panel/Panel.js +1 -1
  53. package/dist/components/Panel/Panel.test.d.ts.map +1 -1
  54. package/dist/components/Panel/Panel.test.js +1 -1
  55. package/dist/components/Panel/PanelContent.d.ts +11 -0
  56. package/dist/components/Panel/PanelContent.d.ts.map +1 -0
  57. package/dist/components/Panel/PanelContent.js +1 -0
  58. package/dist/components/Panel/index.d.ts +2 -0
  59. package/dist/components/Panel/index.d.ts.map +1 -0
  60. package/dist/components/Panel/index.js +1 -0
  61. package/dist/components/PanelDrawer/PanelDrawer.d.ts +4 -0
  62. package/dist/components/PanelDrawer/PanelDrawer.d.ts.map +1 -0
  63. package/dist/components/PanelDrawer/PanelDrawer.js +1 -0
  64. package/dist/components/PanelDrawer/PanelDrawer.test.d.ts +2 -0
  65. package/dist/components/PanelDrawer/PanelDrawer.test.d.ts.map +1 -0
  66. package/dist/components/PanelDrawer/PanelDrawer.test.js +1 -0
  67. package/dist/components/PanelDrawer/PanelOptionsEditor.d.ts +9 -0
  68. package/dist/components/PanelDrawer/PanelOptionsEditor.d.ts.map +1 -0
  69. package/dist/components/PanelDrawer/PanelOptionsEditor.js +1 -0
  70. package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts +4 -0
  71. package/dist/components/PanelGroupDialog/PanelGroupDialog.d.ts.map +1 -0
  72. package/dist/components/PanelGroupDialog/PanelGroupDialog.js +1 -0
  73. package/dist/components/PanelGroupDialog/PanelGroupDialog.test.d.ts +2 -0
  74. package/dist/components/PanelGroupDialog/PanelGroupDialog.test.d.ts.map +1 -0
  75. package/dist/components/PanelGroupDialog/PanelGroupDialog.test.js +1 -0
  76. package/dist/components/{TimeRangeControls.d.ts → TimeRangeControls/TimeRangeControls.d.ts} +0 -0
  77. package/dist/components/TimeRangeControls/TimeRangeControls.d.ts.map +1 -0
  78. package/dist/components/TimeRangeControls/TimeRangeControls.js +1 -0
  79. package/dist/components/TimeRangeControls/TimeRangeControls.test.d.ts +2 -0
  80. package/dist/components/TimeRangeControls/TimeRangeControls.test.d.ts.map +1 -0
  81. package/dist/components/TimeRangeControls/TimeRangeControls.test.js +1 -0
  82. package/dist/components/TimeRangeControls/index.d.ts +2 -0
  83. package/dist/components/TimeRangeControls/index.d.ts.map +1 -0
  84. package/dist/components/TimeRangeControls/index.js +1 -0
  85. package/dist/components/Variables/Variable.d.ts +8 -0
  86. package/dist/components/Variables/Variable.d.ts.map +1 -0
  87. package/dist/components/Variables/Variable.js +1 -0
  88. package/dist/components/Variables/VariableList.d.ts +3 -0
  89. package/dist/components/Variables/VariableList.d.ts.map +1 -0
  90. package/dist/components/Variables/VariableList.js +1 -0
  91. package/dist/components/Variables/index.d.ts +3 -0
  92. package/dist/components/Variables/index.d.ts.map +1 -0
  93. package/dist/components/Variables/index.js +1 -0
  94. package/dist/components/index.d.ts +2 -3
  95. package/dist/components/index.d.ts.map +1 -1
  96. package/dist/components/index.js +1 -1
  97. package/dist/context/DashboardAppSlice.d.ts +26 -0
  98. package/dist/context/DashboardAppSlice.d.ts.map +1 -0
  99. package/dist/context/DashboardAppSlice.js +1 -0
  100. package/dist/context/DashboardProvider.d.ts +8 -19
  101. package/dist/context/DashboardProvider.d.ts.map +1 -1
  102. package/dist/context/DashboardProvider.js +1 -1
  103. package/dist/context/LayoutsSlice.d.ts +12 -0
  104. package/dist/context/LayoutsSlice.d.ts.map +1 -0
  105. package/dist/context/LayoutsSlice.js +1 -0
  106. package/dist/context/QueryStringProvider.d.ts +13 -0
  107. package/dist/context/QueryStringProvider.d.ts.map +1 -0
  108. package/dist/context/QueryStringProvider.js +1 -0
  109. package/dist/context/TemplateVariableProvider.d.ts +25 -0
  110. package/dist/context/TemplateVariableProvider.d.ts.map +1 -0
  111. package/dist/context/TemplateVariableProvider.js +1 -0
  112. package/dist/context/TimeRangeProvider.d.ts +12 -0
  113. package/dist/context/TimeRangeProvider.d.ts.map +1 -0
  114. package/dist/context/TimeRangeProvider.js +1 -0
  115. package/dist/context/index.d.ts +5 -2
  116. package/dist/context/index.d.ts.map +1 -1
  117. package/dist/context/index.js +1 -1
  118. package/dist/css/styles.d.ts +7 -7
  119. package/dist/css/styles.d.ts.map +1 -1
  120. package/dist/css/styles.js +1 -1
  121. package/dist/test/plugin-registry.d.ts +4 -2
  122. package/dist/test/plugin-registry.d.ts.map +1 -1
  123. package/dist/test/plugin-registry.js +1 -1
  124. package/dist/test/render.d.ts +2 -1
  125. package/dist/test/render.d.ts.map +1 -1
  126. package/dist/test/render.js +1 -1
  127. package/dist/test/testDashboard.d.ts.map +1 -1
  128. package/dist/test/testDashboard.js +1 -1
  129. package/dist/views/DashboardApp.js +1 -1
  130. package/dist/views/ViewDashboard.d.ts.map +1 -1
  131. package/dist/views/ViewDashboard.js +1 -1
  132. package/package.json +9 -11
  133. package/dist/cjs/components/AddPanel/AddPanel.js +0 -75
  134. package/dist/cjs/components/VariableAutocomplete.js +0 -63
  135. package/dist/cjs/components/VariableList/VariableList.js +0 -42
  136. package/dist/cjs/components/VariableList/VariableList.test.js +0 -86
  137. package/dist/cjs/context/TemplateVariablesProvider.js +0 -142
  138. package/dist/cjs/context/TimeRangeStateProvider.js +0 -49
  139. package/dist/components/AddPanel/AddPanel.d.ts +0 -8
  140. package/dist/components/AddPanel/AddPanel.d.ts.map +0 -1
  141. package/dist/components/AddPanel/AddPanel.js +0 -1
  142. package/dist/components/TimeRangeControls.d.ts.map +0 -1
  143. package/dist/components/TimeRangeControls.js +0 -1
  144. package/dist/components/VariableAutocomplete.d.ts +0 -21
  145. package/dist/components/VariableAutocomplete.d.ts.map +0 -1
  146. package/dist/components/VariableAutocomplete.js +0 -1
  147. package/dist/components/VariableList/VariableList.d.ts +0 -11
  148. package/dist/components/VariableList/VariableList.d.ts.map +0 -1
  149. package/dist/components/VariableList/VariableList.js +0 -1
  150. package/dist/components/VariableList/VariableList.test.d.ts +0 -2
  151. package/dist/components/VariableList/VariableList.test.d.ts.map +0 -1
  152. package/dist/components/VariableList/VariableList.test.js +0 -1
  153. package/dist/components/VariableList/index.d.ts +0 -2
  154. package/dist/components/VariableList/index.d.ts.map +0 -1
  155. package/dist/components/VariableList/index.js +0 -1
  156. package/dist/context/TemplateVariablesProvider.d.ts +0 -23
  157. package/dist/context/TemplateVariablesProvider.d.ts.map +0 -1
  158. package/dist/context/TemplateVariablesProvider.js +0 -1
  159. package/dist/context/TimeRangeStateProvider.d.ts +0 -22
  160. package/dist/context/TimeRangeStateProvider.d.ts.map +0 -1
  161. package/dist/context/TimeRangeStateProvider.js +0 -1
@@ -3,6 +3,7 @@ import { DashboardSpec, GridItemDefinition } from '@perses-dev/core';
3
3
  export interface GridItemContentProps {
4
4
  spec: DashboardSpec;
5
5
  content: GridItemDefinition['content'];
6
+ groupIndex: number;
6
7
  }
7
8
  /**
8
9
  * Resolves the reference to panel content in a GridItemDefinition and renders the panel.
@@ -1 +1 @@
1
- {"version":3,"file":"GridItemContent.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAmB,MAAM,kBAAkB,CAAC;AAGtF,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;CACxC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,eAQ1D"}
1
+ {"version":3,"file":"GridItemContent.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAmB,MAAM,kBAAkB,CAAC;AAGtF,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,eAQ1D"}
@@ -1 +1 @@
1
- import{jsx as _jsx}from"react/jsx-runtime";import{ErrorAlert}from"@perses-dev/components";import{resolvePanelRef}from"@perses-dev/core";import{Panel}from"../Panel/Panel";export function GridItemContent(e){const{content:r,spec:o}=e;try{const e=resolvePanelRef(o,r);return _jsx(Panel,{definition:e})}catch(e){return _jsx(ErrorAlert,{error:e})}}
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{ErrorAlert}from"@perses-dev/components";import{resolvePanelRef}from"@perses-dev/core";import{Panel}from"../Panel/Panel";export function GridItemContent(e){const{content:r,spec:n,groupIndex:o}=e;try{const{panelDefinition:e,panelsKey:t}=resolvePanelRef(n,r);return _jsx(Panel,{definition:e,groupIndex:o,panelKey:t})}catch(e){return _jsx(ErrorAlert,{error:e})}}
@@ -2,8 +2,9 @@
2
2
  import { BoxProps } from '@mui/material';
3
3
  import { GridDefinition, GridItemDefinition } from '@perses-dev/core';
4
4
  export interface GridLayoutProps extends BoxProps {
5
+ groupIndex: number;
5
6
  definition: GridDefinition;
6
- renderGridItemContent: (definition: GridItemDefinition) => React.ReactNode;
7
+ renderGridItemContent: (definition: GridItemDefinition, groupIndex: number) => React.ReactNode;
7
8
  }
8
9
  /**
9
10
  * Layout component that arranges children in a Grid based on the definition.
@@ -1 +1 @@
1
- {"version":3,"file":"GridLayout.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridLayout.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAO,QAAQ,EAA0B,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAOtE,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C,UAAU,EAAE,cAAc,CAAC;IAC3B,qBAAqB,EAAE,CAAC,UAAU,EAAE,kBAAkB,KAAK,KAAK,CAAC,SAAS,CAAC;CAC5E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,eAsDhD"}
1
+ {"version":3,"file":"GridLayout.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridLayout.tsx"],"names":[],"mappings":";AAcA,OAAO,EAAO,QAAQ,EAA0B,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAOtE,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,cAAc,CAAC;IAC3B,qBAAqB,EAAE,CAAC,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CAChG;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,eAwDhD"}
@@ -1 +1 @@
1
- import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useState}from"react";import{Responsive,WidthProvider}from"react-grid-layout";import{Box,Collapse,GlobalStyles}from"@mui/material";import styles from"../../css/styles";import{useEditMode}from"../../context";import{GridTitle}from"./GridTitle";const ResponsiveGridLayout=WidthProvider(Responsive);export function GridLayout(s){var e,i,o;const{definition:{spec:t},renderGridItemContent:l,...r}=s,[d,a]=useState(null===(o=null===(i=null===(e=t.display)||void 0===e?void 0:e.collapse)||void 0===i?void 0:i.open)||void 0===o||o),{isEditMode:n}=useEditMode(),m=[];return t.items.forEach(((s,e)=>{const{x:i,y:o,width:t,height:r}=s;m.push(_jsx("div",{"data-grid":{x:i,y:o,w:t,h:r},children:l(s)},e))})),_jsxs(_Fragment,{children:[_jsx(GlobalStyles,{styles}),_jsxs(Box,{...r,component:"section",sx:{"& + &":{marginTop:s=>s.spacing(1)}},children:[void 0!==t.display&&_jsx(GridTitle,{title:t.display.title,collapse:void 0===t.display.collapse?void 0:{isOpen:d,onToggleOpen:()=>a((s=>!s))}}),_jsx(Collapse,{in:d,unmountOnExit:!0,children:_jsx(ResponsiveGridLayout,{className:"layout",breakpoints:{lg:1200,md:996,sm:768,xs:480,xxs:0},cols:{lg:24,md:24,sm:24,xs:24,xxs:2},rowHeight:30,draggableHandle:".drag-handle",resizeHandles:["se"],isDraggable:n,isResizable:n,children:m})})]})]})}
1
+ import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{useState}from"react";import{Responsive,WidthProvider}from"react-grid-layout";import{Box,Collapse,GlobalStyles}from"@mui/material";import{styles}from"../../css/styles";import{useEditMode}from"../../context";import{GridTitle}from"./GridTitle";const ResponsiveGridLayout=WidthProvider(Responsive);export function GridLayout(e){var s,i;const{groupIndex:o,definition:{spec:t},renderGridItemContent:r,...l}=e,[d,a]=useState(!!(null===(i=null===(s=t.display)||void 0===s?void 0:s.collapse)||void 0===i?void 0:i.open)),{isEditMode:n}=useEditMode(),p=[];return t.items.forEach(((e,s)=>{const{x:i,y:t,width:l,height:d}=e;p.push(_jsx("div",{"data-grid":{x:i,y:t,w:l,h:d},children:r(e,o)},s))})),_jsxs(_Fragment,{children:[_jsx(GlobalStyles,{styles}),_jsxs(Box,{...l,component:"section",sx:{"& + &":{marginTop:e=>e.spacing(1)}},children:[void 0!==t.display&&_jsx(GridTitle,{groupIndex:o,title:t.display.title,collapse:void 0===t.display.collapse?void 0:{isOpen:d,onToggleOpen:()=>a((e=>!e))}}),_jsx(Collapse,{in:d,unmountOnExit:!0,children:_jsx(ResponsiveGridLayout,{className:"layout",breakpoints:{lg:1200,md:996,sm:768,xs:480,xxs:0},cols:{lg:24,md:24,sm:24,xs:24,xxs:2},rowHeight:30,draggableHandle:".drag-handle",resizeHandles:["se"],isDraggable:n,isResizable:n,children:p})})]})]})}
@@ -1,5 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  export interface GridTitleProps {
3
+ groupIndex: number;
3
4
  title: string;
4
5
  collapse?: {
5
6
  isOpen: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"GridTitle.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridTitle.tsx"],"names":[],"mappings":";AAiBA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE;QACT,MAAM,EAAE,OAAO,CAAC;QAChB,YAAY,EAAE,MAAM,IAAI,CAAC;KAC1B,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,eA6B9C"}
1
+ {"version":3,"file":"GridTitle.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridTitle.tsx"],"names":[],"mappings":";AAqBA,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE;QACT,MAAM,EAAE,OAAO,CAAC;QAChB,YAAY,EAAE,MAAM,IAAI,CAAC;KAC1B,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,eAgD9C"}
@@ -1 +1 @@
1
- import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{ButtonBase,Typography}from"@mui/material";import ExpandedIcon from"mdi-material-ui/ChevronUp";import CollapsedIcon from"mdi-material-ui/ChevronDown";export function GridTitle(o){const{title:e,collapse:n}=o,t=_jsx(Typography,{variant:"h5",sx:{marginLeft:void 0!==n?1:void 0},children:e});return void 0===n?t:_jsxs(ButtonBase,{component:"header",sx:{display:"flex",justifyContent:"start",alignItems:"center"},onClick:n.onToggleOpen,children:[n.isOpen?_jsx(ExpandedIcon,{}):_jsx(CollapsedIcon,{}),t]})}
1
+ import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";import{Box,IconButton,Stack,Typography}from"@mui/material";import ExpandedIcon from"mdi-material-ui/ChevronUp";import CollapsedIcon from"mdi-material-ui/ChevronDown";import AddIcon from"mdi-material-ui/Plus";import PencilIcon from"mdi-material-ui/PencilOutline";import{useState}from"react";import{useDashboardApp,useEditMode}from"../../context";export function GridTitle(o){const{groupIndex:e,title:n,collapse:t}=o,[r,i]=useState(!1),{openPanelDrawer:a,openPanelGroupDialog:s}=useDashboardApp(),{isEditMode:d}=useEditMode(),c=_jsx(Typography,{variant:"h2",sx:{marginLeft:void 0!==t?1:void 0},children:n});return _jsx(Box,{sx:{display:"flex",justifyContent:"start",alignItems:"center",padding:o=>o.spacing(1),backgroundColor:o=>o.palette.background.default},onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),children:t?_jsxs(_Fragment,{children:[_jsx(IconButton,{onClick:t.onToggleOpen,children:t.isOpen?_jsx(ExpandedIcon,{}):_jsx(CollapsedIcon,{})}),c,d&&r&&_jsxs(Stack,{direction:"row",sx:{marginLeft:"auto"},children:[_jsx(IconButton,{onClick:()=>a({groupIndex:e}),children:_jsx(AddIcon,{})}),_jsx(IconButton,{onClick:()=>s(e),children:_jsx(PencilIcon,{})})]})]}):c})}
@@ -3,6 +3,8 @@ import { PanelDefinition } from '@perses-dev/core';
3
3
  import { CardProps } from '@mui/material';
4
4
  export interface PanelProps extends CardProps {
5
5
  definition: PanelDefinition;
6
+ groupIndex: number;
7
+ panelKey: string;
6
8
  }
7
9
  /**
8
10
  * Renders a PanelDefinition's content inside of a Card.
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/Panel.tsx"],"names":[],"mappings":";AAkBA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAGL,SAAS,EAOV,MAAM,eAAe,CAAC;AAOvB,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,eAoHtC"}
1
+ {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/Panel.tsx"],"names":[],"mappings":";AAkBA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAGL,SAAS,EAOV,MAAM,eAAe,CAAC;AAOvB,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,eA2HtC"}
@@ -1 +1 @@
1
- import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useState,useMemo}from"react";import useResizeObserver from"use-resize-observer";import{useInView}from"react-intersection-observer";import{PluginBoundary,PanelComponent}from"@perses-dev/plugin-system";import{ErrorAlert,InfoTooltip,TooltipPlacement}from"@perses-dev/components";import{Box,Card,CardHeader,CardContent,Typography,IconButton as MuiIconButton,Stack,styled}from"@mui/material";import InformationOutlineIcon from"mdi-material-ui/InformationOutline";import PencilIcon from"mdi-material-ui/Pencil";import MenuIcon from"mdi-material-ui/DotsVertical";import DragIcon from"mdi-material-ui/Drag";import{useEditMode}from"../../context";export function Panel(e){const{definition:i,...o}=e,[n,r]=useState(null),{width:t,height:a}=useResizeObserver({ref:n}),s=useMemo((()=>{if(void 0!==t&&void 0!==a)return{width:t,height:a}}),[t,a]),{ref:l,inView:d}=useInView({threshold:.3,initialInView:!1,triggerOnce:!0}),{isEditMode:c}=useEditMode();return _jsxs(Card,{ref:l,sx:{...o.sx,width:"100%",height:"100%",display:"flex",flexFlow:"column nowrap"},variant:"outlined",...o,children:[_jsx(CardHeader,{title:_jsxs(Box,{sx:{display:"flex",alignItems:"center",minHeight:"24px"},children:[_jsx(Typography,{component:"h2",variant:"body2",fontWeight:e=>e.typography.fontWeightMedium,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",children:i.display.name}),_jsxs(Box,{sx:{display:"flex",alignItems:"center",marginLeft:"auto"},children:[!c&&i.display.description&&_jsx(InfoTooltip,{id:"info-tooltip",description:i.display.description,placement:TooltipPlacement.Bottom,children:_jsx(InformationOutlineIcon,{"aria-describedby":"info-tooltip","aria-hidden":!1,fontSize:"small",sx:{cursor:"pointer"}})}),c&&_jsxs(Stack,{direction:"row",alignItems:"center",spacing:.5,children:[_jsx(IconButton,{"aria-label":"drag handle",size:"small",children:_jsx(DragIcon,{className:"drag-handle",sx:{cursor:"grab"}})}),_jsx(IconButton,{"aria-label":"edit panel",size:"small",children:_jsx(PencilIcon,{})}),_jsx(IconButton,{"aria-label":"more",size:"small",children:_jsx(MenuIcon,{})})]})]})]}),sx:{display:"block",padding:e=>e.spacing(1,1.5),borderBottom:e=>`solid 1px ${e.palette.divider}`}}),_jsx(CardContent,{sx:{position:"relative",overflow:"hidden",flexGrow:1,padding:e=>e.spacing(1.5),":last-child":{padding:e=>e.spacing(1.5)}},ref:r,children:_jsx(PluginBoundary,{loadingFallback:"Loading...",ErrorFallbackComponent:ErrorAlert,children:!0===d&&_jsx(PanelComponent,{definition:i,contentDimensions:s})})})]})}const IconButton=styled(MuiIconButton)((({theme:e})=>({borderRadius:e.shape.borderRadius,padding:"4px"})));
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useState,useMemo}from"react";import useResizeObserver from"use-resize-observer";import{useInView}from"react-intersection-observer";import{PluginBoundary}from"@perses-dev/plugin-system";import{ErrorAlert,InfoTooltip,TooltipPlacement}from"@perses-dev/components";import{Box,Card,CardHeader,CardContent,Typography,IconButton as MuiIconButton,Stack,styled}from"@mui/material";import InformationOutlineIcon from"mdi-material-ui/InformationOutline";import PencilIcon from"mdi-material-ui/Pencil";import DragIcon from"mdi-material-ui/DragVertical";import{useDashboardApp,useEditMode}from"../../context";import{PanelContent}from"./PanelContent";export function Panel(e){const{definition:i,groupIndex:o,panelKey:n,...r}=e,[t,a]=useState(null),[s,l]=useState(!1),{width:d,height:p}=useResizeObserver({ref:t}),c=useMemo((()=>{if(void 0!==d&&void 0!==p)return{width:d,height:p}}),[d,p]),{ref:m,inView:u}=useInView({threshold:.3,initialInView:!1,triggerOnce:!0}),{isEditMode:x}=useEditMode(),{openPanelDrawer:f}=useDashboardApp();return _jsxs(Card,{ref:m,sx:{...r.sx,width:"100%",height:"100%",display:"flex",flexFlow:"column nowrap"},variant:"outlined",...r,onMouseEnter:()=>l(!0),onMouseLeave:()=>l(!1),children:[_jsx(CardHeader,{title:_jsxs(Box,{sx:{display:"flex",alignItems:"center",minHeight:"24px"},children:[_jsx(Typography,{component:"h2",variant:"body2",fontWeight:e=>e.typography.fontWeightMedium,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",children:i.display.name}),_jsxs(Box,{sx:{display:"flex",alignItems:"center",marginLeft:"auto"},children:[!x&&s&&i.display.description&&_jsx(InfoTooltip,{id:"info-tooltip",description:i.display.description,placement:TooltipPlacement.Bottom,children:_jsx(InformationOutlineIcon,{"aria-describedby":"info-tooltip","aria-hidden":!1,fontSize:"small",sx:{cursor:"pointer"}})}),x&&s&&_jsxs(Stack,{direction:"row",alignItems:"center",spacing:.5,children:[_jsx(IconButton,{"aria-label":"edit panel",size:"small",onClick:()=>{f({groupIndex:o,panelKey:n})},children:_jsx(PencilIcon,{})}),_jsx(IconButton,{"aria-label":"drag handle",size:"small",children:_jsx(DragIcon,{className:"drag-handle",sx:{cursor:"grab"}})})]})]})]}),sx:{display:"block",padding:e=>e.spacing(1,1.5),borderBottom:e=>`solid 1px ${e.palette.divider}`}}),_jsx(CardContent,{sx:{position:"relative",overflow:"hidden",flexGrow:1,padding:e=>e.spacing(1.5),":last-child":{padding:e=>e.spacing(1.5)}},ref:a,children:_jsx(PluginBoundary,{loadingFallback:"Loading...",ErrorFallbackComponent:ErrorAlert,children:!0===u&&_jsx(PanelContent,{definition:i,contentDimensions:c})})})]})}const IconButton=styled(MuiIconButton)((({theme:e})=>({borderRadius:e.shape.borderRadius,padding:"4px"})));
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.test.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/Panel.test.tsx"],"names":[],"mappings":"AAeA,OAAO,uBAAuB,CAAC"}
1
+ {"version":3,"file":"Panel.test.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/Panel.test.tsx"],"names":[],"mappings":"AAcA,OAAO,uBAAuB,CAAC"}
@@ -1 +1 @@
1
- import{jsx as _jsx}from"react/jsx-runtime";import{PluginRegistry}from"@perses-dev/plugin-system";import"intersection-observer";import{screen}from"@testing-library/react";import{renderWithContext,mockPluginRegistryProps}from"../../test";import testDashboard from"../../test/testDashboard";import{DashboardProvider}from"../../context";import{Panel}from"./Panel";const FAKE_PANEL_PLUGIN={pluginType:"Panel",kind:"FakePanel",plugin:{PanelComponent:()=>_jsx("div",{role:"figure",children:"FakePanel chart"})}};describe("Panel",(()=>{let e,r;beforeEach((()=>{e={definition:{display:{name:"Fake Panel",description:"This is a fake panel"},kind:"FakePanel",options:{}}},r={isEditMode:!1,dashboardSpec:testDashboard.spec}}));const i=r=>{const{addMockPlugin:i,pluginRegistryProps:n}=mockPluginRegistryProps();i(FAKE_PANEL_PLUGIN),renderWithContext(_jsx(DashboardProvider,{initialState:r,children:_jsx(PluginRegistry,{...n,children:_jsx(Panel,{...e})})}))};it("should render name and info icon",(async()=>{i(r),await screen.findByText("Fake Panel"),screen.queryByLabelText("info-tooltip")})),it("should render edit icons when in edit mode",(async()=>{r.isEditMode=!0,i(r),await screen.queryByLabelText("drag handle"),screen.queryByLabelText("edit panel"),screen.queryByLabelText("more")}))}));
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{PluginRegistry}from"@perses-dev/plugin-system";import"intersection-observer";import{screen}from"@testing-library/react";import{renderWithContext,mockPluginRegistryProps,FAKE_PANEL_PLUGIN}from"../../test";import testDashboard from"../../test/testDashboard";import{Panel}from"./Panel";describe("Panel",(()=>{let e,r;beforeEach((()=>{e={definition:{display:{name:"Fake Panel",description:"This is a fake panel"},kind:"FakePanel",options:{}},groupIndex:0,panelKey:"panelRef"},r={isEditMode:!1,dashboardSpec:testDashboard.spec}}));const n=r=>{const{addMockPlugin:n,pluginRegistryProps:t}=mockPluginRegistryProps();n("Panel","FakePanel",FAKE_PANEL_PLUGIN),renderWithContext(_jsx(PluginRegistry,{...t,children:_jsx(Panel,{...e})}),r)};it("should render name and info icon",(async()=>{n(),await screen.findByText("Fake Panel"),screen.queryByLabelText("info-tooltip")})),it("should render edit icons when in edit mode",(async()=>{r.isEditMode=!0,n(r),await screen.queryByLabelText("drag handle"),screen.queryByLabelText("edit panel"),screen.queryByLabelText("more")}))}));
@@ -0,0 +1,11 @@
1
+ /// <reference types="react" />
2
+ import { JsonObject } from '@perses-dev/core';
3
+ import { PanelProps } from '@perses-dev/plugin-system';
4
+ export declare type PanelContentProps = PanelProps<JsonObject>;
5
+ /**
6
+ * A small wrapper component that renders the appropriate PanelComponent from a Panel plugin based on the panel
7
+ * definition's kind. Used so that a PluginLoadingBoundary can be wrapped around this for fallback UI while
8
+ * the plugin is loading.
9
+ */
10
+ export declare function PanelContent(props: PanelContentProps): JSX.Element;
11
+ //# sourceMappingURL=PanelContent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelContent.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelContent.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAkB,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvE,oBAAY,iBAAiB,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,eAGpD"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{usePanelPlugin}from"@perses-dev/plugin-system";export function PanelContent(n){const{PanelComponent:e}=usePanelPlugin(n.definition.kind);return _jsx(e,{...n})}
@@ -0,0 +1,2 @@
1
+ export * from './Panel';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/index.ts"],"names":[],"mappings":"AAaA,cAAc,SAAS,CAAC"}
@@ -0,0 +1 @@
1
+ export*from"./Panel";
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ declare const PanelDrawer: () => JSX.Element;
3
+ export default PanelDrawer;
4
+ //# sourceMappingURL=PanelDrawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelDrawer.tsx"],"names":[],"mappings":";AAuCA,QAAA,MAAM,WAAW,mBA0JhB,CAAC;AA2BF,eAAe,WAAW,CAAC"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{MenuItem,Stack,Select,TextField,InputLabel,FormControl,Grid,Box,Button,Typography}from"@mui/material";import{Drawer,ErrorAlert}from"@perses-dev/components";import{PluginBoundary}from"@perses-dev/plugin-system";import{useState,useEffect}from"react";import{useDashboardApp,useLayouts,usePanels}from"../../context";import{removeWhiteSpacesAndSpecialCharacters}from"../../utils/functions";import{PanelOptionsEditor}from"./PanelOptionsEditor";const PanelDrawer=()=>{var e,l,n,a;const{layouts:r}=useLayouts(),{panels:i,updatePanel:t}=usePanels(),{panelDrawer:o,closePanelDrawer:s}=useDashboardApp();let d="",u="";(null==o?void 0:o.panelKey)&&(d=null!==(l=null===(e=i[o.panelKey])||void 0===e?void 0:e.display.name)&&void 0!==l?l:"",u=null!==(a=null===(n=i[o.panelKey])||void 0===n?void 0:n.display.description)&&void 0!==a?a:"");const[p,c]=useState(null==o?void 0:o.groupIndex),[x,v]=useState(d),[m,h]=useState(u),[y,g]=useState(""),[j,_]=useState({});useEffect((()=>{var e,l,n,a;c(null==o?void 0:o.groupIndex),(null==o?void 0:o.panelKey)?(v(null!==(l=null===(e=i[o.panelKey])||void 0===e?void 0:e.display.name)&&void 0!==l?l:""),h(null!==(a=null===(n=i[o.panelKey])||void 0===n?void 0:n.display.description)&&void 0!==a?a:"")):(v(""),h(""))}),[o,i]);return _jsx(Drawer,{isOpen:!!o,onClose:()=>s(),children:_jsxs("form",{onSubmit:e=>{e.preventDefault(),void 0===(null==o?void 0:o.groupIndex)||(null==o?void 0:o.panelKey)?(null==o?void 0:o.panelKey)&&(void 0!==(null==o?void 0:o.panelKey)&&t(o.panelKey,{...i[o.panelKey],kind:y,options:j,display:{name:null!=x?x:"",description:m}})):(()=>{if(void 0===(null==o?void 0:o.groupIndex))return;const e=removeWhiteSpacesAndSpecialCharacters(x);t(e,{kind:y,options:j,display:{name:x,description:m}},o.groupIndex)})(),s()},children:[_jsx(PanelDrawerHeader,{panelKey:null==o?void 0:o.panelKey,onClose:()=>s()}),_jsxs(Grid,{container:!0,spacing:2,children:[_jsx(Grid,{item:!0,xs:4,children:_jsxs(FormControl,{children:[_jsx(InputLabel,{id:"select-group",children:"Group"}),_jsx(Select,{required:!0,labelId:"select-group",label:"Group",value:null!=p?p:0,onChange:e=>{const{value:l}=e.target;"string"!=typeof l&&c(l)},children:r.map(((e,l)=>{var n;return _jsx(MenuItem,{value:l,children:(null===(n=e.spec.display)||void 0===n?void 0:n.title)||`Group ${l+1}`},l)}))})]})}),_jsx(Grid,{item:!0,xs:8,children:_jsxs(Stack,{spacing:2,sx:{flexGrow:"1"},children:[_jsx(TextField,{required:!0,label:"Panel Name",value:x,variant:"outlined",onChange:e=>{v(e.target.value)}}),_jsx(TextField,{label:"Description",value:m,variant:"outlined",onChange:e=>{h(e.target.value)}})]})}),_jsx(Grid,{item:!0,xs:4,children:_jsxs(FormControl,{children:[_jsx(InputLabel,{id:"panel-type-label",children:"Panel Type"}),_jsxs(Select,{required:!0,labelId:"panel-type-label",label:"Panel Type",value:y,onChange:e=>{g(e.target.value)},children:[_jsx(MenuItem,{value:"LineChart",children:"Line Chart"}),_jsx(MenuItem,{value:"GaugeChart",children:"Gauge Chart"}),_jsx(MenuItem,{value:"StatChart",children:"Stat Chart"})]})]})}),_jsx(Grid,{item:!0,xs:8,children:_jsx(PluginBoundary,{loadingFallback:"Loading...",ErrorFallbackComponent:ErrorAlert,children:""!==y&&_jsx(PanelOptionsEditor,{kind:y,value:j,onChange:e=>{_(e)}})})})]})]})})},PanelDrawerHeader=({panelKey:e,onClose:l})=>_jsxs(Box,{sx:{display:"flex",alignItems:"center",marginBottom:e=>e.spacing(2),paddingBottom:e=>e.spacing(2),borderBottom:e=>`1px solid ${e.palette.grey[100]}`},children:[_jsx(Typography,{variant:"h2",children:(e?"Edit":"Add")+" Panel"}),_jsxs(Stack,{direction:"row",spacing:1,sx:{marginLeft:"auto"},children:[_jsx(Button,{type:"submit",variant:"contained",children:e?"Apply":"Add"}),_jsx(Button,{variant:"outlined",onClick:l,children:"Cancel"})]})]});export default PanelDrawer;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=PanelDrawer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelDrawer.test.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelDrawer.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{PluginRegistry}from"@perses-dev/plugin-system";import{screen}from"@testing-library/react";import userEvent from"@testing-library/user-event";import*as dashboardAppSlice from"../../context/DashboardAppSlice";import*as layoutsSlice from"../../context/LayoutsSlice";import*as context from"../../context/DashboardProvider";import{FAKE_PANEL_PLUGIN,mockPluginRegistryProps,renderWithContext}from"../../test";import testDashboard from"../../test/testDashboard";import PanelDrawer from"./PanelDrawer";const updatePanel=jest.fn();jest.spyOn(context,"usePanels").mockReturnValue({updatePanel,panels:{}});const addItemToLayout=jest.fn();jest.spyOn(layoutsSlice,"useLayouts").mockReturnValue({addItemToLayout,updateLayout:jest.fn(),layouts:testDashboard.spec.layouts});const dashboardApp={panelDrawer:{groupIndex:0},openPanelDrawer:jest.fn(),closePanelDrawer:jest.fn(),panelGroupDialog:void 0,openPanelGroupDialog:jest.fn(),closePanelGroupDialog:jest.fn()};describe("Panel Drawer",(()=>{beforeEach((()=>{jest.clearAllMocks()}));const e=()=>{const{addMockPlugin:e,pluginRegistryProps:t}=mockPluginRegistryProps();e("Panel","FakePanel",FAKE_PANEL_PLUGIN),renderWithContext(_jsxs(PluginRegistry,{...t,children:[_jsx(PanelDrawer,{}),","]}))};it("should add new panel",(()=>{jest.spyOn(dashboardAppSlice,"useDashboardApp").mockReturnValue(dashboardApp),e();const t=screen.getByLabelText(/Panel Name/);userEvent.type(t,"New Panel"),userEvent.click(screen.getByText("Add")),expect(updatePanel).toHaveBeenCalledWith("NewPanel",{kind:"",display:{name:"New Panel",description:""},options:{}},0)})),it("should edit an existing panel",(()=>{jest.spyOn(dashboardAppSlice,"useDashboardApp").mockReturnValue({...dashboardApp,panelDrawer:{groupIndex:0,panelKey:"cpu"}}),e();const t=screen.getByLabelText(/Panel Name/);userEvent.type(t,"cpu usage"),userEvent.click(screen.getByText("Apply")),expect(updatePanel).toHaveBeenCalledWith("cpu",{display:{name:"cpu usage",description:""},kind:"",options:{}})}))}));
@@ -0,0 +1,9 @@
1
+ /// <reference types="react" />
2
+ import { JsonObject } from '@perses-dev/core';
3
+ export interface PanelOptionsEditorProps {
4
+ kind: string;
5
+ value: JsonObject;
6
+ onChange: (next: JsonObject) => void;
7
+ }
8
+ export declare function PanelOptionsEditor(props: PanelOptionsEditorProps): JSX.Element;
9
+ //# sourceMappingURL=PanelOptionsEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelOptionsEditor.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelOptionsEditor.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;CACtC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,eAchE"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{usePanelPlugin}from"@perses-dev/plugin-system";import{useEffect}from"react";export function PanelOptionsEditor(e){const{kind:n,value:t,onChange:o}=e,{OptionsEditorComponent:s,createInitialOptions:i}=usePanelPlugin(n);return useEffect((()=>{o(i())}),[n]),_jsx(s,{value:t,onChange:o})}
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ declare const PanelGroupDialog: () => JSX.Element;
3
+ export default PanelGroupDialog;
4
+ //# sourceMappingURL=PanelGroupDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelGroupDialog.d.ts","sourceRoot":"","sources":["../../../src/components/PanelGroupDialog/PanelGroupDialog.tsx"],"names":[],"mappings":";AAkCA,QAAA,MAAM,gBAAgB,mBA4FrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useState}from"react";import{IconButton,Dialog,DialogTitle,DialogContent,FormControl,InputLabel,TextField,Stack,Box,DialogActions,Button,Select,MenuItem}from"@mui/material";import CloseIcon from"mdi-material-ui/Close";import{useDashboardApp,useLayouts}from"../../context";const PanelGroupDialog=()=>{var e,l,o,t,i;const{layouts:s,updateLayout:n}=useLayouts(),{panelGroupDialog:a,closePanelGroupDialog:r}=useDashboardApp(),{groupIndex:u}=a,d=void 0!==u,[p,c]=useState(d&&!(null===(o=null===(l=null===(e=s[u])||void 0===e?void 0:e.spec.display)||void 0===l?void 0:l.collapse)||void 0===o?void 0:o.open)),[x,m]=useState(d?null===(i=null===(t=s[u])||void 0===t?void 0:t.spec.display)||void 0===i?void 0:i.title:"");return _jsxs(Dialog,{open:!0,children:[_jsx(DialogTitle,{children:"Panel Group"}),_jsx(IconButton,{"aria-label":"Close",onClick:()=>r(),sx:e=>({position:"absolute",top:e.spacing(.5),right:e.spacing(.5)}),children:_jsx(CloseIcon,{})}),_jsxs("form",{onSubmit:e=>{var l,o;e.preventDefault();const t={kind:"Grid",spec:{display:{title:null!=x?x:"",collapse:{open:!p}},items:void 0===u?[]:null!==(o=null===(l=s[u])||void 0===l?void 0:l.spec.items)&&void 0!==o?o:[]}};n(t,u),r()},children:[_jsx(DialogContent,{sx:{width:"500px"},children:_jsxs(Stack,{spacing:2,children:[_jsx(FormControl,{children:_jsx(TextField,{required:!0,label:"Name",variant:"outlined",value:x,onChange:e=>m(e.target.value)})}),_jsxs(Box,{sx:{display:"flex",alignItems:"center",width:"100%",justifyContent:"space-between"},children:[_jsx(InputLabel,{children:"Collapse State"}),_jsxs(Select,{required:!0,displayEmpty:!0,labelId:"select-collapse-state",size:"small",value:p?"Close":"Open",onChange:e=>{const l="Close"===e.target.value;c(l)},children:[_jsx(MenuItem,{value:"Open",children:"Open"},"open"),_jsx(MenuItem,{value:"Close",children:"Close"},"close")]})]})]})}),_jsxs(DialogActions,{children:[_jsx(Button,{variant:"contained",type:"submit",children:d?"Apply":"Add"}),_jsx(Button,{onClick:()=>r(),children:"Cancel"})]})]})]})};export default PanelGroupDialog;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=PanelGroupDialog.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelGroupDialog.test.d.ts","sourceRoot":"","sources":["../../../src/components/PanelGroupDialog/PanelGroupDialog.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{screen}from"@testing-library/react";import userEvent from"@testing-library/user-event";import produce from"immer";import*as dashboardAppSlice from"../../context/DashboardAppSlice";import*as layoutsSlice from"../../context/LayoutsSlice";import{renderWithContext}from"../../test";import testDashboard from"../../test/testDashboard";import PanelGroupDialog from"./PanelGroupDialog";const dashboardApp={panelDrawer:void 0,openPanelDrawer:jest.fn(),closePanelDrawer:jest.fn(),panelGroupDialog:{groupIndex:void 0},openPanelGroupDialog:jest.fn(),closePanelGroupDialog:jest.fn()},updateLayout=jest.fn();jest.spyOn(layoutsSlice,"useLayouts").mockReturnValue({updateLayout,addItemToLayout:jest.fn(),layouts:testDashboard.spec.layouts}),describe("Add Panel Group",(()=>{beforeEach((()=>{jest.clearAllMocks()})),it("should add new panel group",(()=>{jest.spyOn(dashboardAppSlice,"useDashboardApp").mockReturnValue(dashboardApp),renderWithContext(_jsx(PanelGroupDialog,{}));const e=screen.getByLabelText(/Name/);userEvent.type(e,"New Panel Group"),userEvent.click(screen.getByText("Add")),expect(updateLayout).toHaveBeenCalledWith({kind:"Grid",spec:{display:{title:"New Panel Group",collapse:{open:!0}},items:[]}},void 0)})),it("should edit existing panel group",(()=>{jest.spyOn(dashboardAppSlice,"useDashboardApp").mockReturnValue({...dashboardApp,panelGroupDialog:{groupIndex:0}}),renderWithContext(_jsx(PanelGroupDialog,{}));const e=screen.getByLabelText(/Name/);userEvent.type(e,"New Name"),userEvent.click(screen.getByText("Apply")),expect(updateLayout).toHaveBeenCalledWith(produce(testDashboard.spec.layouts[0],(e=>{e.spec.display.title+="New Name",e.spec.display.collapse={open:!1}})),0)}))}));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeRangeControls.d.ts","sourceRoot":"","sources":["../../../src/components/TimeRangeControls/TimeRangeControls.tsx"],"names":[],"mappings":";AAeA,OAAO,EAAyC,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAY3F,eAAO,MAAM,YAAY,EAAE,UAAU,EAUpC,CAAC;AAEF,wBAAgB,iBAAiB,gBA2DhC"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useRef,useState}from"react";import{Box,FormControl,Popover,Stack}from"@mui/material";import{AbsoluteTimePicker,TimeRangeSelector}from"@perses-dev/components";import{getDefaultTimeRange}from"@perses-dev/core";import{useTimeRange,useQueryString}from"@perses-dev/plugin-system";import{useDashboard}from"../../context";export const TIME_OPTIONS=[{value:{pastDuration:"5m"},display:"Last 5 minutes"},{value:{pastDuration:"15m"},display:"Last 15 minutes"},{value:{pastDuration:"30m"},display:"Last 30 minutes"},{value:{pastDuration:"1h"},display:"Last 1 hour"},{value:{pastDuration:"6h"},display:"Last 6 hours"},{value:{pastDuration:"12h"},display:"Last 12 hours"},{value:{pastDuration:"24h"},display:"Last 1 day"},{value:{pastDuration:"7d"},display:"Last 7 days"},{value:{pastDuration:"14d"},display:"Last 14 days"}];export function TimeRangeControls(){const{timeRange:e,setTimeRange:t}=useTimeRange(),{dashboard:a}=useDashboard(),{queryString:s}=useQueryString(),r=getDefaultTimeRange(a.duration,s),[o,i]=useState(r),[n,u]=useState(!1),l=useRef();return _jsxs(Stack,{direction:"row",spacing:1,children:[_jsx(Popover,{anchorEl:l.current,anchorOrigin:{vertical:"bottom",horizontal:"center"},open:n,onClose:()=>u(!1),sx:e=>({padding:e.spacing(2)}),children:_jsx(AbsoluteTimePicker,{initialTimeRange:e,onChange:e=>{t(e),i(e),u(!1)}})}),_jsx(FormControl,{fullWidth:!0,children:_jsx(Box,{ref:l,children:_jsx(TimeRangeSelector,{timeOptions:TIME_OPTIONS,value:o,onSelectChange:e=>{const a={pastDuration:e.target.value,end:new Date};t(a),i(a),u(!1)},onCustomClick:()=>{u(!0)}})})})]})}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TimeRangeControls.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeRangeControls.test.d.ts","sourceRoot":"","sources":["../../../src/components/TimeRangeControls/TimeRangeControls.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx}from"react/jsx-runtime";import userEvent from"@testing-library/user-event";import{getDefaultTimeRange}from"@perses-dev/core";import{screen}from"@testing-library/react";import{renderWithContext}from"../../test";import testDashboard from"../../test/testDashboard";import{DashboardProvider,TimeRangeProvider,QueryStringProvider}from"../../context";import{TimeRangeControls}from"./TimeRangeControls";describe("TimeRangeControls",(()=>{let e;beforeEach((()=>{e={dashboardSpec:testDashboard.spec}}));const t=()=>{const t=new URLSearchParams,r=getDefaultTimeRange(e.dashboardSpec.duration,t);renderWithContext(_jsx(QueryStringProvider,{queryString:t,children:_jsx(DashboardProvider,{initialState:e,children:_jsx(TimeRangeProvider,{initialTimeRange:r,children:_jsx(TimeRangeControls,{})})})}))};it("should render correct initial relative time shortcut",(async()=>{t(),expect(screen.getByText("Last 1 day")).toBeInTheDocument()})),it("should be able to select the first option",(()=>{t();const e=screen.getByRole("button");userEvent.click(e);const r=screen.getByRole("option",{name:"Last 5 minutes"});userEvent.click(r),expect(e).toHaveTextContent(/5 minutes/i)}))}));
@@ -0,0 +1,2 @@
1
+ export * from './TimeRangeControls';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TimeRangeControls/index.ts"],"names":[],"mappings":"AAaA,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export*from"./TimeRangeControls";
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { VariableName } from '@perses-dev/core';
3
+ declare type TemplateVariableProps = {
4
+ name: VariableName;
5
+ };
6
+ export declare function TemplateVariable({ name }: TemplateVariableProps): JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=Variable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Variable.d.ts","sourceRoot":"","sources":["../../../src/components/Variables/Variable.tsx"],"names":[],"mappings":";AAgBA,OAAO,EAAE,YAAY,EAA0B,MAAM,kBAAkB,CAAC;AAGxE,aAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,EAAE,qBAAqB,eAW/D"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useEffect,useRef}from"react";import{Select,FormControl,InputLabel,MenuItem,Box,LinearProgress,IconButton,TextField}from"@mui/material";import{Reload}from"mdi-material-ui";import{useTemplateVariable,useTemplateVariableActions,useTemplateVariableStore}from"../../context";export function TemplateVariable({name:e}){var a;const l=null===(a=useTemplateVariable(e).definition)||void 0===a?void 0:a.kind;switch(l){case"TextVariable":return _jsx(TextVariable,{name:e});case"ListVariable":return _jsx(ListVariable,{name:e})}return _jsxs("div",{children:["Unsupported Variable Kind: $",l]})}function ListVariable({name:e}){var a,l,t,i;const r=useTemplateVariable(e),n=r.definition,{setVariableValue:o,loadTemplateVariable:s}=useTemplateVariableActions(),u=!0===(null==n?void 0:n.options.allowMultiple);useEffect((()=>{s(e)}),[e,s]);let d=null===(a=r.state)||void 0===a?void 0:a.value;return u&&!Array.isArray(d)&&(d=[]),_jsxs(Box,{display:"flex",children:[_jsxs(FormControl,{children:[_jsx(InputLabel,{id:e,children:e}),_jsx(Select,{id:e,label:e,value:d,onChange:a=>{o(e,a.target.value)},multiple:u,children:null===(t=null===(l=r.state)||void 0===l?void 0:l.options)||void 0===t?void 0:t.map((e=>_jsx(MenuItem,{value:e.value,children:e.label},e.value)))}),(null===(i=r.state)||void 0===i?void 0:i.loading)&&_jsx(LinearProgress,{})]}),_jsx(IconButton,{onClick:()=>s(e),children:_jsx(Reload,{})})]})}function TextVariable({name:e}){const{state:a}=useTemplateVariable(e),l=useTemplateVariableStore().setVariableValue,t=useRef(null);return _jsx(TextField,{ref:t,defaultValue:null==a?void 0:a.value,onBlur:a=>l(e,a.target.value),placeholder:e,label:e})}
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ export declare function TemplateVariableList(): JSX.Element;
3
+ //# sourceMappingURL=VariableList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VariableList.d.ts","sourceRoot":"","sources":["../../../src/components/Variables/VariableList.tsx"],"names":[],"mappings":";AA8BA,wBAAgB,oBAAoB,gBA2CnC"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";import{useState}from"react";import{Button,Stack,Box,Drawer,TableContainer,TableBody,TableRow,TableCell,Table,Paper,TableHead}from"@mui/material";import{useTemplateVariableDefinitions,useEditMode}from"../../context";import{TemplateVariable}from"./Variable";export function TemplateVariableList(){const[e,a]=useState(!1),l=useTemplateVariableDefinitions(),{isEditMode:i}=useEditMode();return _jsxs(Box,{m:2,children:[_jsx(Drawer,{anchor:"right",open:e,onClose:()=>a(!1),children:_jsxs(Box,{width:900,p:4,children:[_jsx(TableContainer,{component:Paper,children:_jsxs(Table,{sx:{minWidth:650},"aria-label":"simple table",children:[_jsx(TableHead,{children:_jsxs(TableRow,{children:[_jsx(TableCell,{children:"Variable Name"}),_jsx(TableCell,{align:"right",children:"Type"})]})}),_jsx(TableBody,{children:l.map((e=>_jsxs(TableRow,{sx:{"&:last-child td, &:last-child th":{border:0}},children:[_jsx(TableCell,{component:"th",scope:"row",sx:{fontWeight:"bold"},children:e.name}),_jsx(TableCell,{align:"right",children:e.kind})]},e.name)))})]})}),_jsx("pre",{children:JSON.stringify(l,null,2)})]})}),_jsx(Box,{display:"flex",justifyContent:"space-between",children:_jsxs(Stack,{direction:"row",spacing:2,children:[l.map((e=>_jsx(Box,{children:_jsx(TemplateVariable,{name:e.name},e.name)},e.name))),i&&_jsx(Button,{onClick:()=>a(!0),children:"Modify Variables"})]})})]})}
@@ -0,0 +1,3 @@
1
+ export * from './Variable';
2
+ export * from './VariableList';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Variables/index.tsx"],"names":[],"mappings":"AAaA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export*from"./Variable";export*from"./VariableList";
@@ -1,7 +1,6 @@
1
1
  export * from './Dashboard';
2
2
  export * from './GridLayout';
3
- export * from './Panel/Panel';
3
+ export * from './Panel';
4
4
  export * from './TimeRangeControls';
5
- export * from './VariableAutocomplete';
6
- export * from './VariableList';
5
+ export * from './Variables';
7
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAaA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAaA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC"}
@@ -1 +1 @@
1
- export*from"./Dashboard";export*from"./GridLayout";export*from"./Panel/Panel";export*from"./TimeRangeControls";export*from"./VariableAutocomplete";export*from"./VariableList";
1
+ export*from"./Dashboard";export*from"./GridLayout";export*from"./Panel";export*from"./TimeRangeControls";export*from"./Variables";
@@ -0,0 +1,26 @@
1
+ interface PanelDrawer {
2
+ groupIndex?: number;
3
+ panelKey?: string;
4
+ }
5
+ interface PanelGroupDialog {
6
+ groupIndex?: number;
7
+ }
8
+ export interface DashboardAppSlice {
9
+ panelDrawer?: PanelDrawer;
10
+ openPanelDrawer: (panelDrawer: PanelDrawer) => void;
11
+ closePanelDrawer: () => void;
12
+ panelGroupDialog?: PanelGroupDialog;
13
+ openPanelGroupDialog: (groupIndex?: number) => void;
14
+ closePanelGroupDialog: () => void;
15
+ }
16
+ export declare const createDashboardAppSlice: import("zustand").StateCreator<DashboardAppSlice, [], [["zustand/immer", never]], DashboardAppSlice>;
17
+ export declare function useDashboardApp(): {
18
+ panelDrawer: PanelDrawer | undefined;
19
+ openPanelDrawer: (panelDrawer: PanelDrawer) => void;
20
+ closePanelDrawer: () => void;
21
+ panelGroupDialog: PanelGroupDialog | undefined;
22
+ openPanelGroupDialog: (groupIndex?: number | undefined) => void;
23
+ closePanelGroupDialog: () => void;
24
+ };
25
+ export {};
26
+ //# sourceMappingURL=DashboardAppSlice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardAppSlice.d.ts","sourceRoot":"","sources":["../../src/context/DashboardAppSlice.tsx"],"names":[],"mappings":"AAgBA,UAAU,WAAW;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AACD,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC;IACpD,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,oBAAoB,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,qBAAqB,EAAE,MAAM,IAAI,CAAC;CACnC;AAED,eAAO,MAAM,uBAAuB,sGAoBjC,CAAC;AAEJ,wBAAgB,eAAe;;;;;;;EAkB9B"}
@@ -0,0 +1 @@
1
+ import{immer}from"zustand/middleware/immer";import{useDashboardStore}from"./DashboardProvider";export const createDashboardAppSlice=immer((e=>({openPanelDrawer:({groupIndex:a,panelKey:r})=>e((e=>{e.panelDrawer={groupIndex:a,panelKey:r}})),closePanelDrawer:()=>e((e=>{e.panelDrawer=void 0})),openPanelGroupDialog:a=>e((e=>{e.panelGroupDialog={groupIndex:a}})),closePanelGroupDialog:()=>e((e=>{e.panelGroupDialog=void 0}))})));export function useDashboardApp(){return useDashboardStore((({panelDrawer:e,openPanelDrawer:a,closePanelDrawer:r,panelGroupDialog:o,openPanelGroupDialog:l,closePanelGroupDialog:p})=>({panelDrawer:e,openPanelDrawer:a,closePanelDrawer:r,panelGroupDialog:o,openPanelGroupDialog:l,closePanelGroupDialog:p})))}
@@ -1,20 +1,15 @@
1
1
  /// <reference types="react" />
2
- import { DashboardSpec, GridItemDefinition, LayoutDefinition, PanelDefinition } from '@perses-dev/core';
3
- interface DashboardState {
2
+ import { DashboardSpec, LayoutDefinition, PanelDefinition } from '@perses-dev/core';
3
+ import { DashboardAppSlice } from './DashboardAppSlice';
4
+ import { LayoutsSlice } from './LayoutsSlice';
5
+ export interface DashboardStoreState extends DashboardAppSlice, LayoutsSlice {
4
6
  dashboard: DashboardSpec;
5
- isEditMode: boolean;
6
7
  layouts: LayoutDefinition[];
7
8
  panels: Record<string, PanelDefinition>;
8
- }
9
- interface DashboardActions {
9
+ updatePanel: (name: string, panel: PanelDefinition, groupIndex?: number) => void;
10
+ isEditMode: boolean;
10
11
  setEditMode: (isEditMode: boolean) => void;
11
- setLayouts: (layouts: LayoutDefinition[]) => void;
12
- addLayout: (layout: LayoutDefinition) => void;
13
- addItemToLayout: (index: number, item: GridItemDefinition) => void;
14
- setPanels: (panels: Record<string, PanelDefinition>) => void;
15
- addPanel: (name: string, panel: PanelDefinition) => void;
16
12
  }
17
- export declare type DashboardStoreState = DashboardState & DashboardActions;
18
13
  export interface DashboardStoreProps {
19
14
  dashboardSpec: DashboardSpec;
20
15
  isEditMode?: boolean;
@@ -25,13 +20,7 @@ export interface DashboardProviderProps {
25
20
  }
26
21
  export declare function usePanels(): {
27
22
  panels: Record<string, PanelDefinition<import("@perses-dev/core").JsonObject>>;
28
- addPanel: (name: string, panel: PanelDefinition<import("@perses-dev/core").JsonObject>) => void;
29
- };
30
- export declare function useLayouts(): {
31
- layouts: import("@perses-dev/core").GridDefinition[];
32
- setLayouts: (layouts: import("@perses-dev/core").GridDefinition[]) => void;
33
- addLayout: (layout: import("@perses-dev/core").GridDefinition) => void;
34
- addItemToLayout: (index: number, item: GridItemDefinition) => void;
23
+ updatePanel: (name: string, panel: PanelDefinition<import("@perses-dev/core").JsonObject>, groupIndex?: number | undefined) => void;
35
24
  };
36
25
  export declare function useEditMode(): {
37
26
  isEditMode: boolean;
@@ -40,6 +29,6 @@ export declare function useEditMode(): {
40
29
  export declare function useDashboard(): {
41
30
  dashboard: DashboardSpec;
42
31
  };
32
+ export declare function useDashboardStore<T>(selector: (state: DashboardStoreState) => T): T;
43
33
  export declare function DashboardProvider(props: DashboardProviderProps): JSX.Element;
44
- export {};
45
34
  //# sourceMappingURL=DashboardProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardProvider.d.ts","sourceRoot":"","sources":["../../src/context/DashboardProvider.tsx"],"names":[],"mappings":";AAiBA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExG,UAAU,cAAc;IACtB,SAAS,EAAE,aAAa,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CACzC;AAED,UAAU,gBAAgB;IACxB,WAAW,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,UAAU,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAClD,SAAS,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnE,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,KAAK,IAAI,CAAC;IAC7D,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CAC1D;AAED,oBAAY,mBAAmB,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEpE,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AACD,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,mBAAmB,CAAC;IAClC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAID,wBAAgB,SAAS;;;EAGxB;AAED,wBAAgB,UAAU;;;;;EAUzB;AAED,wBAAgB,WAAW;;;EAG1B;AAED,wBAAgB,YAAY;;EAU3B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,eA4C9D"}
1
+ {"version":3,"file":"DashboardProvider.d.ts","sourceRoot":"","sources":["../../src/context/DashboardProvider.tsx"],"names":[],"mappings":";AAmBA,OAAO,EAAE,aAAa,EAAsB,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,EAAE,iBAAiB,EAA2B,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAsB,MAAM,gBAAgB,CAAC;AAElE,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB,EAAE,YAAY;IAC1E,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjF,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AACD,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,mBAAmB,CAAC;IAClC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,wBAAgB,SAAS;;;EAExB;AAED,wBAAgB,WAAW;;;EAE1B;AAED,wBAAgB,YAAY;;EAU3B;AAID,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,CAAC,KAM/E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,eAqD9D"}
@@ -1 +1 @@
1
- import{jsx as _jsx}from"react/jsx-runtime";import create from"zustand";import createZustandContext from"zustand/context";import produce from"immer";const{Provider,useStore}=createZustandContext();export function usePanels(){const{panels:t,addPanel:e}=useStore((({panels:t,addPanel:e})=>({panels:t,addPanel:e})));return{panels:t,addPanel:e}}export function useLayouts(){const{layouts:t,setLayouts:e,addLayout:o,addItemToLayout:a}=useStore((({layouts:t,setLayouts:e,addLayout:o,addItemToLayout:a})=>({layouts:t,setLayouts:e,addLayout:o,addItemToLayout:a})));return{layouts:t,setLayouts:e,addLayout:o,addItemToLayout:a}}export function useEditMode(){const{isEditMode:t,setEditMode:e}=useStore((({isEditMode:t,setEditMode:e})=>({isEditMode:t,setEditMode:e})));return{isEditMode:t,setEditMode:e}}export function useDashboard(){return{dashboard:useStore((t=>produce(t.dashboard,(e=>{e.panels=t.panels,e.layouts=t.layouts}))))}}export function DashboardProvider(t){const{children:e,initialState:{dashboardSpec:o,isEditMode:a}}=t,{layouts:d,panels:s}=o;return _jsx(Provider,{createStore:()=>create((t=>({layouts:d,panels:s,dashboard:o,isEditMode:!!a,setEditMode:e=>t({isEditMode:e}),setLayouts:e=>t({layouts:e}),addLayout:e=>t(produce((t=>{t.layouts.push(e)}))),addItemToLayout:(e,o)=>t(produce((t=>{t.layouts[e].spec.items.push(o)}))),setPanels:e=>t({panels:e}),addPanel:(e,o)=>{t(produce((t=>{t.panels[e]=o}),{}))}}))),children:e})}
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{createStore,useStore}from"zustand";import{immer}from"zustand/middleware/immer";import shallow from"zustand/shallow";import{createContext,useContext}from"react";import produce from"immer";import{createDashboardAppSlice}from"./DashboardAppSlice";import{createLayoutsSlice}from"./LayoutsSlice";export function usePanels(){return useDashboardStore((({panels:e,updatePanel:o})=>({panels:e,updatePanel:o})))}export function useEditMode(){return useDashboardStore((({isEditMode:e,setEditMode:o})=>({isEditMode:e,setEditMode:o})))}export function useDashboard(){return{dashboard:useDashboardStore((e=>produce(e.dashboard,(o=>{o.panels=e.panels,o.layouts=e.layouts}))))}}const DashboardContext=createContext(void 0);export function useDashboardStore(e){const o=useContext(DashboardContext);if(void 0===o)throw new Error("No DashboardContext found. Did you forget a Provider?");return useStore(o,e,shallow)}export function DashboardProvider(e){const{children:o,initialState:{dashboardSpec:t,isEditMode:r}}=e,{layouts:a,panels:s}=t,d=createStore()(immer(((e,o,d)=>({...createDashboardAppSlice(e,o,d,[]),...createLayoutsSlice(e,o,d,[]),layouts:a,panels:s,dashboard:t,updatePanel:(o,t,r=0)=>e((e=>{var a,s;if(void 0===e.panels[o]){let t=0;null===(a=e.layouts[r])||void 0===a||a.spec.items.forEach((e=>{e.y>t&&(t=e.y)}));const d={x:0,y:t+1,width:12,height:6,content:{$ref:`#/spec/panels/${o}`}},i=e.layouts;i&&i[r]&&(null===(s=i[r])||void 0===s||s.spec.items.push(d))}e.panels[o]=t})),isEditMode:!!r,setEditMode:o=>e({isEditMode:o})}))));return _jsx(DashboardContext.Provider,{value:d,children:o})}
@@ -0,0 +1,12 @@
1
+ import { LayoutDefinition, GridItemDefinition } from '@perses-dev/core';
2
+ export interface LayoutsSlice {
3
+ updateLayout: (layout: LayoutDefinition, index?: number) => void;
4
+ addItemToLayout: (index: number, item: GridItemDefinition) => void;
5
+ }
6
+ export declare const createLayoutsSlice: import("zustand").StateCreator<LayoutsSlice, [], [["zustand/immer", never]], LayoutsSlice>;
7
+ export declare function useLayouts(): {
8
+ layouts: import("@perses-dev/core").GridDefinition[];
9
+ updateLayout: (layout: import("@perses-dev/core").GridDefinition, index?: number | undefined) => void;
10
+ addItemToLayout: (index: number, item: GridItemDefinition) => void;
11
+ };
12
+ //# sourceMappingURL=LayoutsSlice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayoutsSlice.d.ts","sourceRoot":"","sources":["../../src/context/LayoutsSlice.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAIxE,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACjE,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACpE;AAED,eAAO,MAAM,kBAAkB,4FAgB5B,CAAC;AAEJ,wBAAgB,UAAU;;;;EAMzB"}
@@ -0,0 +1 @@
1
+ import{immer}from"zustand/middleware/immer";import{useDashboardStore}from"./DashboardProvider";export const createLayoutsSlice=immer((o=>({updateLayout:(t,a)=>o((o=>{void 0===a?o.layouts.unshift(t):o.layouts[a]=t})),addItemToLayout:(t,a)=>o((o=>{var e;const u=o.layouts;u&&u[t]&&(null===(e=u[t])||void 0===e||e.spec.items.push(a))}))})));export function useLayouts(){return useDashboardStore((({layouts:o,updateLayout:t,addItemToLayout:a})=>({layouts:o,updateLayout:t,addItemToLayout:a})))}
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { QueryString } from '@perses-dev/plugin-system';
3
+ export interface QueryStringProviderProps {
4
+ queryString: URLSearchParams;
5
+ setQueryString?: (queryString: URLSearchParams) => void;
6
+ children?: React.ReactNode;
7
+ }
8
+ /**
9
+ * Allows apps to provide their own query string implementations
10
+ */
11
+ export declare function QueryStringProvider(props: QueryStringProviderProps): JSX.Element;
12
+ export declare function useQueryString(): QueryString;
13
+ //# sourceMappingURL=QueryStringProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryStringProvider.d.ts","sourceRoot":"","sources":["../../src/context/QueryStringProvider.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA8B,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,WAAW,EAAsB,MAAM,2BAA2B,CAAC;AAE5E,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,eAAe,CAAC;IAC7B,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,eAAe,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,eAMlE;AAED,wBAAgB,cAAc,IAAI,WAAW,CAM5C"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{useContext,useMemo}from"react";import{QueryStringContext}from"@perses-dev/plugin-system";export function QueryStringProvider(r){const{queryString:e,setQueryString:t,children:n}=r,o=useMemo((()=>({queryString:e,setQueryString:t})),[e,t]);return _jsx(QueryStringContext.Provider,{value:o,children:n})}export function useQueryString(){const r=useContext(QueryStringContext);if(void 0===r)throw new Error("No QueryStringContext found. Did you forget a Provider?");return r}
@@ -0,0 +1,25 @@
1
+ /// <reference types="react" />
2
+ import { VariableStateMap, VariableState, VariableName, VariableValue, VariableDefinition } from '@perses-dev/core';
3
+ declare type TemplateVariableStore = {
4
+ variableDefinitions: VariableDefinition[];
5
+ variableState: VariableStateMap;
6
+ setVariableValue: (variableName: VariableName, value: VariableValue) => void;
7
+ loadTemplateVariable: (name: VariableName) => Promise<void>;
8
+ };
9
+ export declare function useTemplateVariableValues(variableNames?: string[]): VariableStateMap;
10
+ export declare function useTemplateVariable(name: string): {
11
+ state: VariableState | undefined;
12
+ definition: VariableDefinition | undefined;
13
+ };
14
+ export declare function useTemplateVariableActions(): {
15
+ setVariableValue: (variableName: string, value: VariableValue) => void;
16
+ loadTemplateVariable: (name: string) => Promise<void>;
17
+ };
18
+ export declare function useTemplateVariableDefinitions(): VariableDefinition[];
19
+ export declare function useTemplateVariableStore(): TemplateVariableStore;
20
+ export declare function TemplateVariableProvider({ children, initialVariableDefinitions, }: {
21
+ children: React.ReactNode;
22
+ initialVariableDefinitions?: VariableDefinition[];
23
+ }): JSX.Element;
24
+ export {};
25
+ //# sourceMappingURL=TemplateVariableProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateVariableProvider.d.ts","sourceRoot":"","sources":["../../src/context/TemplateVariableProvider.tsx"],"names":[],"mappings":";AAkBA,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,aAAa,EAEb,kBAAkB,EAEnB,MAAM,kBAAkB,CAAC;AAE1B,aAAK,qBAAqB,GAAG;IAC3B,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,aAAa,EAAE,gBAAgB,CAAC;IAChC,gBAAgB,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7E,oBAAoB,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D,CAAC;AAaF,wBAAgB,yBAAyB,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,oBAqBjE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM;;;EAU/C;AAED,wBAAgB,0BAA0B;;;EAQzC;AAED,wBAAgB,8BAA8B,yBAG7C;AAED,wBAAgB,wBAAwB,0BAGvC;AA0ED,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,0BAA+B,GAChC,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,0BAA0B,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACnD,eAQA"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{createContext,useContext}from"react";import{createStore,useStore}from"zustand";import{immer}from"zustand/middleware/immer";import{devtools}from"zustand/middleware";import{TemplateVariableContext}from"@perses-dev/plugin-system";import{DEFAULT_ALL_VALUE as ALL_VALUE}from"@perses-dev/core";const TemplateVariableStoreContext=createContext(void 0);function useTemplateVariableStoreCtx(){const e=useContext(TemplateVariableStoreContext);if(!e)throw new Error("TemplateVariableStoreContext not initialized");return e}export function useTemplateVariableValues(e){const t=useTemplateVariableStoreCtx();return useStore(t,(t=>{const a=null!=e?e:Object.keys(t.variableState),r={};return a.forEach((e=>{const a=t.variableState[e];a&&(r[e]=a)})),r}),((e,t)=>JSON.stringify(e)===JSON.stringify(t)))}export function useTemplateVariable(e){const t=useTemplateVariableStoreCtx();return useStore(t,(t=>({state:t.variableState[e],definition:t.variableDefinitions.find((t=>t.name===e))})))}export function useTemplateVariableActions(){const e=useTemplateVariableStoreCtx();return useStore(e,(e=>({setVariableValue:e.setVariableValue,loadTemplateVariable:e.loadTemplateVariable})))}export function useTemplateVariableDefinitions(){const e=useTemplateVariableStoreCtx();return useStore(e,(e=>e.variableDefinitions))}export function useTemplateVariableStore(){const e=useTemplateVariableStoreCtx();return useStore(e)}function PluginProvider({children:e}){const t=useTemplateVariableValues();return _jsx(TemplateVariableContext.Provider,{value:{state:t},children:e})}function createTemplateVariableSrvStore({initialVariableDefinitions:e=[]}){return createStore()(devtools(immer(((t,a)=>({variableState:hydrateTemplateVariableStates(e),variableDefinitions:e,loadTemplateVariable:async e=>{const r=a().variableDefinitions.find((t=>t.name===e));if(!r)return;t((t=>{const a=t.variableState[e];a&&(a.loading=!0)}));const{data:i}=await loadTemplateVariables();r.options.allowAllValue&&i.unshift(getAllOption()),t((t=>{const a=t.variableState[e];a&&(a.options=i,a.loading=!1)}))},setVariableValue:(e,a)=>t((t=>{let r=a;const i=t.variableState[e];i&&(Array.isArray(r)&&r.includes(ALL_VALUE)&&(r=r.at(-1)===ALL_VALUE?[ALL_VALUE]:r.filter((e=>e!==ALL_VALUE))),i.value=r)}))})))))}export function TemplateVariableProvider({children:e,initialVariableDefinitions:t=[]}){const a=createTemplateVariableSrvStore({initialVariableDefinitions:t});return _jsx(TemplateVariableStoreContext.Provider,{value:a,children:_jsx(PluginProvider,{children:e})})}async function loadTemplateVariables(){const e=Math.floor(1e4*Math.random())+1e3;return await new Promise((t=>setTimeout(t,e))),{data:["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"].map((e=>({label:e,value:e})))}}function getAllOption(){return{label:"All",value:ALL_VALUE}}function hydrateTemplateVariableState(e){var t,a;const r=e,i={value:null,loading:!1};switch(r.kind){case"TextVariable":i.value=r.options.value;break;case"ListVariable":if(i.options=[],r.options.allowAllValue&&i.options.unshift({label:"All",value:ALL_VALUE}),i.options.length>0&&!i.value){const e=null!==(a=null===(t=i.options[0])||void 0===t?void 0:t.value)&&void 0!==a?a:null;null!==e&&(i.value=r.options.allowMultiple?[e]:e)}}return i}function hydrateTemplateVariableStates(e){const t={};return e.forEach((e=>{t[e.name]=hydrateTemplateVariableState(e)})),t}
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { TimeRangeValue } from '@perses-dev/core';
3
+ export interface TimeRangeProviderProps {
4
+ initialTimeRange: TimeRangeValue;
5
+ children?: React.ReactNode;
6
+ onTimeRangeChange?: (e: TimeRangeValue) => void;
7
+ }
8
+ /**
9
+ * Provider implementation that supplies the time range state at runtime.
10
+ */
11
+ export declare function TimeRangeProvider(props: TimeRangeProviderProps): JSX.Element;
12
+ //# sourceMappingURL=TimeRangeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeRangeProvider.d.ts","sourceRoot":"","sources":["../../src/context/TimeRangeProvider.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D,OAAO,EAAE,cAAc,EAA+D,MAAM,kBAAkB,CAAC;AAG/G,MAAM,WAAW,sBAAsB;IACrC,gBAAgB,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;CACjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,eAkD9D"}
@@ -0,0 +1 @@
1
+ import{jsx as _jsx}from"react/jsx-runtime";import{useState,useMemo,useCallback}from"react";import{getUnixTime}from"date-fns";import{toAbsoluteTimeRange,isRelativeTimeRange}from"@perses-dev/core";import{TimeRangeContext,useQueryString}from"@perses-dev/plugin-system";export function TimeRangeProvider(e){const{initialTimeRange:t,children:i,onTimeRangeChange:n}=e,{queryString:s,setQueryString:r}=useQueryString(),a=isRelativeTimeRange(t)?toAbsoluteTimeRange(t):t,[o,m]=useState(a),g=useCallback((e=>{if(void 0===n)if(isRelativeTimeRange(e))r?(s.set("start",e.pastDuration),s.delete("end"),r(s)):m(toAbsoluteTimeRange(e));else if(r){const t=1e3*getUnixTime(e.start),i=1e3*getUnixTime(e.end);s.set("start",t.toString()),s.set("end",i.toString()),r(s)}else m(e);else n(e)}),[s,r,n]),u=useMemo((()=>({timeRange:o,setTimeRange:g})),[o,g]);return _jsx(TimeRangeContext.Provider,{value:u,children:i})}