@perses-dev/dashboards 0.22.0 → 0.23.1

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 (126) hide show
  1. package/dist/cjs/components/DashboardToolbar/DashboardToolbar.js +3 -0
  2. package/dist/cjs/components/DeletePanelDialog/DeletePanelDialog.js +8 -30
  3. package/dist/cjs/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +1 -0
  4. package/dist/cjs/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.js +1 -0
  5. package/dist/cjs/components/GridLayout/GridItemContent.js +2 -1
  6. package/dist/cjs/components/GridLayout/GridLayout.js +4 -7
  7. package/dist/cjs/components/Panel/Panel.js +4 -5
  8. package/dist/cjs/components/Panel/Panel.test.js +10 -2
  9. package/dist/cjs/components/Panel/PanelContent.js +2 -1
  10. package/dist/cjs/components/Panel/PanelHeader.js +17 -0
  11. package/dist/cjs/components/PanelGroupDialog/PanelGroupDialog.js +1 -0
  12. package/dist/cjs/components/TimeRangeControls/TimeRangeControls.test.js +2 -2
  13. package/dist/cjs/components/Variables/EditVariablesButton.js +1 -0
  14. package/dist/cjs/components/Variables/VariableEditor.js +1 -1
  15. package/dist/cjs/components/Variables/VariableList.js +8 -2
  16. package/dist/cjs/{utils/functions.js → constants/grid-layout-config.js} +13 -5
  17. package/dist/cjs/constants/index.js +1 -0
  18. package/dist/cjs/constants/user-interface-text.js +2 -0
  19. package/dist/cjs/context/DashboardProvider/DashboardProvider.js +29 -9
  20. package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +6 -4
  21. package/dist/cjs/context/DashboardProvider/duplicate-panel-slice.js +62 -0
  22. package/dist/cjs/context/DashboardProvider/panel-editor-slice.js +8 -37
  23. package/dist/cjs/context/useDashboard.js +4 -2
  24. package/dist/cjs/utils/index.js +1 -1
  25. package/dist/cjs/utils/panelUtils.js +168 -0
  26. package/dist/cjs/utils/panelUtils.test.js +195 -0
  27. package/dist/cjs/views/ViewDashboard/DashboardApp.js +4 -1
  28. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +4 -2
  29. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
  30. package/dist/components/DashboardToolbar/DashboardToolbar.js +3 -0
  31. package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
  32. package/dist/components/DeletePanelDialog/DeletePanelDialog.d.ts.map +1 -1
  33. package/dist/components/DeletePanelDialog/DeletePanelDialog.js +7 -24
  34. package/dist/components/DeletePanelDialog/DeletePanelDialog.js.map +1 -1
  35. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +1 -0
  36. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
  37. package/dist/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.js +1 -0
  38. package/dist/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.js.map +1 -1
  39. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  40. package/dist/components/GridLayout/GridItemContent.js +2 -1
  41. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  42. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  43. package/dist/components/GridLayout/GridLayout.js +4 -7
  44. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  45. package/dist/components/Panel/Panel.d.ts.map +1 -1
  46. package/dist/components/Panel/Panel.js +5 -6
  47. package/dist/components/Panel/Panel.js.map +1 -1
  48. package/dist/components/Panel/Panel.test.js +10 -2
  49. package/dist/components/Panel/Panel.test.js.map +1 -1
  50. package/dist/components/Panel/PanelContent.d.ts.map +1 -1
  51. package/dist/components/Panel/PanelContent.js +2 -1
  52. package/dist/components/Panel/PanelContent.js.map +1 -1
  53. package/dist/components/Panel/PanelHeader.d.ts +1 -0
  54. package/dist/components/Panel/PanelHeader.d.ts.map +1 -1
  55. package/dist/components/Panel/PanelHeader.js +17 -0
  56. package/dist/components/Panel/PanelHeader.js.map +1 -1
  57. package/dist/components/PanelGroupDialog/PanelGroupDialog.js +1 -0
  58. package/dist/components/PanelGroupDialog/PanelGroupDialog.js.map +1 -1
  59. package/dist/components/TimeRangeControls/TimeRangeControls.test.js +2 -2
  60. package/dist/components/TimeRangeControls/TimeRangeControls.test.js.map +1 -1
  61. package/dist/components/Variables/EditVariablesButton.d.ts.map +1 -1
  62. package/dist/components/Variables/EditVariablesButton.js +1 -0
  63. package/dist/components/Variables/EditVariablesButton.js.map +1 -1
  64. package/dist/components/Variables/VariableEditor.js +1 -1
  65. package/dist/components/Variables/VariableEditor.js.map +1 -1
  66. package/dist/components/Variables/VariableList.d.ts.map +1 -1
  67. package/dist/components/Variables/VariableList.js +8 -2
  68. package/dist/components/Variables/VariableList.js.map +1 -1
  69. package/dist/constants/grid-layout-config.d.ts +6 -0
  70. package/dist/constants/grid-layout-config.d.ts.map +1 -0
  71. package/dist/{utils/functions.js → constants/grid-layout-config.js} +5 -3
  72. package/dist/constants/grid-layout-config.js.map +1 -0
  73. package/dist/constants/index.d.ts +1 -0
  74. package/dist/constants/index.d.ts.map +1 -1
  75. package/dist/constants/index.js +1 -0
  76. package/dist/constants/index.js.map +1 -1
  77. package/dist/constants/user-interface-text.d.ts +2 -0
  78. package/dist/constants/user-interface-text.d.ts.map +1 -1
  79. package/dist/constants/user-interface-text.js +2 -0
  80. package/dist/constants/user-interface-text.js.map +1 -1
  81. package/dist/context/DashboardProvider/DashboardProvider.d.ts +6 -4
  82. package/dist/context/DashboardProvider/DashboardProvider.d.ts.map +1 -1
  83. package/dist/context/DashboardProvider/DashboardProvider.js +29 -4
  84. package/dist/context/DashboardProvider/DashboardProvider.js.map +1 -1
  85. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +1 -0
  86. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  87. package/dist/context/DashboardProvider/dashboard-provider-api.js +6 -4
  88. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  89. package/dist/context/DashboardProvider/duplicate-panel-slice.d.ts +19 -0
  90. package/dist/context/DashboardProvider/duplicate-panel-slice.d.ts.map +1 -0
  91. package/dist/context/DashboardProvider/duplicate-panel-slice.js +58 -0
  92. package/dist/context/DashboardProvider/duplicate-panel-slice.js.map +1 -0
  93. package/dist/context/DashboardProvider/index.d.ts +1 -1
  94. package/dist/context/DashboardProvider/index.d.ts.map +1 -1
  95. package/dist/context/DashboardProvider/index.js.map +1 -1
  96. package/dist/context/DashboardProvider/panel-editor-slice.d.ts +4 -0
  97. package/dist/context/DashboardProvider/panel-editor-slice.d.ts.map +1 -1
  98. package/dist/context/DashboardProvider/panel-editor-slice.js +6 -35
  99. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  100. package/dist/context/useDashboard.d.ts.map +1 -1
  101. package/dist/context/useDashboard.js +4 -2
  102. package/dist/context/useDashboard.js.map +1 -1
  103. package/dist/utils/index.d.ts +1 -1
  104. package/dist/utils/index.d.ts.map +1 -1
  105. package/dist/utils/index.js +1 -1
  106. package/dist/utils/index.js.map +1 -1
  107. package/dist/utils/panelUtils.d.ts +27 -0
  108. package/dist/utils/panelUtils.d.ts.map +1 -0
  109. package/dist/utils/panelUtils.js +174 -0
  110. package/dist/utils/panelUtils.js.map +1 -0
  111. package/dist/utils/panelUtils.test.d.ts +2 -0
  112. package/dist/utils/panelUtils.test.d.ts.map +1 -0
  113. package/dist/utils/panelUtils.test.js +193 -0
  114. package/dist/utils/panelUtils.test.js.map +1 -0
  115. package/dist/views/ViewDashboard/DashboardApp.d.ts +1 -0
  116. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  117. package/dist/views/ViewDashboard/DashboardApp.js +4 -1
  118. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  119. package/dist/views/ViewDashboard/ViewDashboard.d.ts +2 -0
  120. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  121. package/dist/views/ViewDashboard/ViewDashboard.js +4 -2
  122. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  123. package/package.json +5 -5
  124. package/dist/utils/functions.d.ts +0 -2
  125. package/dist/utils/functions.d.ts.map +0 -1
  126. package/dist/utils/functions.js.map +0 -1
@@ -11,27 +11,17 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
- import { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';
15
- import CloseIcon from 'mdi-material-ui/Close';
14
+ import { Dialog } from '@perses-dev/components';
16
15
  import { useDeletePanelDialog } from '../../context';
17
16
  export const DeletePanelDialog = ()=>{
18
17
  const { deletePanelDialog , closeDeletePanelDialog } = useDeletePanelDialog();
19
18
  return /*#__PURE__*/ _jsxs(Dialog, {
20
19
  open: deletePanelDialog !== undefined,
21
20
  children: [
22
- /*#__PURE__*/ _jsx(DialogTitle, {
21
+ /*#__PURE__*/ _jsx(Dialog.Header, {
22
+ onClose: ()=>closeDeletePanelDialog(),
23
23
  children: "Delete Panel"
24
24
  }),
25
- /*#__PURE__*/ _jsx(IconButton, {
26
- "aria-label": "Close",
27
- onClick: ()=>closeDeletePanelDialog(),
28
- sx: (theme)=>({
29
- position: 'absolute',
30
- top: theme.spacing(0.5),
31
- right: theme.spacing(0.5)
32
- }),
33
- children: /*#__PURE__*/ _jsx(CloseIcon, {})
34
- }),
35
25
  deletePanelDialog && /*#__PURE__*/ _jsx(DeletePanelForm, {
36
26
  deletePanelDialog: deletePanelDialog
37
27
  })
@@ -49,11 +39,7 @@ const DeletePanelForm = ({ deletePanelDialog })=>{
49
39
  return /*#__PURE__*/ _jsxs("form", {
50
40
  onSubmit: handleDelete,
51
41
  children: [
52
- /*#__PURE__*/ _jsxs(DialogContent, {
53
- dividers: true,
54
- sx: {
55
- width: '500px'
56
- },
42
+ /*#__PURE__*/ _jsxs(Dialog.Content, {
57
43
  children: [
58
44
  "Are you sure you want to delete ",
59
45
  deletePanelDialog.panelName,
@@ -62,15 +48,12 @@ const DeletePanelForm = ({ deletePanelDialog })=>{
62
48
  "? This action cannot be undone."
63
49
  ]
64
50
  }),
65
- /*#__PURE__*/ _jsxs(DialogActions, {
51
+ /*#__PURE__*/ _jsxs(Dialog.Actions, {
66
52
  children: [
67
- /*#__PURE__*/ _jsx(Button, {
68
- variant: "contained",
69
- type: "submit",
53
+ /*#__PURE__*/ _jsx(Dialog.PrimaryButton, {
70
54
  children: "Delete"
71
55
  }),
72
- /*#__PURE__*/ _jsx(Button, {
73
- variant: "outlined",
56
+ /*#__PURE__*/ _jsx(Dialog.SecondaryButton, {
74
57
  onClick: ()=>closeDeletePanelDialog(),
75
58
  children: "Cancel"
76
59
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/DeletePanelDialog/DeletePanelDialog.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { FormEvent } from 'react';\nimport { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { useDeletePanelDialog, DeletePanelDialogState } from '../../context';\n\nexport const DeletePanelDialog = () => {\n const { deletePanelDialog, closeDeletePanelDialog } = useDeletePanelDialog();\n\n return (\n <Dialog open={deletePanelDialog !== undefined}>\n <DialogTitle>Delete Panel</DialogTitle>\n <IconButton\n aria-label=\"Close\"\n onClick={() => closeDeletePanelDialog()}\n sx={(theme) => ({\n position: 'absolute',\n top: theme.spacing(0.5),\n right: theme.spacing(0.5),\n })}\n >\n <CloseIcon />\n </IconButton>\n {deletePanelDialog && <DeletePanelForm deletePanelDialog={deletePanelDialog} />}\n </Dialog>\n );\n};\n\ninterface DeletePanelFormProps {\n deletePanelDialog: DeletePanelDialogState;\n}\n\nconst DeletePanelForm = ({ deletePanelDialog }: DeletePanelFormProps) => {\n const { deletePanel, closeDeletePanelDialog } = useDeletePanelDialog();\n\n const handleDelete = (e: FormEvent) => {\n e.preventDefault();\n const { panelGroupItemId } = deletePanelDialog;\n deletePanel(panelGroupItemId);\n closeDeletePanelDialog();\n };\n return (\n <form onSubmit={handleDelete}>\n <DialogContent dividers sx={{ width: '500px' }}>\n Are you sure you want to delete {deletePanelDialog.panelName} from {deletePanelDialog.panelGroupName}? This\n action cannot be undone.\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" type=\"submit\">\n Delete\n </Button>\n <Button variant=\"outlined\" onClick={() => closeDeletePanelDialog()}>\n Cancel\n </Button>\n </DialogActions>\n </form>\n );\n};\n"],"names":["IconButton","Dialog","DialogTitle","DialogContent","DialogActions","Button","CloseIcon","useDeletePanelDialog","DeletePanelDialog","deletePanelDialog","closeDeletePanelDialog","open","undefined","aria-label","onClick","sx","theme","position","top","spacing","right","DeletePanelForm","deletePanel","handleDelete","e","preventDefault","panelGroupItemId","form","onSubmit","dividers","width","panelName","panelGroupName","variant","type"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AACA,SAASA,UAAU,EAAEC,MAAM,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,MAAM,QAAQ,eAAe,CAAC;AACtG,OAAOC,SAAS,MAAM,uBAAuB,CAAC;AAC9C,SAASC,oBAAoB,QAAgC,eAAe,CAAC;AAE7E,OAAO,MAAMC,iBAAiB,GAAG,IAAM;IACrC,MAAM,EAAEC,iBAAiB,CAAA,EAAEC,sBAAsB,CAAA,EAAE,GAAGH,oBAAoB,EAAE,AAAC;IAE7E,qBACE,MAACN,MAAM;QAACU,IAAI,EAAEF,iBAAiB,KAAKG,SAAS;;0BAC3C,KAACV,WAAW;0BAAC,cAAY;cAAc;0BACvC,KAACF,UAAU;gBACTa,YAAU,EAAC,OAAO;gBAClBC,OAAO,EAAE,IAAMJ,sBAAsB,EAAE;gBACvCK,EAAE,EAAE,CAACC,KAAK,GAAM,CAAA;wBACdC,QAAQ,EAAE,UAAU;wBACpBC,GAAG,EAAEF,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;wBACvBC,KAAK,EAAEJ,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;qBAC1B,CAAA,AAAC;0BAEF,cAAA,KAACb,SAAS,KAAG;cACF;YACZG,iBAAiB,kBAAI,KAACY,eAAe;gBAACZ,iBAAiB,EAAEA,iBAAiB;cAAI;;MACxE,CACT;AACJ,CAAC,CAAC;AAMF,MAAMY,eAAe,GAAG,CAAC,EAAEZ,iBAAiB,CAAA,EAAwB,GAAK;IACvE,MAAM,EAAEa,WAAW,CAAA,EAAEZ,sBAAsB,CAAA,EAAE,GAAGH,oBAAoB,EAAE,AAAC;IAEvE,MAAMgB,YAAY,GAAG,CAACC,CAAY,GAAK;QACrCA,CAAC,CAACC,cAAc,EAAE,CAAC;QACnB,MAAM,EAAEC,gBAAgB,CAAA,EAAE,GAAGjB,iBAAiB,AAAC;QAC/Ca,WAAW,CAACI,gBAAgB,CAAC,CAAC;QAC9BhB,sBAAsB,EAAE,CAAC;IAC3B,CAAC,AAAC;IACF,qBACE,MAACiB,MAAI;QAACC,QAAQ,EAAEL,YAAY;;0BAC1B,MAACpB,aAAa;gBAAC0B,QAAQ;gBAACd,EAAE,EAAE;oBAAEe,KAAK,EAAE,OAAO;iBAAE;;oBAAE,kCACd;oBAACrB,iBAAiB,CAACsB,SAAS;oBAAC,QAAM;oBAACtB,iBAAiB,CAACuB,cAAc;oBAAC,iCAEvG;;cAAgB;0BAChB,MAAC5B,aAAa;;kCACZ,KAACC,MAAM;wBAAC4B,OAAO,EAAC,WAAW;wBAACC,IAAI,EAAC,QAAQ;kCAAC,QAE1C;sBAAS;kCACT,KAAC7B,MAAM;wBAAC4B,OAAO,EAAC,UAAU;wBAACnB,OAAO,EAAE,IAAMJ,sBAAsB,EAAE;kCAAE,QAEpE;sBAAS;;cACK;;MACX,CACP;AACJ,CAAC,AAAC"}
1
+ {"version":3,"sources":["../../../src/components/DeletePanelDialog/DeletePanelDialog.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { FormEvent } from 'react';\nimport { Dialog } from '@perses-dev/components';\nimport { useDeletePanelDialog, DeletePanelDialogState } from '../../context';\n\nexport const DeletePanelDialog = () => {\n const { deletePanelDialog, closeDeletePanelDialog } = useDeletePanelDialog();\n\n return (\n <Dialog open={deletePanelDialog !== undefined}>\n <Dialog.Header onClose={() => closeDeletePanelDialog()}>Delete Panel</Dialog.Header>\n {deletePanelDialog && <DeletePanelForm deletePanelDialog={deletePanelDialog} />}\n </Dialog>\n );\n};\n\ninterface DeletePanelFormProps {\n deletePanelDialog: DeletePanelDialogState;\n}\n\nconst DeletePanelForm = ({ deletePanelDialog }: DeletePanelFormProps) => {\n const { deletePanel, closeDeletePanelDialog } = useDeletePanelDialog();\n\n const handleDelete = (e: FormEvent) => {\n e.preventDefault();\n const { panelGroupItemId } = deletePanelDialog;\n deletePanel(panelGroupItemId);\n closeDeletePanelDialog();\n };\n return (\n <form onSubmit={handleDelete}>\n <Dialog.Content>\n Are you sure you want to delete {deletePanelDialog.panelName} from {deletePanelDialog.panelGroupName}? This\n action cannot be undone.\n </Dialog.Content>\n <Dialog.Actions>\n <Dialog.PrimaryButton>Delete</Dialog.PrimaryButton>\n <Dialog.SecondaryButton onClick={() => closeDeletePanelDialog()}>Cancel</Dialog.SecondaryButton>\n </Dialog.Actions>\n </form>\n );\n};\n"],"names":["Dialog","useDeletePanelDialog","DeletePanelDialog","deletePanelDialog","closeDeletePanelDialog","open","undefined","Header","onClose","DeletePanelForm","deletePanel","handleDelete","e","preventDefault","panelGroupItemId","form","onSubmit","Content","panelName","panelGroupName","Actions","PrimaryButton","SecondaryButton","onClick"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AACA,SAASA,MAAM,QAAQ,wBAAwB,CAAC;AAChD,SAASC,oBAAoB,QAAgC,eAAe,CAAC;AAE7E,OAAO,MAAMC,iBAAiB,GAAG,IAAM;IACrC,MAAM,EAAEC,iBAAiB,CAAA,EAAEC,sBAAsB,CAAA,EAAE,GAAGH,oBAAoB,EAAE,AAAC;IAE7E,qBACE,MAACD,MAAM;QAACK,IAAI,EAAEF,iBAAiB,KAAKG,SAAS;;0BAC3C,KAACN,MAAM,CAACO,MAAM;gBAACC,OAAO,EAAE,IAAMJ,sBAAsB,EAAE;0BAAE,cAAY;cAAgB;YACnFD,iBAAiB,kBAAI,KAACM,eAAe;gBAACN,iBAAiB,EAAEA,iBAAiB;cAAI;;MACxE,CACT;AACJ,CAAC,CAAC;AAMF,MAAMM,eAAe,GAAG,CAAC,EAAEN,iBAAiB,CAAA,EAAwB,GAAK;IACvE,MAAM,EAAEO,WAAW,CAAA,EAAEN,sBAAsB,CAAA,EAAE,GAAGH,oBAAoB,EAAE,AAAC;IAEvE,MAAMU,YAAY,GAAG,CAACC,CAAY,GAAK;QACrCA,CAAC,CAACC,cAAc,EAAE,CAAC;QACnB,MAAM,EAAEC,gBAAgB,CAAA,EAAE,GAAGX,iBAAiB,AAAC;QAC/CO,WAAW,CAACI,gBAAgB,CAAC,CAAC;QAC9BV,sBAAsB,EAAE,CAAC;IAC3B,CAAC,AAAC;IACF,qBACE,MAACW,MAAI;QAACC,QAAQ,EAAEL,YAAY;;0BAC1B,MAACX,MAAM,CAACiB,OAAO;;oBAAC,kCACkB;oBAACd,iBAAiB,CAACe,SAAS;oBAAC,QAAM;oBAACf,iBAAiB,CAACgB,cAAc;oBAAC,iCAEvG;;cAAiB;0BACjB,MAACnB,MAAM,CAACoB,OAAO;;kCACb,KAACpB,MAAM,CAACqB,aAAa;kCAAC,QAAM;sBAAuB;kCACnD,KAACrB,MAAM,CAACsB,eAAe;wBAACC,OAAO,EAAE,IAAMnB,sBAAsB,EAAE;kCAAE,QAAM;sBAAyB;;cACjF;;MACZ,CACP;AACJ,CAAC,AAAC"}
@@ -65,6 +65,7 @@ export const DeletePanelGroupDialog = ()=>{
65
65
  }),
66
66
  /*#__PURE__*/ _jsx(Button, {
67
67
  variant: "outlined",
68
+ color: "secondary",
68
69
  onClick: ()=>closeDeletePanelGroupDialog(),
69
70
  children: "Cancel"
70
71
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/DeletePanelGroupDialog/DeletePanelGroupDialog.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { FormEvent } from 'react';\nimport { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { useDeletePanelGroupDialog } from '../../context';\n\nexport const DeletePanelGroupDialog = () => {\n const { deletePanelGroupDialog, closeDeletePanelGroupDialog, deletePanelGroup } = useDeletePanelGroupDialog();\n\n const panelGroupId = deletePanelGroupDialog?.panelGroupId;\n\n const handleDelete = (e: FormEvent) => {\n e.preventDefault();\n if (panelGroupId == undefined) {\n throw new Error('group index is undefined');\n }\n deletePanelGroup(panelGroupId);\n closeDeletePanelGroupDialog();\n };\n\n return (\n <Dialog open={deletePanelGroupDialog !== undefined}>\n <DialogTitle>Delete Panel Group</DialogTitle>\n <IconButton\n aria-label=\"Close\"\n onClick={() => closeDeletePanelGroupDialog()}\n sx={(theme) => ({\n position: 'absolute',\n top: theme.spacing(0.5),\n right: theme.spacing(0.5),\n })}\n >\n <CloseIcon />\n </IconButton>\n <form onSubmit={handleDelete}>\n <DialogContent dividers sx={{ width: '500px' }}>\n Are you sure you want to delete {deletePanelGroupDialog?.panelGroupName ?? 'panel group'}? This will delete\n all the panels within the group.\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" type=\"submit\">\n Delete\n </Button>\n <Button variant=\"outlined\" onClick={() => closeDeletePanelGroupDialog()}>\n Cancel\n </Button>\n </DialogActions>\n </form>\n </Dialog>\n );\n};\n"],"names":["IconButton","Dialog","DialogTitle","DialogContent","DialogActions","Button","CloseIcon","useDeletePanelGroupDialog","DeletePanelGroupDialog","deletePanelGroupDialog","closeDeletePanelGroupDialog","deletePanelGroup","panelGroupId","handleDelete","e","preventDefault","undefined","Error","open","aria-label","onClick","sx","theme","position","top","spacing","right","form","onSubmit","dividers","width","panelGroupName","variant","type"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AACA,SAASA,UAAU,EAAEC,MAAM,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,MAAM,QAAQ,eAAe,CAAC;AACtG,OAAOC,SAAS,MAAM,uBAAuB,CAAC;AAC9C,SAASC,yBAAyB,QAAQ,eAAe,CAAC;AAE1D,OAAO,MAAMC,sBAAsB,GAAG,IAAM;IAC1C,MAAM,EAAEC,sBAAsB,CAAA,EAAEC,2BAA2B,CAAA,EAAEC,gBAAgB,CAAA,EAAE,GAAGJ,yBAAyB,EAAE,AAAC;IAE9G,MAAMK,YAAY,GAAGH,sBAAsB,aAAtBA,sBAAsB,WAAc,GAApCA,KAAAA,CAAoC,GAApCA,sBAAsB,CAAEG,YAAY,AAAC;IAE1D,MAAMC,YAAY,GAAG,CAACC,CAAY,GAAK;QACrCA,CAAC,CAACC,cAAc,EAAE,CAAC;QACnB,IAAIH,YAAY,IAAII,SAAS,EAAE;YAC7B,MAAM,IAAIC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACDN,gBAAgB,CAACC,YAAY,CAAC,CAAC;QAC/BF,2BAA2B,EAAE,CAAC;IAChC,CAAC,AAAC;QAkBuCD,GAAsC;IAhB/E,qBACE,MAACR,MAAM;QAACiB,IAAI,EAAET,sBAAsB,KAAKO,SAAS;;0BAChD,KAACd,WAAW;0BAAC,oBAAkB;cAAc;0BAC7C,KAACF,UAAU;gBACTmB,YAAU,EAAC,OAAO;gBAClBC,OAAO,EAAE,IAAMV,2BAA2B,EAAE;gBAC5CW,EAAE,EAAE,CAACC,KAAK,GAAM,CAAA;wBACdC,QAAQ,EAAE,UAAU;wBACpBC,GAAG,EAAEF,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;wBACvBC,KAAK,EAAEJ,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;qBAC1B,CAAA,AAAC;0BAEF,cAAA,KAACnB,SAAS,KAAG;cACF;0BACb,MAACqB,MAAI;gBAACC,QAAQ,EAAEf,YAAY;;kCAC1B,MAACV,aAAa;wBAAC0B,QAAQ;wBAACR,EAAE,EAAE;4BAAES,KAAK,EAAE,OAAO;yBAAE;;4BAAE,kCACd;4BAACrB,CAAAA,GAAsC,GAAtCA,sBAAsB,aAAtBA,sBAAsB,WAAgB,GAAtCA,KAAAA,CAAsC,GAAtCA,sBAAsB,CAAEsB,cAAc,cAAtCtB,GAAsC,cAAtCA,GAAsC,GAAI,aAAa;4BAAC,qDAE3F;;sBAAgB;kCAChB,MAACL,aAAa;;0CACZ,KAACC,MAAM;gCAAC2B,OAAO,EAAC,WAAW;gCAACC,IAAI,EAAC,QAAQ;0CAAC,QAE1C;8BAAS;0CACT,KAAC5B,MAAM;gCAAC2B,OAAO,EAAC,UAAU;gCAACZ,OAAO,EAAE,IAAMV,2BAA2B,EAAE;0CAAE,QAEzE;8BAAS;;sBACK;;cACX;;MACA,CACT;AACJ,CAAC,CAAC"}
1
+ {"version":3,"sources":["../../../src/components/DeletePanelGroupDialog/DeletePanelGroupDialog.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { FormEvent } from 'react';\nimport { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { useDeletePanelGroupDialog } from '../../context';\n\nexport const DeletePanelGroupDialog = () => {\n const { deletePanelGroupDialog, closeDeletePanelGroupDialog, deletePanelGroup } = useDeletePanelGroupDialog();\n\n const panelGroupId = deletePanelGroupDialog?.panelGroupId;\n\n const handleDelete = (e: FormEvent) => {\n e.preventDefault();\n if (panelGroupId == undefined) {\n throw new Error('group index is undefined');\n }\n deletePanelGroup(panelGroupId);\n closeDeletePanelGroupDialog();\n };\n\n return (\n <Dialog open={deletePanelGroupDialog !== undefined}>\n <DialogTitle>Delete Panel Group</DialogTitle>\n <IconButton\n aria-label=\"Close\"\n onClick={() => closeDeletePanelGroupDialog()}\n sx={(theme) => ({\n position: 'absolute',\n top: theme.spacing(0.5),\n right: theme.spacing(0.5),\n })}\n >\n <CloseIcon />\n </IconButton>\n <form onSubmit={handleDelete}>\n <DialogContent dividers sx={{ width: '500px' }}>\n Are you sure you want to delete {deletePanelGroupDialog?.panelGroupName ?? 'panel group'}? This will delete\n all the panels within the group.\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" type=\"submit\">\n Delete\n </Button>\n <Button variant=\"outlined\" color=\"secondary\" onClick={() => closeDeletePanelGroupDialog()}>\n Cancel\n </Button>\n </DialogActions>\n </form>\n </Dialog>\n );\n};\n"],"names":["IconButton","Dialog","DialogTitle","DialogContent","DialogActions","Button","CloseIcon","useDeletePanelGroupDialog","DeletePanelGroupDialog","deletePanelGroupDialog","closeDeletePanelGroupDialog","deletePanelGroup","panelGroupId","handleDelete","e","preventDefault","undefined","Error","open","aria-label","onClick","sx","theme","position","top","spacing","right","form","onSubmit","dividers","width","panelGroupName","variant","type","color"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AACA,SAASA,UAAU,EAAEC,MAAM,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,MAAM,QAAQ,eAAe,CAAC;AACtG,OAAOC,SAAS,MAAM,uBAAuB,CAAC;AAC9C,SAASC,yBAAyB,QAAQ,eAAe,CAAC;AAE1D,OAAO,MAAMC,sBAAsB,GAAG,IAAM;IAC1C,MAAM,EAAEC,sBAAsB,CAAA,EAAEC,2BAA2B,CAAA,EAAEC,gBAAgB,CAAA,EAAE,GAAGJ,yBAAyB,EAAE,AAAC;IAE9G,MAAMK,YAAY,GAAGH,sBAAsB,aAAtBA,sBAAsB,WAAc,GAApCA,KAAAA,CAAoC,GAApCA,sBAAsB,CAAEG,YAAY,AAAC;IAE1D,MAAMC,YAAY,GAAG,CAACC,CAAY,GAAK;QACrCA,CAAC,CAACC,cAAc,EAAE,CAAC;QACnB,IAAIH,YAAY,IAAII,SAAS,EAAE;YAC7B,MAAM,IAAIC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACDN,gBAAgB,CAACC,YAAY,CAAC,CAAC;QAC/BF,2BAA2B,EAAE,CAAC;IAChC,CAAC,AAAC;QAkBuCD,GAAsC;IAhB/E,qBACE,MAACR,MAAM;QAACiB,IAAI,EAAET,sBAAsB,KAAKO,SAAS;;0BAChD,KAACd,WAAW;0BAAC,oBAAkB;cAAc;0BAC7C,KAACF,UAAU;gBACTmB,YAAU,EAAC,OAAO;gBAClBC,OAAO,EAAE,IAAMV,2BAA2B,EAAE;gBAC5CW,EAAE,EAAE,CAACC,KAAK,GAAM,CAAA;wBACdC,QAAQ,EAAE,UAAU;wBACpBC,GAAG,EAAEF,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;wBACvBC,KAAK,EAAEJ,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;qBAC1B,CAAA,AAAC;0BAEF,cAAA,KAACnB,SAAS,KAAG;cACF;0BACb,MAACqB,MAAI;gBAACC,QAAQ,EAAEf,YAAY;;kCAC1B,MAACV,aAAa;wBAAC0B,QAAQ;wBAACR,EAAE,EAAE;4BAAES,KAAK,EAAE,OAAO;yBAAE;;4BAAE,kCACd;4BAACrB,CAAAA,GAAsC,GAAtCA,sBAAsB,aAAtBA,sBAAsB,WAAgB,GAAtCA,KAAAA,CAAsC,GAAtCA,sBAAsB,CAAEsB,cAAc,cAAtCtB,GAAsC,cAAtCA,GAAsC,GAAI,aAAa;4BAAC,qDAE3F;;sBAAgB;kCAChB,MAACL,aAAa;;0CACZ,KAACC,MAAM;gCAAC2B,OAAO,EAAC,WAAW;gCAACC,IAAI,EAAC,QAAQ;0CAAC,QAE1C;8BAAS;0CACT,KAAC5B,MAAM;gCAAC2B,OAAO,EAAC,UAAU;gCAACE,KAAK,EAAC,WAAW;gCAACd,OAAO,EAAE,IAAMV,2BAA2B,EAAE;0CAAE,QAE3F;8BAAS;;sBACK;;cACX;;MACA,CACT;AACJ,CAAC,CAAC"}
@@ -50,6 +50,7 @@ export const DiscardChangesConfirmationDialog = ()=>{
50
50
  }),
51
51
  /*#__PURE__*/ _jsx(Button, {
52
52
  variant: "outlined",
53
+ color: "secondary",
53
54
  onClick: dialog.onCancel,
54
55
  children: "Cancel"
55
56
  })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { useDiscardChangesConfirmationDialog } from '../../context';\n\nexport const DiscardChangesConfirmationDialog = () => {\n const { discardChangesConfirmationDialog: dialog } = useDiscardChangesConfirmationDialog();\n const isOpen = dialog !== undefined;\n\n return (\n <Dialog open={isOpen}>\n {dialog !== undefined && (\n <>\n <DialogTitle>Discard Changes</DialogTitle>\n <IconButton\n aria-label=\"Close\"\n onClick={dialog.onCancel}\n sx={(theme) => ({\n position: 'absolute',\n top: theme.spacing(0.5),\n right: theme.spacing(0.5),\n })}\n >\n <CloseIcon />\n </IconButton>\n <DialogContent dividers sx={{ width: '500px' }}>\n {dialog.description ||\n 'You have unsaved changes in this dashboard. Are you sure you want to discard these changes? Changes cannot be recovered.'}\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" onClick={dialog.onDiscardChanges}>\n Discard Changes\n </Button>\n <Button variant=\"outlined\" onClick={dialog.onCancel}>\n Cancel\n </Button>\n </DialogActions>\n </>\n )}\n </Dialog>\n );\n};\n"],"names":["IconButton","Dialog","DialogTitle","DialogContent","DialogActions","Button","CloseIcon","useDiscardChangesConfirmationDialog","DiscardChangesConfirmationDialog","discardChangesConfirmationDialog","dialog","isOpen","undefined","open","aria-label","onClick","onCancel","sx","theme","position","top","spacing","right","dividers","width","description","variant","onDiscardChanges"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AAAA,SAASA,UAAU,EAAEC,MAAM,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,MAAM,QAAQ,eAAe,CAAC;AACtG,OAAOC,SAAS,MAAM,uBAAuB,CAAC;AAC9C,SAASC,mCAAmC,QAAQ,eAAe,CAAC;AAEpE,OAAO,MAAMC,gCAAgC,GAAG,IAAM;IACpD,MAAM,EAAEC,gCAAgC,EAAEC,MAAM,CAAA,EAAE,GAAGH,mCAAmC,EAAE,AAAC;IAC3F,MAAMI,MAAM,GAAGD,MAAM,KAAKE,SAAS,AAAC;IAEpC,qBACE,KAACX,MAAM;QAACY,IAAI,EAAEF,MAAM;kBACjBD,MAAM,KAAKE,SAAS,kBACnB;;8BACE,KAACV,WAAW;8BAAC,iBAAe;kBAAc;8BAC1C,KAACF,UAAU;oBACTc,YAAU,EAAC,OAAO;oBAClBC,OAAO,EAAEL,MAAM,CAACM,QAAQ;oBACxBC,EAAE,EAAE,CAACC,KAAK,GAAM,CAAA;4BACdC,QAAQ,EAAE,UAAU;4BACpBC,GAAG,EAAEF,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;4BACvBC,KAAK,EAAEJ,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;yBAC1B,CAAA,AAAC;8BAEF,cAAA,KAACf,SAAS,KAAG;kBACF;8BACb,KAACH,aAAa;oBAACoB,QAAQ;oBAACN,EAAE,EAAE;wBAAEO,KAAK,EAAE,OAAO;qBAAE;8BAC3Cd,MAAM,CAACe,WAAW,IACjB,0HAA0H;kBAC9G;8BAChB,MAACrB,aAAa;;sCACZ,KAACC,MAAM;4BAACqB,OAAO,EAAC,WAAW;4BAACX,OAAO,EAAEL,MAAM,CAACiB,gBAAgB;sCAAE,iBAE9D;0BAAS;sCACT,KAACtB,MAAM;4BAACqB,OAAO,EAAC,UAAU;4BAACX,OAAO,EAAEL,MAAM,CAACM,QAAQ;sCAAE,QAErD;0BAAS;;kBACK;;UACf,AACJ;MACM,CACT;AACJ,CAAC,CAAC"}
1
+ {"version":3,"sources":["../../../src/components/DiscardChangesConfirmationDialog/DiscardChangesConfirmationDialog.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { IconButton, Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';\nimport CloseIcon from 'mdi-material-ui/Close';\nimport { useDiscardChangesConfirmationDialog } from '../../context';\n\nexport const DiscardChangesConfirmationDialog = () => {\n const { discardChangesConfirmationDialog: dialog } = useDiscardChangesConfirmationDialog();\n const isOpen = dialog !== undefined;\n\n return (\n <Dialog open={isOpen}>\n {dialog !== undefined && (\n <>\n <DialogTitle>Discard Changes</DialogTitle>\n <IconButton\n aria-label=\"Close\"\n onClick={dialog.onCancel}\n sx={(theme) => ({\n position: 'absolute',\n top: theme.spacing(0.5),\n right: theme.spacing(0.5),\n })}\n >\n <CloseIcon />\n </IconButton>\n <DialogContent dividers sx={{ width: '500px' }}>\n {dialog.description ||\n 'You have unsaved changes in this dashboard. Are you sure you want to discard these changes? Changes cannot be recovered.'}\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" onClick={dialog.onDiscardChanges}>\n Discard Changes\n </Button>\n <Button variant=\"outlined\" color=\"secondary\" onClick={dialog.onCancel}>\n Cancel\n </Button>\n </DialogActions>\n </>\n )}\n </Dialog>\n );\n};\n"],"names":["IconButton","Dialog","DialogTitle","DialogContent","DialogActions","Button","CloseIcon","useDiscardChangesConfirmationDialog","DiscardChangesConfirmationDialog","discardChangesConfirmationDialog","dialog","isOpen","undefined","open","aria-label","onClick","onCancel","sx","theme","position","top","spacing","right","dividers","width","description","variant","onDiscardChanges","color"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AAAA,SAASA,UAAU,EAAEC,MAAM,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,MAAM,QAAQ,eAAe,CAAC;AACtG,OAAOC,SAAS,MAAM,uBAAuB,CAAC;AAC9C,SAASC,mCAAmC,QAAQ,eAAe,CAAC;AAEpE,OAAO,MAAMC,gCAAgC,GAAG,IAAM;IACpD,MAAM,EAAEC,gCAAgC,EAAEC,MAAM,CAAA,EAAE,GAAGH,mCAAmC,EAAE,AAAC;IAC3F,MAAMI,MAAM,GAAGD,MAAM,KAAKE,SAAS,AAAC;IAEpC,qBACE,KAACX,MAAM;QAACY,IAAI,EAAEF,MAAM;kBACjBD,MAAM,KAAKE,SAAS,kBACnB;;8BACE,KAACV,WAAW;8BAAC,iBAAe;kBAAc;8BAC1C,KAACF,UAAU;oBACTc,YAAU,EAAC,OAAO;oBAClBC,OAAO,EAAEL,MAAM,CAACM,QAAQ;oBACxBC,EAAE,EAAE,CAACC,KAAK,GAAM,CAAA;4BACdC,QAAQ,EAAE,UAAU;4BACpBC,GAAG,EAAEF,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;4BACvBC,KAAK,EAAEJ,KAAK,CAACG,OAAO,CAAC,GAAG,CAAC;yBAC1B,CAAA,AAAC;8BAEF,cAAA,KAACf,SAAS,KAAG;kBACF;8BACb,KAACH,aAAa;oBAACoB,QAAQ;oBAACN,EAAE,EAAE;wBAAEO,KAAK,EAAE,OAAO;qBAAE;8BAC3Cd,MAAM,CAACe,WAAW,IACjB,0HAA0H;kBAC9G;8BAChB,MAACrB,aAAa;;sCACZ,KAACC,MAAM;4BAACqB,OAAO,EAAC,WAAW;4BAACX,OAAO,EAAEL,MAAM,CAACiB,gBAAgB;sCAAE,iBAE9D;0BAAS;sCACT,KAACtB,MAAM;4BAACqB,OAAO,EAAC,UAAU;4BAACE,KAAK,EAAC,WAAW;4BAACb,OAAO,EAAEL,MAAM,CAACM,QAAQ;sCAAE,QAEvE;0BAAS;;kBACK;;UACf,AACJ;MACM,CACT;AACJ,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"GridItemContent.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,gBAAgB,EAA0C,MAAM,eAAe,CAAC;AAGzF,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,eAgB1D"}
1
+ {"version":3,"file":"GridItemContent.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAE,gBAAgB,EAA0C,MAAM,eAAe,CAAC;AAGzF,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,eAiB1D"}
@@ -19,12 +19,13 @@ import { Panel } from '../Panel/Panel';
19
19
  const { panelGroupItemId } = props;
20
20
  const panelDefinition = usePanel(panelGroupItemId);
21
21
  const { isEditMode } = useEditMode();
22
- const { openEditPanel , openDeletePanelDialog } = usePanelActions(panelGroupItemId);
22
+ const { openEditPanel , openDeletePanelDialog , duplicatePanel } = usePanelActions(panelGroupItemId);
23
23
  // Provide actions to the panel when in edit mode
24
24
  let editHandlers = undefined;
25
25
  if (isEditMode) {
26
26
  editHandlers = {
27
27
  onEditPanelClick: openEditPanel,
28
+ onDuplicatePanelClick: duplicatePanel,
28
29
  onDeletePanelClick: openDeletePanelDialog
29
30
  };
30
31
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { PanelGroupItemId, useEditMode, usePanel, usePanelActions } from '../../context';\nimport { Panel, PanelProps } from '../Panel/Panel';\n\nexport interface GridItemContentProps {\n panelGroupItemId: PanelGroupItemId;\n}\n\n/**\n * Resolves the reference to panel content in a GridItemDefinition and renders the panel.\n */\nexport function GridItemContent(props: GridItemContentProps) {\n const { panelGroupItemId } = props;\n const panelDefinition = usePanel(panelGroupItemId);\n const { isEditMode } = useEditMode();\n const { openEditPanel, openDeletePanelDialog } = usePanelActions(panelGroupItemId);\n\n // Provide actions to the panel when in edit mode\n let editHandlers: PanelProps['editHandlers'] = undefined;\n if (isEditMode) {\n editHandlers = {\n onEditPanelClick: openEditPanel,\n onDeletePanelClick: openDeletePanelDialog,\n };\n }\n\n return <Panel definition={panelDefinition} editHandlers={editHandlers} />;\n}\n"],"names":["useEditMode","usePanel","usePanelActions","Panel","GridItemContent","props","panelGroupItemId","panelDefinition","isEditMode","openEditPanel","openDeletePanelDialog","editHandlers","undefined","onEditPanelClick","onDeletePanelClick","definition"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AAAA,SAA2BA,WAAW,EAAEC,QAAQ,EAAEC,eAAe,QAAQ,eAAe,CAAC;AACzF,SAASC,KAAK,QAAoB,gBAAgB,CAAC;AAMnD;;CAEC,GACD,OAAO,SAASC,eAAe,CAACC,KAA2B,EAAE;IAC3D,MAAM,EAAEC,gBAAgB,CAAA,EAAE,GAAGD,KAAK,AAAC;IACnC,MAAME,eAAe,GAAGN,QAAQ,CAACK,gBAAgB,CAAC,AAAC;IACnD,MAAM,EAAEE,UAAU,CAAA,EAAE,GAAGR,WAAW,EAAE,AAAC;IACrC,MAAM,EAAES,aAAa,CAAA,EAAEC,qBAAqB,CAAA,EAAE,GAAGR,eAAe,CAACI,gBAAgB,CAAC,AAAC;IAEnF,iDAAiD;IACjD,IAAIK,YAAY,GAA+BC,SAAS,AAAC;IACzD,IAAIJ,UAAU,EAAE;QACdG,YAAY,GAAG;YACbE,gBAAgB,EAAEJ,aAAa;YAC/BK,kBAAkB,EAAEJ,qBAAqB;SAC1C,CAAC;IACJ,CAAC;IAED,qBAAO,KAACP,KAAK;QAACY,UAAU,EAAER,eAAe;QAAEI,YAAY,EAAEA,YAAY;MAAI,CAAC;AAC5E,CAAC"}
1
+ {"version":3,"sources":["../../../src/components/GridLayout/GridItemContent.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { PanelGroupItemId, useEditMode, usePanel, usePanelActions } from '../../context';\nimport { Panel, PanelProps } from '../Panel/Panel';\n\nexport interface GridItemContentProps {\n panelGroupItemId: PanelGroupItemId;\n}\n\n/**\n * Resolves the reference to panel content in a GridItemDefinition and renders the panel.\n */\nexport function GridItemContent(props: GridItemContentProps) {\n const { panelGroupItemId } = props;\n const panelDefinition = usePanel(panelGroupItemId);\n const { isEditMode } = useEditMode();\n const { openEditPanel, openDeletePanelDialog, duplicatePanel } = usePanelActions(panelGroupItemId);\n\n // Provide actions to the panel when in edit mode\n let editHandlers: PanelProps['editHandlers'] = undefined;\n if (isEditMode) {\n editHandlers = {\n onEditPanelClick: openEditPanel,\n onDuplicatePanelClick: duplicatePanel,\n onDeletePanelClick: openDeletePanelDialog,\n };\n }\n\n return <Panel definition={panelDefinition} editHandlers={editHandlers} />;\n}\n"],"names":["useEditMode","usePanel","usePanelActions","Panel","GridItemContent","props","panelGroupItemId","panelDefinition","isEditMode","openEditPanel","openDeletePanelDialog","duplicatePanel","editHandlers","undefined","onEditPanelClick","onDuplicatePanelClick","onDeletePanelClick","definition"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AAAA,SAA2BA,WAAW,EAAEC,QAAQ,EAAEC,eAAe,QAAQ,eAAe,CAAC;AACzF,SAASC,KAAK,QAAoB,gBAAgB,CAAC;AAMnD;;CAEC,GACD,OAAO,SAASC,eAAe,CAACC,KAA2B,EAAE;IAC3D,MAAM,EAAEC,gBAAgB,CAAA,EAAE,GAAGD,KAAK,AAAC;IACnC,MAAME,eAAe,GAAGN,QAAQ,CAACK,gBAAgB,CAAC,AAAC;IACnD,MAAM,EAAEE,UAAU,CAAA,EAAE,GAAGR,WAAW,EAAE,AAAC;IACrC,MAAM,EAAES,aAAa,CAAA,EAAEC,qBAAqB,CAAA,EAAEC,cAAc,CAAA,EAAE,GAAGT,eAAe,CAACI,gBAAgB,CAAC,AAAC;IAEnG,iDAAiD;IACjD,IAAIM,YAAY,GAA+BC,SAAS,AAAC;IACzD,IAAIL,UAAU,EAAE;QACdI,YAAY,GAAG;YACbE,gBAAgB,EAAEL,aAAa;YAC/BM,qBAAqB,EAAEJ,cAAc;YACrCK,kBAAkB,EAAEN,qBAAqB;SAC1C,CAAC;IACJ,CAAC;IAED,qBAAO,KAACP,KAAK;QAACc,UAAU,EAAEV,eAAe;QAAEK,YAAY,EAAEA,YAAY;MAAI,CAAC;AAC5E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"GridLayout.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridLayout.tsx"],"names":[],"mappings":";AAgBA,OAAO,EAAoD,YAAY,EAAE,MAAM,eAAe,CAAC;AAO/F,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAID;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,eA0DhD"}
1
+ {"version":3,"file":"GridLayout.d.ts","sourceRoot":"","sources":["../../../src/components/GridLayout/GridLayout.tsx"],"names":[],"mappings":";AAgBA,OAAO,EAAoD,YAAY,EAAE,MAAM,eAAe,CAAC;AAQ/F,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,eA0DhD"}
@@ -16,11 +16,11 @@ import { Responsive, WidthProvider } from 'react-grid-layout';
16
16
  import { Collapse, useTheme } from '@mui/material';
17
17
  import { ErrorAlert, ErrorBoundary } from '@perses-dev/components';
18
18
  import { useEditMode, usePanelGroup, usePanelGroupActions } from '../../context';
19
+ import { GRID_LAYOUT_COLS, GRID_LAYOUT_SMALL_BREAKPOINT } from '../../constants';
19
20
  import { GridTitle } from './GridTitle';
20
21
  import { GridItemContent } from './GridItemContent';
21
22
  import { GridContainer } from './GridContainer';
22
23
  const ResponsiveGridLayout = WidthProvider(Responsive);
23
- const SMALL_LAYOUT_BREAKPOINT = 'sm';
24
24
  /**
25
25
  * Layout component that arranges children in a Grid based on the definition.
26
26
  */ export function GridLayout(props) {
@@ -36,7 +36,7 @@ const SMALL_LAYOUT_BREAKPOINT = 'sm';
36
36
  // a bug in react-layout-grid where `currentLayout` does not adjust properly
37
37
  // when going to a smaller breakpoint and then back to a larger breakpoint.
38
38
  // https://github.com/react-grid-layout/react-grid-layout/issues/1663
39
- const smallLayout = allLayouts[SMALL_LAYOUT_BREAKPOINT];
39
+ const smallLayout = allLayouts[GRID_LAYOUT_SMALL_BREAKPOINT];
40
40
  if (smallLayout) {
41
41
  updatePanelGroupLayouts(smallLayout);
42
42
  }
@@ -62,10 +62,7 @@ const SMALL_LAYOUT_BREAKPOINT = 'sm';
62
62
  sm: theme.breakpoints.values.sm,
63
63
  xxs: 0
64
64
  },
65
- cols: {
66
- sm: 24,
67
- xxs: 2
68
- },
65
+ cols: GRID_LAYOUT_COLS,
69
66
  rowHeight: 30,
70
67
  draggableHandle: '.drag-handle',
71
68
  resizeHandles: [
@@ -78,7 +75,7 @@ const SMALL_LAYOUT_BREAKPOINT = 'sm';
78
75
  10
79
76
  ],
80
77
  layouts: {
81
- [SMALL_LAYOUT_BREAKPOINT]: groupDefinition.itemLayouts
78
+ [GRID_LAYOUT_SMALL_BREAKPOINT]: groupDefinition.itemLayouts
82
79
  },
83
80
  onLayoutChange: handleLayoutChange,
84
81
  children: groupDefinition.itemLayouts.map(({ i })=>/*#__PURE__*/ _jsx("div", {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/GridLayout/GridLayout.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { useState } from 'react';\nimport { Responsive, WidthProvider, Layouts, Layout } from 'react-grid-layout';\nimport { Collapse, useTheme } from '@mui/material';\nimport { ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { useEditMode, usePanelGroup, usePanelGroupActions, PanelGroupId } from '../../context';\nimport { GridTitle } from './GridTitle';\nimport { GridItemContent } from './GridItemContent';\nimport { GridContainer } from './GridContainer';\n\nconst ResponsiveGridLayout = WidthProvider(Responsive);\n\nexport interface GridLayoutProps {\n panelGroupId: PanelGroupId;\n}\n\nconst SMALL_LAYOUT_BREAKPOINT = 'sm' as const;\n\n/**\n * Layout component that arranges children in a Grid based on the definition.\n */\nexport function GridLayout(props: GridLayoutProps) {\n const { panelGroupId /*...others */ } = props;\n const theme = useTheme();\n const groupDefinition = usePanelGroup(panelGroupId);\n const { updatePanelGroupLayouts } = usePanelGroupActions(panelGroupId);\n\n const [isOpen, setIsOpen] = useState(!groupDefinition.isCollapsed ?? true);\n const { isEditMode } = useEditMode();\n\n const handleLayoutChange = (currentLayout: Layout[], allLayouts: Layouts) => {\n // Using the value from `allLayouts` instead of `currentLayout` because of\n // a bug in react-layout-grid where `currentLayout` does not adjust properly\n // when going to a smaller breakpoint and then back to a larger breakpoint.\n // https://github.com/react-grid-layout/react-grid-layout/issues/1663\n const smallLayout = allLayouts[SMALL_LAYOUT_BREAKPOINT];\n if (smallLayout) {\n updatePanelGroupLayouts(smallLayout);\n }\n };\n\n return (\n <GridContainer>\n {groupDefinition.title !== undefined && (\n <GridTitle\n panelGroupId={panelGroupId}\n title={groupDefinition.title}\n collapse={\n groupDefinition.isCollapsed === undefined\n ? undefined\n : { isOpen, onToggleOpen: () => setIsOpen((current) => !current) }\n }\n />\n )}\n <Collapse in={isOpen} unmountOnExit appear={false} data-testid=\"panel-group-content\">\n <ResponsiveGridLayout\n className=\"layout\"\n breakpoints={{ sm: theme.breakpoints.values.sm, xxs: 0 }}\n cols={{ sm: 24, xxs: 2 }}\n rowHeight={30}\n draggableHandle={'.drag-handle'}\n resizeHandles={['se']}\n isDraggable={isEditMode}\n isResizable={isEditMode}\n containerPadding={[0, 10]}\n layouts={{ [SMALL_LAYOUT_BREAKPOINT]: groupDefinition.itemLayouts }}\n onLayoutChange={handleLayoutChange}\n >\n {groupDefinition.itemLayouts.map(({ i }) => (\n <div key={i}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <GridItemContent panelGroupItemId={{ panelGroupId, panelGroupItemLayoutId: i }} />\n </ErrorBoundary>\n </div>\n ))}\n </ResponsiveGridLayout>\n </Collapse>\n </GridContainer>\n );\n}\n"],"names":["useState","Responsive","WidthProvider","Collapse","useTheme","ErrorAlert","ErrorBoundary","useEditMode","usePanelGroup","usePanelGroupActions","GridTitle","GridItemContent","GridContainer","ResponsiveGridLayout","SMALL_LAYOUT_BREAKPOINT","GridLayout","props","panelGroupId","theme","groupDefinition","updatePanelGroupLayouts","isOpen","setIsOpen","isCollapsed","isEditMode","handleLayoutChange","currentLayout","allLayouts","smallLayout","title","undefined","collapse","onToggleOpen","current","in","unmountOnExit","appear","data-testid","className","breakpoints","sm","values","xxs","cols","rowHeight","draggableHandle","resizeHandles","isDraggable","isResizable","containerPadding","layouts","itemLayouts","onLayoutChange","map","i","div","FallbackComponent","panelGroupItemId","panelGroupItemLayoutId"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/GridLayout/GridLayout.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { useState } from 'react';\nimport { Responsive, WidthProvider, Layouts, Layout } from 'react-grid-layout';\nimport { Collapse, useTheme } from '@mui/material';\nimport { ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport { useEditMode, usePanelGroup, usePanelGroupActions, PanelGroupId } from '../../context';\nimport { GRID_LAYOUT_COLS, GRID_LAYOUT_SMALL_BREAKPOINT } from '../../constants';\nimport { GridTitle } from './GridTitle';\nimport { GridItemContent } from './GridItemContent';\nimport { GridContainer } from './GridContainer';\n\nconst ResponsiveGridLayout = WidthProvider(Responsive);\n\nexport interface GridLayoutProps {\n panelGroupId: PanelGroupId;\n}\n\n/**\n * Layout component that arranges children in a Grid based on the definition.\n */\nexport function GridLayout(props: GridLayoutProps) {\n const { panelGroupId /*...others */ } = props;\n const theme = useTheme();\n const groupDefinition = usePanelGroup(panelGroupId);\n const { updatePanelGroupLayouts } = usePanelGroupActions(panelGroupId);\n\n const [isOpen, setIsOpen] = useState(!groupDefinition.isCollapsed ?? true);\n const { isEditMode } = useEditMode();\n\n const handleLayoutChange = (currentLayout: Layout[], allLayouts: Layouts) => {\n // Using the value from `allLayouts` instead of `currentLayout` because of\n // a bug in react-layout-grid where `currentLayout` does not adjust properly\n // when going to a smaller breakpoint and then back to a larger breakpoint.\n // https://github.com/react-grid-layout/react-grid-layout/issues/1663\n const smallLayout = allLayouts[GRID_LAYOUT_SMALL_BREAKPOINT];\n if (smallLayout) {\n updatePanelGroupLayouts(smallLayout);\n }\n };\n\n return (\n <GridContainer>\n {groupDefinition.title !== undefined && (\n <GridTitle\n panelGroupId={panelGroupId}\n title={groupDefinition.title}\n collapse={\n groupDefinition.isCollapsed === undefined\n ? undefined\n : { isOpen, onToggleOpen: () => setIsOpen((current) => !current) }\n }\n />\n )}\n <Collapse in={isOpen} unmountOnExit appear={false} data-testid=\"panel-group-content\">\n <ResponsiveGridLayout\n className=\"layout\"\n breakpoints={{ sm: theme.breakpoints.values.sm, xxs: 0 }}\n cols={GRID_LAYOUT_COLS}\n rowHeight={30}\n draggableHandle={'.drag-handle'}\n resizeHandles={['se']}\n isDraggable={isEditMode}\n isResizable={isEditMode}\n containerPadding={[0, 10]}\n layouts={{ [GRID_LAYOUT_SMALL_BREAKPOINT]: groupDefinition.itemLayouts }}\n onLayoutChange={handleLayoutChange}\n >\n {groupDefinition.itemLayouts.map(({ i }) => (\n <div key={i}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <GridItemContent panelGroupItemId={{ panelGroupId, panelGroupItemLayoutId: i }} />\n </ErrorBoundary>\n </div>\n ))}\n </ResponsiveGridLayout>\n </Collapse>\n </GridContainer>\n );\n}\n"],"names":["useState","Responsive","WidthProvider","Collapse","useTheme","ErrorAlert","ErrorBoundary","useEditMode","usePanelGroup","usePanelGroupActions","GRID_LAYOUT_COLS","GRID_LAYOUT_SMALL_BREAKPOINT","GridTitle","GridItemContent","GridContainer","ResponsiveGridLayout","GridLayout","props","panelGroupId","theme","groupDefinition","updatePanelGroupLayouts","isOpen","setIsOpen","isCollapsed","isEditMode","handleLayoutChange","currentLayout","allLayouts","smallLayout","title","undefined","collapse","onToggleOpen","current","in","unmountOnExit","appear","data-testid","className","breakpoints","sm","values","xxs","cols","rowHeight","draggableHandle","resizeHandles","isDraggable","isResizable","containerPadding","layouts","itemLayouts","onLayoutChange","map","i","div","FallbackComponent","panelGroupItemId","panelGroupItemLayoutId"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/Panel.tsx"],"names":[],"mappings":";AAiBA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAQ,SAAS,EAAe,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAe,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAG9D,MAAM,WAAW,UAAW,SAAQ,SAAS,CAAC,SAAS,CAAC;IACtD,UAAU,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;CACjD;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,eA4FtC"}
1
+ {"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/Panel.tsx"],"names":[],"mappings":";AAiBA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAQ,SAAS,EAAe,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAe,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAG9D,MAAM,WAAW,UAAW,SAAQ,SAAS,CAAC,SAAS,CAAC;IACtD,UAAU,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;CACjD;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,eA2FtC"}
@@ -14,7 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import { useState, useMemo } from 'react';
15
15
  import useResizeObserver from 'use-resize-observer';
16
16
  import { useInView } from 'react-intersection-observer';
17
- import { ErrorBoundary, ErrorAlert, combineSx, useId } from '@perses-dev/components';
17
+ import { ErrorBoundary, ErrorAlert, combineSx, useId, useChartsTheme } from '@perses-dev/components';
18
18
  import { Card, CardContent } from '@mui/material';
19
19
  import { PanelHeader } from './PanelHeader';
20
20
  import { PanelContent } from './PanelContent';
@@ -45,8 +45,7 @@ import { PanelContent } from './PanelContent';
45
45
  initialInView: false,
46
46
  triggerOnce: true
47
47
  });
48
- // TODO: adjust padding for small panels, consistent way to determine isLargePanel here and in StatChart
49
- const panelPadding = 1.5;
48
+ const chartsTheme = useChartsTheme();
50
49
  const handleMouseEnter = (e)=>{
51
50
  setIsHovered(true);
52
51
  onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(e);
@@ -79,7 +78,7 @@ import { PanelContent } from './PanelContent';
79
78
  editHandlers: editHandlers,
80
79
  isHovered: isHovered,
81
80
  sx: {
82
- paddingX: (theme)=>theme.spacing(panelPadding)
81
+ paddingX: `${chartsTheme.container.padding.default}px`
83
82
  }
84
83
  }),
85
84
  /*#__PURE__*/ _jsx(CardContent, {
@@ -89,10 +88,10 @@ import { PanelContent } from './PanelContent';
89
88
  overflow: 'hidden',
90
89
  flexGrow: 1,
91
90
  margin: 0,
92
- padding: (theme)=>theme.spacing(panelPadding),
91
+ padding: 0,
93
92
  // Override MUI default style for last-child
94
93
  ':last-child': {
95
- padding: (theme)=>theme.spacing(panelPadding)
94
+ padding: 0
96
95
  }
97
96
  },
98
97
  ref: setContentElement,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/Panel.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useState, useMemo } from 'react';\nimport useResizeObserver from 'use-resize-observer';\nimport { useInView } from 'react-intersection-observer';\nimport { ErrorBoundary, ErrorAlert, combineSx, useId } from '@perses-dev/components';\nimport { PanelDefinition } from '@perses-dev/core';\nimport { Card, CardProps, CardContent } from '@mui/material';\nimport { PanelHeader, PanelHeaderProps } from './PanelHeader';\nimport { PanelContent } from './PanelContent';\n\nexport interface PanelProps extends CardProps<'section'> {\n definition: PanelDefinition;\n editHandlers?: PanelHeaderProps['editHandlers'];\n}\n\n/**\n * Renders a PanelDefinition's content inside of a Card.\n */\nexport function Panel(props: PanelProps) {\n const { definition, editHandlers, onMouseEnter, onMouseLeave, sx, ...others } = props;\n\n // Make sure we have an ID we can use for aria attributes\n const generatedPanelId = useId('Panel');\n const headerId = `${generatedPanelId}-header`;\n\n const [contentElement, setContentElement] = useState<HTMLElement | null>(null);\n const [isHovered, setIsHovered] = useState(false);\n\n const { width, height } = useResizeObserver({ ref: contentElement });\n\n const contentDimensions = useMemo(() => {\n if (width === undefined || height === undefined) return undefined;\n return { width, height };\n }, [width, height]);\n\n const { ref, inView } = useInView({\n threshold: 0.3,\n initialInView: false,\n triggerOnce: true,\n });\n\n // TODO: adjust padding for small panels, consistent way to determine isLargePanel here and in StatChart\n const panelPadding = 1.5;\n\n const handleMouseEnter: CardProps['onMouseEnter'] = (e) => {\n setIsHovered(true);\n onMouseEnter?.(e);\n };\n\n const handleMouseLeave: CardProps['onMouseLeave'] = (e) => {\n setIsHovered(false);\n onMouseLeave?.(e);\n };\n\n return (\n <Card\n ref={ref}\n component=\"section\"\n sx={combineSx(\n {\n width: '100%',\n height: '100%',\n display: 'flex',\n flexFlow: 'column nowrap',\n },\n sx\n )}\n variant=\"outlined\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n aria-labelledby={headerId}\n aria-describedby={headerId}\n data-testid=\"panel\"\n {...others}\n >\n <PanelHeader\n id={headerId}\n title={definition.spec.display.name}\n description={definition.spec.display.description}\n editHandlers={editHandlers}\n isHovered={isHovered}\n sx={{ paddingX: (theme) => theme.spacing(panelPadding) }}\n />\n <CardContent\n component=\"figure\"\n sx={{\n position: 'relative',\n overflow: 'hidden',\n flexGrow: 1,\n margin: 0,\n padding: (theme) => theme.spacing(panelPadding),\n // Override MUI default style for last-child\n ':last-child': {\n padding: (theme) => theme.spacing(panelPadding),\n },\n }}\n ref={setContentElement}\n >\n <ErrorBoundary FallbackComponent={ErrorAlert} resetKeys={[definition.spec.plugin.spec]}>\n {inView === true && (\n <PanelContent\n panelPluginKind={definition.spec.plugin.kind}\n spec={definition.spec.plugin.spec}\n contentDimensions={contentDimensions}\n />\n )}\n </ErrorBoundary>\n </CardContent>\n </Card>\n );\n}\n"],"names":["useState","useMemo","useResizeObserver","useInView","ErrorBoundary","ErrorAlert","combineSx","useId","Card","CardContent","PanelHeader","PanelContent","Panel","props","definition","editHandlers","onMouseEnter","onMouseLeave","sx","others","generatedPanelId","headerId","contentElement","setContentElement","isHovered","setIsHovered","width","height","ref","contentDimensions","undefined","inView","threshold","initialInView","triggerOnce","panelPadding","handleMouseEnter","e","handleMouseLeave","component","display","flexFlow","variant","aria-labelledby","aria-describedby","data-testid","id","title","spec","name","description","paddingX","theme","spacing","position","overflow","flexGrow","margin","padding","FallbackComponent","resetKeys","plugin","panelPluginKind","kind"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/Panel/Panel.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useState, useMemo } from 'react';\nimport useResizeObserver from 'use-resize-observer';\nimport { useInView } from 'react-intersection-observer';\nimport { ErrorBoundary, ErrorAlert, combineSx, useId, useChartsTheme } from '@perses-dev/components';\nimport { PanelDefinition } from '@perses-dev/core';\nimport { Card, CardProps, CardContent } from '@mui/material';\nimport { PanelHeader, PanelHeaderProps } from './PanelHeader';\nimport { PanelContent } from './PanelContent';\n\nexport interface PanelProps extends CardProps<'section'> {\n definition: PanelDefinition;\n editHandlers?: PanelHeaderProps['editHandlers'];\n}\n\n/**\n * Renders a PanelDefinition's content inside of a Card.\n */\nexport function Panel(props: PanelProps) {\n const { definition, editHandlers, onMouseEnter, onMouseLeave, sx, ...others } = props;\n\n // Make sure we have an ID we can use for aria attributes\n const generatedPanelId = useId('Panel');\n const headerId = `${generatedPanelId}-header`;\n\n const [contentElement, setContentElement] = useState<HTMLElement | null>(null);\n const [isHovered, setIsHovered] = useState(false);\n\n const { width, height } = useResizeObserver({ ref: contentElement });\n\n const contentDimensions = useMemo(() => {\n if (width === undefined || height === undefined) return undefined;\n return { width, height };\n }, [width, height]);\n\n const { ref, inView } = useInView({\n threshold: 0.3,\n initialInView: false,\n triggerOnce: true,\n });\n\n const chartsTheme = useChartsTheme();\n\n const handleMouseEnter: CardProps['onMouseEnter'] = (e) => {\n setIsHovered(true);\n onMouseEnter?.(e);\n };\n\n const handleMouseLeave: CardProps['onMouseLeave'] = (e) => {\n setIsHovered(false);\n onMouseLeave?.(e);\n };\n\n return (\n <Card\n ref={ref}\n component=\"section\"\n sx={combineSx(\n {\n width: '100%',\n height: '100%',\n display: 'flex',\n flexFlow: 'column nowrap',\n },\n sx\n )}\n variant=\"outlined\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n aria-labelledby={headerId}\n aria-describedby={headerId}\n data-testid=\"panel\"\n {...others}\n >\n <PanelHeader\n id={headerId}\n title={definition.spec.display.name}\n description={definition.spec.display.description}\n editHandlers={editHandlers}\n isHovered={isHovered}\n sx={{ paddingX: `${chartsTheme.container.padding.default}px` }}\n />\n <CardContent\n component=\"figure\"\n sx={{\n position: 'relative',\n overflow: 'hidden',\n flexGrow: 1,\n margin: 0,\n padding: 0,\n // Override MUI default style for last-child\n ':last-child': {\n padding: 0,\n },\n }}\n ref={setContentElement}\n >\n <ErrorBoundary FallbackComponent={ErrorAlert} resetKeys={[definition.spec.plugin.spec]}>\n {inView === true && (\n <PanelContent\n panelPluginKind={definition.spec.plugin.kind}\n spec={definition.spec.plugin.spec}\n contentDimensions={contentDimensions}\n />\n )}\n </ErrorBoundary>\n </CardContent>\n </Card>\n );\n}\n"],"names":["useState","useMemo","useResizeObserver","useInView","ErrorBoundary","ErrorAlert","combineSx","useId","useChartsTheme","Card","CardContent","PanelHeader","PanelContent","Panel","props","definition","editHandlers","onMouseEnter","onMouseLeave","sx","others","generatedPanelId","headerId","contentElement","setContentElement","isHovered","setIsHovered","width","height","ref","contentDimensions","undefined","inView","threshold","initialInView","triggerOnce","chartsTheme","handleMouseEnter","e","handleMouseLeave","component","display","flexFlow","variant","aria-labelledby","aria-describedby","data-testid","id","title","spec","name","description","paddingX","container","padding","default","position","overflow","flexGrow","margin","FallbackComponent","resetKeys","plugin","panelPluginKind","kind"],"mappings":"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"}
@@ -88,7 +88,8 @@ describe('Panel', ()=>{
88
88
  it('does not show description in edit mode', ()=>{
89
89
  renderPanel(undefined, {
90
90
  onEditPanelClick: jest.fn(),
91
- onDeletePanelClick: jest.fn()
91
+ onDeletePanelClick: jest.fn(),
92
+ onDuplicatePanelClick: jest.fn()
92
93
  });
93
94
  const panel = getPanel();
94
95
  userEvent.hover(panel);
@@ -100,9 +101,11 @@ describe('Panel', ()=>{
100
101
  it('can trigger panel actions in edit mode', ()=>{
101
102
  const onEditPanelClick = jest.fn();
102
103
  const onDeletePanelClick = jest.fn();
104
+ const onDuplicatePanelClick = jest.fn();
103
105
  renderPanel(undefined, {
104
106
  onEditPanelClick,
105
- onDeletePanelClick
107
+ onDeletePanelClick,
108
+ onDuplicatePanelClick
106
109
  });
107
110
  const panel = getPanel();
108
111
  userEvent.hover(panel);
@@ -114,8 +117,13 @@ describe('Panel', ()=>{
114
117
  name: /delete/i
115
118
  });
116
119
  userEvent.click(deleteButton);
120
+ const duplicateButton = screen.getByRole('button', {
121
+ name: /duplicate/i
122
+ });
123
+ userEvent.click(duplicateButton);
117
124
  expect(onEditPanelClick).toHaveBeenCalledTimes(1);
118
125
  expect(onDeletePanelClick).toHaveBeenCalledTimes(1);
126
+ expect(onDuplicatePanelClick).toHaveBeenCalledTimes(1);
119
127
  });
120
128
  });
121
129
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/Panel.test.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { screen, waitFor } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { PanelDefinition } from '@perses-dev/core';\nimport { renderWithContext } from '../../test';\nimport { Panel, PanelProps } from './Panel';\n\ndescribe('Panel', () => {\n const createTestPanel = (): PanelDefinition => ({\n kind: 'Panel',\n spec: {\n display: {\n name: 'Fake Panel Title',\n description: 'This is a fake panel',\n },\n plugin: {\n kind: 'TimeSeriesChart',\n spec: {},\n },\n },\n });\n\n // Helper to render the panel with some context set\n const renderPanel = (definition?: PanelDefinition, editHandlers?: PanelProps['editHandlers']) => {\n definition ??= createTestPanel();\n\n renderWithContext(<Panel definition={definition} editHandlers={editHandlers} />);\n };\n\n // Helper to get the panel once rendered\n const getPanel = () => screen.getByRole('region', { name: 'Fake Panel Title' });\n\n it('should render panel', async () => {\n renderPanel();\n\n const panel = getPanel();\n expect(panel).toBeInTheDocument();\n\n // Should diplay header with panel's title\n const header = screen.getByRole('banner');\n expect(header).toHaveTextContent('Fake Panel Title');\n\n // Should display chart's content from the fake panel plugin\n const content = screen.getByRole('figure');\n await waitFor(() => {\n expect(content).toHaveTextContent('TimeSeriesChart panel');\n });\n expect(content);\n });\n\n it('shows panel description', async () => {\n renderPanel();\n\n const panel = getPanel();\n\n // Description button should not be visible until hover on panel\n const missingButton = screen.queryByRole('button', { name: /description/i });\n expect(missingButton).not.toBeInTheDocument();\n userEvent.hover(panel);\n const descriptionButton = screen.getByRole('button', { name: /description/i });\n expect(descriptionButton).toBeInTheDocument();\n\n // Can hover to see panel description in tooltip\n userEvent.hover(descriptionButton);\n const tooltip = await screen.findByRole('tooltip');\n expect(tooltip).toHaveTextContent('This is a fake panel');\n });\n\n it('does not show description when panel does not have one', () => {\n // Render a panel without a description set\n const withoutDescription = createTestPanel();\n withoutDescription.spec.display.description = undefined;\n renderPanel(withoutDescription);\n\n const panel = getPanel();\n userEvent.hover(panel);\n const descriptionButton = screen.queryByRole('button', { name: /description/i });\n expect(descriptionButton).not.toBeInTheDocument();\n });\n\n it('does not show description in edit mode', () => {\n renderPanel(undefined, { onEditPanelClick: jest.fn(), onDeletePanelClick: jest.fn() });\n\n const panel = getPanel();\n userEvent.hover(panel);\n const descriptionButton = screen.queryByRole('button', { name: /description/i });\n expect(descriptionButton).not.toBeInTheDocument();\n });\n\n it('can trigger panel actions in edit mode', () => {\n const onEditPanelClick = jest.fn();\n const onDeletePanelClick = jest.fn();\n renderPanel(undefined, { onEditPanelClick, onDeletePanelClick });\n\n const panel = getPanel();\n userEvent.hover(panel);\n\n const editButton = screen.getByRole('button', { name: /edit/i });\n userEvent.click(editButton);\n\n const deleteButton = screen.getByRole('button', { name: /delete/i });\n userEvent.click(deleteButton);\n\n expect(onEditPanelClick).toHaveBeenCalledTimes(1);\n expect(onDeletePanelClick).toHaveBeenCalledTimes(1);\n });\n});\n"],"names":["screen","waitFor","userEvent","renderWithContext","Panel","describe","createTestPanel","kind","spec","display","name","description","plugin","renderPanel","definition","editHandlers","getPanel","getByRole","it","panel","expect","toBeInTheDocument","header","toHaveTextContent","content","missingButton","queryByRole","not","hover","descriptionButton","tooltip","findByRole","withoutDescription","undefined","onEditPanelClick","jest","fn","onDeletePanelClick","editButton","click","deleteButton","toHaveBeenCalledTimes"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/Panel/Panel.test.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { screen, waitFor } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { PanelDefinition } from '@perses-dev/core';\nimport { renderWithContext } from '../../test';\nimport { Panel, PanelProps } from './Panel';\n\ndescribe('Panel', () => {\n const createTestPanel = (): PanelDefinition => ({\n kind: 'Panel',\n spec: {\n display: {\n name: 'Fake Panel Title',\n description: 'This is a fake panel',\n },\n plugin: {\n kind: 'TimeSeriesChart',\n spec: {},\n },\n },\n });\n\n // Helper to render the panel with some context set\n const renderPanel = (definition?: PanelDefinition, editHandlers?: PanelProps['editHandlers']) => {\n definition ??= createTestPanel();\n\n renderWithContext(<Panel definition={definition} editHandlers={editHandlers} />);\n };\n\n // Helper to get the panel once rendered\n const getPanel = () => screen.getByRole('region', { name: 'Fake Panel Title' });\n\n it('should render panel', async () => {\n renderPanel();\n\n const panel = getPanel();\n expect(panel).toBeInTheDocument();\n\n // Should diplay header with panel's title\n const header = screen.getByRole('banner');\n expect(header).toHaveTextContent('Fake Panel Title');\n\n // Should display chart's content from the fake panel plugin\n const content = screen.getByRole('figure');\n await waitFor(() => {\n expect(content).toHaveTextContent('TimeSeriesChart panel');\n });\n expect(content);\n });\n\n it('shows panel description', async () => {\n renderPanel();\n\n const panel = getPanel();\n\n // Description button should not be visible until hover on panel\n const missingButton = screen.queryByRole('button', { name: /description/i });\n expect(missingButton).not.toBeInTheDocument();\n userEvent.hover(panel);\n const descriptionButton = screen.getByRole('button', { name: /description/i });\n expect(descriptionButton).toBeInTheDocument();\n\n // Can hover to see panel description in tooltip\n userEvent.hover(descriptionButton);\n const tooltip = await screen.findByRole('tooltip');\n expect(tooltip).toHaveTextContent('This is a fake panel');\n });\n\n it('does not show description when panel does not have one', () => {\n // Render a panel without a description set\n const withoutDescription = createTestPanel();\n withoutDescription.spec.display.description = undefined;\n renderPanel(withoutDescription);\n\n const panel = getPanel();\n userEvent.hover(panel);\n const descriptionButton = screen.queryByRole('button', { name: /description/i });\n expect(descriptionButton).not.toBeInTheDocument();\n });\n\n it('does not show description in edit mode', () => {\n renderPanel(undefined, {\n onEditPanelClick: jest.fn(),\n onDeletePanelClick: jest.fn(),\n onDuplicatePanelClick: jest.fn(),\n });\n\n const panel = getPanel();\n userEvent.hover(panel);\n const descriptionButton = screen.queryByRole('button', { name: /description/i });\n expect(descriptionButton).not.toBeInTheDocument();\n });\n\n it('can trigger panel actions in edit mode', () => {\n const onEditPanelClick = jest.fn();\n const onDeletePanelClick = jest.fn();\n const onDuplicatePanelClick = jest.fn();\n renderPanel(undefined, { onEditPanelClick, onDeletePanelClick, onDuplicatePanelClick });\n\n const panel = getPanel();\n userEvent.hover(panel);\n\n const editButton = screen.getByRole('button', { name: /edit/i });\n userEvent.click(editButton);\n\n const deleteButton = screen.getByRole('button', { name: /delete/i });\n userEvent.click(deleteButton);\n\n const duplicateButton = screen.getByRole('button', { name: /duplicate/i });\n userEvent.click(duplicateButton);\n\n expect(onEditPanelClick).toHaveBeenCalledTimes(1);\n expect(onDeletePanelClick).toHaveBeenCalledTimes(1);\n expect(onDuplicatePanelClick).toHaveBeenCalledTimes(1);\n });\n});\n"],"names":["screen","waitFor","userEvent","renderWithContext","Panel","describe","createTestPanel","kind","spec","display","name","description","plugin","renderPanel","definition","editHandlers","getPanel","getByRole","it","panel","expect","toBeInTheDocument","header","toHaveTextContent","content","missingButton","queryByRole","not","hover","descriptionButton","tooltip","findByRole","withoutDescription","undefined","onEditPanelClick","jest","fn","onDeletePanelClick","onDuplicatePanelClick","editButton","click","deleteButton","duplicateButton","toHaveBeenCalledTimes"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PanelContent.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelContent.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAa,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,WAAW,iBAAkB,SAAQ,UAAU,CAAC,WAAW,CAAC;IAChE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,eAcpD"}
1
+ {"version":3,"file":"PanelContent.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelContent.tsx"],"names":[],"mappings":";AAaA,OAAO,EAAa,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,WAAW,iBAAkB,SAAQ,UAAU,CAAC,WAAW,CAAC;IAChE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,eAqBpD"}
@@ -26,7 +26,8 @@ import { Skeleton } from '@mui/material';
26
26
  return /*#__PURE__*/ _jsx(Skeleton, {
27
27
  variant: "rectangular",
28
28
  width: contentDimensions === null || contentDimensions === void 0 ? void 0 : contentDimensions.width,
29
- height: contentDimensions === null || contentDimensions === void 0 ? void 0 : contentDimensions.height
29
+ height: contentDimensions === null || contentDimensions === void 0 ? void 0 : contentDimensions.height,
30
+ "aria-label": "Loading..."
30
31
  });
31
32
  }
32
33
  if (PanelComponent === undefined) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/PanelContent.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { usePlugin, PanelProps } from '@perses-dev/plugin-system';\nimport { Skeleton } from '@mui/material';\nimport { UnknownSpec } from '@perses-dev/core';\n\nexport interface PanelContentProps extends PanelProps<UnknownSpec> {\n panelPluginKind: string;\n}\n\n/**\n * A small wrapper component that renders the appropriate PanelComponent from a Panel plugin based on the panel\n * definition's kind. Used so that an ErrorBoundary can be wrapped around this.\n */\nexport function PanelContent(props: PanelContentProps) {\n const { panelPluginKind, contentDimensions, ...others } = props;\n const { data: plugin, isLoading } = usePlugin('Panel', panelPluginKind, { useErrorBoundary: true });\n const PanelComponent = plugin?.PanelComponent;\n\n if (isLoading) {\n return <Skeleton variant=\"rectangular\" width={contentDimensions?.width} height={contentDimensions?.height} />;\n }\n\n if (PanelComponent === undefined) {\n throw new Error(`Missing PanelComponent from panel plugin for kind '${panelPluginKind}'`);\n }\n\n return <PanelComponent {...others} contentDimensions={contentDimensions} />;\n}\n"],"names":["usePlugin","Skeleton","PanelContent","props","panelPluginKind","contentDimensions","others","data","plugin","isLoading","useErrorBoundary","PanelComponent","variant","width","height","undefined","Error"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AAAA,SAASA,SAAS,QAAoB,2BAA2B,CAAC;AAClE,SAASC,QAAQ,QAAQ,eAAe,CAAC;AAOzC;;;CAGC,GACD,OAAO,SAASC,YAAY,CAACC,KAAwB,EAAE;IACrD,MAAM,EAAEC,eAAe,CAAA,EAAEC,iBAAiB,CAAA,EAAE,GAAGC,MAAM,EAAE,GAAGH,KAAK,AAAC;IAChE,MAAM,EAAEI,IAAI,EAAEC,MAAM,CAAA,EAAEC,SAAS,CAAA,EAAE,GAAGT,SAAS,CAAC,OAAO,EAAEI,eAAe,EAAE;QAAEM,gBAAgB,EAAE,IAAI;KAAE,CAAC,AAAC;IACpG,MAAMC,cAAc,GAAGH,MAAM,aAANA,MAAM,WAAgB,GAAtBA,KAAAA,CAAsB,GAAtBA,MAAM,CAAEG,cAAc,AAAC;IAE9C,IAAIF,SAAS,EAAE;QACb,qBAAO,KAACR,QAAQ;YAACW,OAAO,EAAC,aAAa;YAACC,KAAK,EAAER,iBAAiB,aAAjBA,iBAAiB,WAAO,GAAxBA,KAAAA,CAAwB,GAAxBA,iBAAiB,CAAEQ,KAAK;YAAEC,MAAM,EAAET,iBAAiB,aAAjBA,iBAAiB,WAAQ,GAAzBA,KAAAA,CAAyB,GAAzBA,iBAAiB,CAAES,MAAM;UAAI,CAAC;IAChH,CAAC;IAED,IAAIH,cAAc,KAAKI,SAAS,EAAE;QAChC,MAAM,IAAIC,KAAK,CAAC,CAAC,mDAAmD,EAAEZ,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,qBAAO,KAACO,cAAc;QAAE,GAAGL,MAAM;QAAED,iBAAiB,EAAEA,iBAAiB;MAAI,CAAC;AAC9E,CAAC"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelContent.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { usePlugin, PanelProps } from '@perses-dev/plugin-system';\nimport { Skeleton } from '@mui/material';\nimport { UnknownSpec } from '@perses-dev/core';\n\nexport interface PanelContentProps extends PanelProps<UnknownSpec> {\n panelPluginKind: string;\n}\n\n/**\n * A small wrapper component that renders the appropriate PanelComponent from a Panel plugin based on the panel\n * definition's kind. Used so that an ErrorBoundary can be wrapped around this.\n */\nexport function PanelContent(props: PanelContentProps) {\n const { panelPluginKind, contentDimensions, ...others } = props;\n const { data: plugin, isLoading } = usePlugin('Panel', panelPluginKind, { useErrorBoundary: true });\n const PanelComponent = plugin?.PanelComponent;\n\n if (isLoading) {\n return (\n <Skeleton\n variant=\"rectangular\"\n width={contentDimensions?.width}\n height={contentDimensions?.height}\n aria-label=\"Loading...\"\n />\n );\n }\n\n if (PanelComponent === undefined) {\n throw new Error(`Missing PanelComponent from panel plugin for kind '${panelPluginKind}'`);\n }\n\n return <PanelComponent {...others} contentDimensions={contentDimensions} />;\n}\n"],"names":["usePlugin","Skeleton","PanelContent","props","panelPluginKind","contentDimensions","others","data","plugin","isLoading","useErrorBoundary","PanelComponent","variant","width","height","aria-label","undefined","Error"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC;AAAA,SAASA,SAAS,QAAoB,2BAA2B,CAAC;AAClE,SAASC,QAAQ,QAAQ,eAAe,CAAC;AAOzC;;;CAGC,GACD,OAAO,SAASC,YAAY,CAACC,KAAwB,EAAE;IACrD,MAAM,EAAEC,eAAe,CAAA,EAAEC,iBAAiB,CAAA,EAAE,GAAGC,MAAM,EAAE,GAAGH,KAAK,AAAC;IAChE,MAAM,EAAEI,IAAI,EAAEC,MAAM,CAAA,EAAEC,SAAS,CAAA,EAAE,GAAGT,SAAS,CAAC,OAAO,EAAEI,eAAe,EAAE;QAAEM,gBAAgB,EAAE,IAAI;KAAE,CAAC,AAAC;IACpG,MAAMC,cAAc,GAAGH,MAAM,aAANA,MAAM,WAAgB,GAAtBA,KAAAA,CAAsB,GAAtBA,MAAM,CAAEG,cAAc,AAAC;IAE9C,IAAIF,SAAS,EAAE;QACb,qBACE,KAACR,QAAQ;YACPW,OAAO,EAAC,aAAa;YACrBC,KAAK,EAAER,iBAAiB,aAAjBA,iBAAiB,WAAO,GAAxBA,KAAAA,CAAwB,GAAxBA,iBAAiB,CAAEQ,KAAK;YAC/BC,MAAM,EAAET,iBAAiB,aAAjBA,iBAAiB,WAAQ,GAAzBA,KAAAA,CAAyB,GAAzBA,iBAAiB,CAAES,MAAM;YACjCC,YAAU,EAAC,YAAY;UACvB,CACF;IACJ,CAAC;IAED,IAAIJ,cAAc,KAAKK,SAAS,EAAE;QAChC,MAAM,IAAIC,KAAK,CAAC,CAAC,mDAAmD,EAAEb,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,qBAAO,KAACO,cAAc;QAAE,GAAGL,MAAM;QAAED,iBAAiB,EAAEA,iBAAiB;MAAI,CAAC;AAC9E,CAAC"}
@@ -7,6 +7,7 @@ export interface PanelHeaderProps extends Omit<CardHeaderProps, OmittedProps> {
7
7
  description?: string;
8
8
  editHandlers?: {
9
9
  onEditPanelClick: () => void;
10
+ onDuplicatePanelClick: () => void;
10
11
  onDeletePanelClick: () => void;
11
12
  };
12
13
  isHovered: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"PanelHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelHeader.tsx"],"names":[],"mappings":";AAaA,OAAO,EAA6C,eAAe,EAAU,MAAM,eAAe,CAAC;AAQnG,aAAK,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,mBAAmB,CAAC;AAE1E,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE;QACb,gBAAgB,EAAE,MAAM,IAAI,CAAC;QAC7B,kBAAkB,EAAE,MAAM,IAAI,CAAC;KAChC,CAAC;IACF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,eAmG7G"}
1
+ {"version":3,"file":"PanelHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelHeader.tsx"],"names":[],"mappings":";AAaA,OAAO,EAA6C,eAAe,EAAU,MAAM,eAAe,CAAC;AASnG,aAAK,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,mBAAmB,CAAC;AAE1E,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE;QACb,gBAAgB,EAAE,MAAM,IAAI,CAAC;QAC7B,qBAAqB,EAAE,MAAM,IAAI,CAAC;QAClC,kBAAkB,EAAE,MAAM,IAAI,CAAC;KAChC,CAAC;IACF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,gBAAgB,eAmH7G"}
@@ -17,6 +17,7 @@ import InformationOutlineIcon from 'mdi-material-ui/InformationOutline';
17
17
  import PencilIcon from 'mdi-material-ui/PencilOutline';
18
18
  import DeleteIcon from 'mdi-material-ui/DeleteOutline';
19
19
  import DragIcon from 'mdi-material-ui/DragVertical';
20
+ import ContentCopy from 'mdi-material-ui/ContentCopy';
20
21
  import { ARIA_LABEL_TEXT, TOOLTIP_TEXT } from '../../constants';
21
22
  export function PanelHeader({ id , title , description , editHandlers , isHovered , sx , ...rest }) {
22
23
  const titleElementId = `${id}-title`;
@@ -37,6 +38,22 @@ export function PanelHeader({ id , title , description , editHandlers , isHovere
37
38
  })
38
39
  })
39
40
  }),
41
+ /*#__PURE__*/ _jsx(InfoTooltip, {
42
+ description: TOOLTIP_TEXT.duplicatePanel,
43
+ children: /*#__PURE__*/ _jsx(HeaderIconButton, {
44
+ "aria-label": ARIA_LABEL_TEXT.duplicatePanel(title),
45
+ size: "small",
46
+ onClick: editHandlers.onDuplicatePanelClick,
47
+ children: /*#__PURE__*/ _jsx(ContentCopy, {
48
+ fontSize: "inherit",
49
+ sx: {
50
+ // Shrink this icon a little bit to look more consistent
51
+ // with the other icons in the header.
52
+ transform: 'scale(0.925)'
53
+ }
54
+ })
55
+ })
56
+ }),
40
57
  /*#__PURE__*/ _jsx(InfoTooltip, {
41
58
  description: TOOLTIP_TEXT.deletePanel,
42
59
  children: /*#__PURE__*/ _jsx(HeaderIconButton, {