@perses-dev/dashboards 0.0.0-snapshot-explorer-plugin-c4a7621 → 0.0.0-snapshot-histogram-types-78c5104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/cjs/components/DashboardToolbar/DashboardToolbar.js +3 -3
  2. package/dist/cjs/components/DeletePanelDialog/DeletePanelDialog.js +2 -0
  3. package/dist/cjs/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +2 -0
  4. package/dist/cjs/components/DownloadButton/DownloadButton.js +135 -29
  5. package/dist/cjs/components/GridLayout/GridItemContent.js +3 -2
  6. package/dist/cjs/components/GridLayout/GridLayout.js +6 -10
  7. package/dist/cjs/components/Panel/Panel.js +6 -2
  8. package/dist/cjs/components/Panel/PanelActions.js +204 -55
  9. package/dist/cjs/components/Panel/PanelContent.js +56 -10
  10. package/dist/cjs/components/Panel/PanelHeader.js +10 -46
  11. package/dist/cjs/components/Panel/PanelPluginLoader.js +56 -0
  12. package/dist/cjs/components/Panel/index.js +1 -0
  13. package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +21 -9
  14. package/dist/cjs/components/Variables/Variable.js +10 -1
  15. package/dist/cjs/constants/styles.js +7 -3
  16. package/dist/cjs/constants/user-interface-text.js +1 -2
  17. package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +12 -1
  18. package/dist/cjs/context/VariableProvider/VariableProvider.js +16 -20
  19. package/dist/cjs/test/datasource-provider.js +1 -1
  20. package/dist/cjs/test/plugin-registry.js +4 -1
  21. package/dist/cjs/views/ViewDashboard/DashboardApp.js +3 -1
  22. package/dist/cjs/views/ViewDashboard/ViewDashboard.js +3 -1
  23. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts +2 -0
  24. package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
  25. package/dist/components/DashboardToolbar/DashboardToolbar.js +3 -3
  26. package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
  27. package/dist/components/Datasources/DatasourceEditor.js.map +1 -1
  28. package/dist/components/DeletePanelDialog/DeletePanelDialog.js +3 -1
  29. package/dist/components/DeletePanelDialog/DeletePanelDialog.js.map +1 -1
  30. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.d.ts.map +1 -1
  31. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +3 -1
  32. package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
  33. package/dist/components/DownloadButton/DownloadButton.d.ts +1 -5
  34. package/dist/components/DownloadButton/DownloadButton.d.ts.map +1 -1
  35. package/dist/components/DownloadButton/DownloadButton.js +94 -29
  36. package/dist/components/DownloadButton/DownloadButton.js.map +1 -1
  37. package/dist/components/GridLayout/GridContainer.js.map +1 -1
  38. package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
  39. package/dist/components/GridLayout/GridItemContent.js +4 -3
  40. package/dist/components/GridLayout/GridItemContent.js.map +1 -1
  41. package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
  42. package/dist/components/GridLayout/GridLayout.js +8 -12
  43. package/dist/components/GridLayout/GridLayout.js.map +1 -1
  44. package/dist/components/GridLayout/GridTitle.js.map +1 -1
  45. package/dist/components/Panel/HeaderIconButton.d.ts +1 -1
  46. package/dist/components/Panel/HeaderIconButton.d.ts.map +1 -1
  47. package/dist/components/Panel/Panel.d.ts +5 -0
  48. package/dist/components/Panel/Panel.d.ts.map +1 -1
  49. package/dist/components/Panel/Panel.js +11 -2
  50. package/dist/components/Panel/Panel.js.map +1 -1
  51. package/dist/components/Panel/PanelActions.d.ts +8 -2
  52. package/dist/components/Panel/PanelActions.d.ts.map +1 -1
  53. package/dist/components/Panel/PanelActions.js +208 -59
  54. package/dist/components/Panel/PanelActions.js.map +1 -1
  55. package/dist/components/Panel/PanelContent.d.ts +5 -4
  56. package/dist/components/Panel/PanelContent.d.ts.map +1 -1
  57. package/dist/components/Panel/PanelContent.js +58 -12
  58. package/dist/components/Panel/PanelContent.js.map +1 -1
  59. package/dist/components/Panel/PanelHeader.d.ts +3 -1
  60. package/dist/components/Panel/PanelHeader.d.ts.map +1 -1
  61. package/dist/components/Panel/PanelHeader.js +12 -43
  62. package/dist/components/Panel/PanelHeader.js.map +1 -1
  63. package/dist/components/Panel/PanelLinks.js.map +1 -1
  64. package/dist/components/Panel/PanelPluginLoader.d.ts +13 -0
  65. package/dist/components/Panel/PanelPluginLoader.d.ts.map +1 -0
  66. package/dist/components/Panel/PanelPluginLoader.js +51 -0
  67. package/dist/components/Panel/PanelPluginLoader.js.map +1 -0
  68. package/dist/components/Panel/index.d.ts +1 -0
  69. package/dist/components/Panel/index.d.ts.map +1 -1
  70. package/dist/components/Panel/index.js +1 -0
  71. package/dist/components/Panel/index.js.map +1 -1
  72. package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
  73. package/dist/components/PanelDrawer/PanelEditorForm.js +21 -9
  74. package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
  75. package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js.map +1 -1
  76. package/dist/components/SaveDashboardButton/SaveDashboardButton.js.map +1 -1
  77. package/dist/components/Variables/BuiltinVariableAccordions.js.map +1 -1
  78. package/dist/components/Variables/Variable.js +10 -1
  79. package/dist/components/Variables/Variable.js.map +1 -1
  80. package/dist/components/Variables/VariableEditor.js.map +1 -1
  81. package/dist/components/Variables/VariableList.js.map +1 -1
  82. package/dist/constants/styles.d.ts +2 -1
  83. package/dist/constants/styles.d.ts.map +1 -1
  84. package/dist/constants/styles.js +2 -1
  85. package/dist/constants/styles.js.map +1 -1
  86. package/dist/constants/user-interface-text.d.ts +0 -1
  87. package/dist/constants/user-interface-text.d.ts.map +1 -1
  88. package/dist/constants/user-interface-text.js +1 -2
  89. package/dist/constants/user-interface-text.js.map +1 -1
  90. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +11 -2
  91. package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
  92. package/dist/context/DashboardProvider/dashboard-provider-api.js +12 -2
  93. package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
  94. package/dist/context/DashboardProvider/delete-panel-slice.js.map +1 -1
  95. package/dist/context/DashboardProvider/duplicate-panel-slice.js.map +1 -1
  96. package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
  97. package/dist/context/DashboardProvider/panel-group-slice.d.ts +1 -1
  98. package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
  99. package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
  100. package/dist/context/DatasourceStoreProvider.js.map +1 -1
  101. package/dist/context/VariableProvider/VariableProvider.d.ts.map +1 -1
  102. package/dist/context/VariableProvider/VariableProvider.js +13 -12
  103. package/dist/context/VariableProvider/VariableProvider.js.map +1 -1
  104. package/dist/context/VariableProvider/query-params.js.map +1 -1
  105. package/dist/context/useDashboard.js.map +1 -1
  106. package/dist/test/datasource-provider.d.ts +1 -1
  107. package/dist/test/datasource-provider.d.ts.map +1 -1
  108. package/dist/test/datasource-provider.js +1 -1
  109. package/dist/test/datasource-provider.js.map +1 -1
  110. package/dist/test/plugin-registry.d.ts.map +1 -1
  111. package/dist/test/plugin-registry.js +4 -1
  112. package/dist/test/plugin-registry.js.map +1 -1
  113. package/dist/utils/panelUtils.js.map +1 -1
  114. package/dist/views/ViewDashboard/DashboardApp.d.ts +2 -0
  115. package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
  116. package/dist/views/ViewDashboard/DashboardApp.js +3 -1
  117. package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
  118. package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
  119. package/dist/views/ViewDashboard/ViewDashboard.js +3 -1
  120. package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
  121. package/package.json +9 -9
  122. package/dist/cjs/stories/decorators/WithDashboard.js +0 -41
  123. package/dist/cjs/stories/decorators/WithDatasourceStore.js +0 -39
  124. package/dist/cjs/stories/decorators/WithVariables.js +0 -37
  125. package/dist/cjs/stories/decorators/constants.js +0 -39
  126. package/dist/cjs/stories/decorators/index.js +0 -33
  127. package/dist/stories/decorators/WithDashboard.js +0 -33
  128. package/dist/stories/decorators/WithDashboard.js.map +0 -1
  129. package/dist/stories/decorators/WithDatasourceStore.js +0 -31
  130. package/dist/stories/decorators/WithDatasourceStore.js.map +0 -1
  131. package/dist/stories/decorators/WithVariables.js +0 -29
  132. package/dist/stories/decorators/WithVariables.js.map +0 -1
  133. package/dist/stories/decorators/constants.js +0 -31
  134. package/dist/stories/decorators/constants.js.map +0 -1
  135. package/dist/stories/decorators/index.js +0 -18
  136. package/dist/stories/decorators/index.js.map +0 -1
@@ -11,15 +11,12 @@
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 { Box, CardHeader, Stack, Typography } from '@mui/material';
15
- import { InfoTooltip, combineSx } from '@perses-dev/components';
14
+ import { CardHeader, Stack, Typography } from '@mui/material';
15
+ import { combineSx } from '@perses-dev/components';
16
16
  import { useReplaceVariablesInString } from '@perses-dev/plugin-system';
17
- import InformationOutlineIcon from 'mdi-material-ui/InformationOutline';
18
17
  import { HEADER_ACTIONS_CONTAINER_NAME } from '../../constants';
19
18
  import { PanelActions } from './PanelActions';
20
- import { PanelLinks } from './PanelLinks';
21
- import { HeaderIconButton } from './HeaderIconButton';
22
- export function PanelHeader({ id, title: rawTitle, description: rawDescription, links, readHandlers, editHandlers, sx, extra, ...rest }) {
19
+ export function PanelHeader({ id, title: rawTitle, description: rawDescription, links, queryResults, readHandlers, editHandlers, sx, extra, ...rest }) {
23
20
  const titleElementId = `${id}-title`;
24
21
  const descriptionTooltipId = `${id}-description`;
25
22
  const title = useReplaceVariablesInString(rawTitle);
@@ -47,39 +44,18 @@ export function PanelHeader({ id, title: rawTitle, description: rawDescription,
47
44
  },
48
45
  children: title
49
46
  }),
50
- description !== undefined && description.trim().length > 0 && /*#__PURE__*/ _jsx(Box, {
51
- sx: {
52
- display: editHandlers === undefined ? 'var(--panel-hover, none)' : 'flex'
53
- },
54
- children: /*#__PURE__*/ _jsx(InfoTooltip, {
55
- id: descriptionTooltipId,
56
- description: description,
57
- enterDelay: 100,
58
- children: /*#__PURE__*/ _jsx(HeaderIconButton, {
59
- "aria-label": "panel description",
60
- size: "small",
61
- children: /*#__PURE__*/ _jsx(InformationOutlineIcon, {
62
- "aria-describedby": "info-tooltip",
63
- "aria-hidden": false,
64
- fontSize: "inherit",
65
- sx: {
66
- color: (theme)=>theme.palette.text.secondary
67
- }
68
- })
69
- })
70
- })
71
- }),
72
- links !== undefined && links.length > 0 && /*#__PURE__*/ _jsx(PanelLinks, {
73
- links: links
47
+ /*#__PURE__*/ _jsx(PanelActions, {
48
+ title: title,
49
+ description: description,
50
+ descriptionTooltipId: descriptionTooltipId,
51
+ links: links,
52
+ queryResults: queryResults,
53
+ readHandlers: readHandlers,
54
+ editHandlers: editHandlers,
55
+ extra: extra
74
56
  })
75
57
  ]
76
58
  }),
77
- action: /*#__PURE__*/ _jsx(PanelActions, {
78
- title: title,
79
- readHandlers: readHandlers,
80
- editHandlers: editHandlers,
81
- extra: extra
82
- }),
83
59
  sx: combineSx((theme)=>({
84
60
  containerType: 'inline-size',
85
61
  containerName: HEADER_ACTIONS_CONTAINER_NAME,
@@ -87,13 +63,6 @@ export function PanelHeader({ id, title: rawTitle, description: rawDescription,
87
63
  borderBottom: `solid 1px ${theme.palette.divider}`,
88
64
  '.MuiCardHeader-content': {
89
65
  overflow: 'hidden'
90
- },
91
- '.MuiCardHeader-action': {
92
- // Overriding the negative margins from MUI's defaults, so we
93
- // can vertically center the icons. Moving these values to a wrapper
94
- // inside the action in `HeaderActionWrapper` below.
95
- // https://github.com/mui/material-ui/blob/master/packages/mui-material/src/CardHeader/CardHeader.js#L56-L58
96
- margin: 'auto'
97
66
  }
98
67
  }), sx),
99
68
  ...rest
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/PanelHeader.tsx"],"sourcesContent":["// Copyright 2025 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 { Box, CardHeader, CardHeaderProps, Stack, Typography } from '@mui/material';\nimport { InfoTooltip, combineSx } from '@perses-dev/components';\nimport { Link } from '@perses-dev/core';\nimport { useReplaceVariablesInString } from '@perses-dev/plugin-system';\nimport InformationOutlineIcon from 'mdi-material-ui/InformationOutline';\nimport { ReactElement, ReactNode } from 'react';\nimport { HEADER_ACTIONS_CONTAINER_NAME } from '../../constants';\nimport { PanelActions, PanelActionsProps } from './PanelActions';\nimport { PanelLinks } from './PanelLinks';\nimport { HeaderIconButton } from './HeaderIconButton';\n\ntype OmittedProps = 'children' | 'action' | 'title' | 'disableTypography';\n\nexport interface PanelHeaderProps extends Omit<CardHeaderProps, OmittedProps> {\n id: string;\n title: string;\n description?: string;\n links?: Link[];\n extra?: ReactNode;\n readHandlers?: PanelActionsProps['readHandlers'];\n editHandlers?: PanelActionsProps['editHandlers'];\n}\n\nexport function PanelHeader({\n id,\n title: rawTitle,\n description: rawDescription,\n links,\n readHandlers,\n editHandlers,\n sx,\n extra,\n ...rest\n}: PanelHeaderProps): ReactElement {\n const titleElementId = `${id}-title`;\n const descriptionTooltipId = `${id}-description`;\n\n const title = useReplaceVariablesInString(rawTitle) as string;\n const description = useReplaceVariablesInString(rawDescription);\n\n return (\n <CardHeader\n id={id}\n component=\"header\"\n aria-labelledby={titleElementId}\n aria-describedby={descriptionTooltipId}\n disableTypography\n title={\n <Stack direction=\"row\">\n <Typography\n id={titleElementId}\n variant=\"subtitle1\"\n sx={{\n // `minHeight` guarantees that the header has the correct height\n // when there is no title (i.e. in the preview)\n lineHeight: '24px',\n minHeight: '26px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {title}\n </Typography>\n {/* Show the info tooltip when description is defined and is not all whitespace */}\n {description !== undefined && description.trim().length > 0 && (\n <Box sx={{ display: editHandlers === undefined ? 'var(--panel-hover, none)' : 'flex' }}>\n <InfoTooltip id={descriptionTooltipId} description={description} enterDelay={100}>\n <HeaderIconButton aria-label=\"panel description\" size=\"small\">\n <InformationOutlineIcon\n aria-describedby=\"info-tooltip\"\n aria-hidden={false}\n fontSize=\"inherit\"\n sx={{ color: (theme) => theme.palette.text.secondary }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n </Box>\n )}\n {links !== undefined && links.length > 0 && <PanelLinks links={links} />}\n </Stack>\n }\n action={<PanelActions title={title} readHandlers={readHandlers} editHandlers={editHandlers} extra={extra} />}\n sx={combineSx(\n (theme) => ({\n containerType: 'inline-size',\n containerName: HEADER_ACTIONS_CONTAINER_NAME,\n padding: theme.spacing(1),\n borderBottom: `solid 1px ${theme.palette.divider}`,\n '.MuiCardHeader-content': {\n overflow: 'hidden',\n },\n '.MuiCardHeader-action': {\n // Overriding the negative margins from MUI's defaults, so we\n // can vertically center the icons. Moving these values to a wrapper\n // inside the action in `HeaderActionWrapper` below.\n // https://github.com/mui/material-ui/blob/master/packages/mui-material/src/CardHeader/CardHeader.js#L56-L58\n margin: 'auto',\n },\n }),\n sx\n )}\n {...rest}\n />\n );\n}\n"],"names":["Box","CardHeader","Stack","Typography","InfoTooltip","combineSx","useReplaceVariablesInString","InformationOutlineIcon","HEADER_ACTIONS_CONTAINER_NAME","PanelActions","PanelLinks","HeaderIconButton","PanelHeader","id","title","rawTitle","description","rawDescription","links","readHandlers","editHandlers","sx","extra","rest","titleElementId","descriptionTooltipId","component","aria-labelledby","aria-describedby","disableTypography","direction","variant","lineHeight","minHeight","whiteSpace","overflow","textOverflow","undefined","trim","length","display","enterDelay","aria-label","size","aria-hidden","fontSize","color","theme","palette","text","secondary","action","containerType","containerName","padding","spacing","borderBottom","divider","margin"],"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,SAASA,GAAG,EAAEC,UAAU,EAAmBC,KAAK,EAAEC,UAAU,QAAQ,gBAAgB;AACpF,SAASC,WAAW,EAAEC,SAAS,QAAQ,yBAAyB;AAEhE,SAASC,2BAA2B,QAAQ,4BAA4B;AACxE,OAAOC,4BAA4B,qCAAqC;AAExE,SAASC,6BAA6B,QAAQ,kBAAkB;AAChE,SAASC,YAAY,QAA2B,iBAAiB;AACjE,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,gBAAgB,QAAQ,qBAAqB;AActD,OAAO,SAASC,YAAY,EAC1BC,EAAE,EACFC,OAAOC,QAAQ,EACfC,aAAaC,cAAc,EAC3BC,KAAK,EACLC,YAAY,EACZC,YAAY,EACZC,EAAE,EACFC,KAAK,EACL,GAAGC,MACc;IACjB,MAAMC,iBAAiB,CAAC,EAAEX,GAAG,MAAM,CAAC;IACpC,MAAMY,uBAAuB,CAAC,EAAEZ,GAAG,YAAY,CAAC;IAEhD,MAAMC,QAAQR,4BAA4BS;IAC1C,MAAMC,cAAcV,4BAA4BW;IAEhD,qBACE,KAAChB;QACCY,IAAIA;QACJa,WAAU;QACVC,mBAAiBH;QACjBI,oBAAkBH;QAClBI,iBAAiB;QACjBf,qBACE,MAACZ;YAAM4B,WAAU;;8BACf,KAAC3B;oBACCU,IAAIW;oBACJO,SAAQ;oBACRV,IAAI;wBACF,gEAAgE;wBAChE,+CAA+C;wBAC/CW,YAAY;wBACZC,WAAW;wBACXC,YAAY;wBACZC,UAAU;wBACVC,cAAc;oBAChB;8BAECtB;;gBAGFE,gBAAgBqB,aAAarB,YAAYsB,IAAI,GAAGC,MAAM,GAAG,mBACxD,KAACvC;oBAAIqB,IAAI;wBAAEmB,SAASpB,iBAAiBiB,YAAY,6BAA6B;oBAAO;8BACnF,cAAA,KAACjC;wBAAYS,IAAIY;wBAAsBT,aAAaA;wBAAayB,YAAY;kCAC3E,cAAA,KAAC9B;4BAAiB+B,cAAW;4BAAoBC,MAAK;sCACpD,cAAA,KAACpC;gCACCqB,oBAAiB;gCACjBgB,eAAa;gCACbC,UAAS;gCACTxB,IAAI;oCAAEyB,OAAO,CAACC,QAAUA,MAAMC,OAAO,CAACC,IAAI,CAACC,SAAS;gCAAC;;;;;gBAM9DhC,UAAUmB,aAAanB,MAAMqB,MAAM,GAAG,mBAAK,KAAC7B;oBAAWQ,OAAOA;;;;QAGnEiC,sBAAQ,KAAC1C;YAAaK,OAAOA;YAAOK,cAAcA;YAAcC,cAAcA;YAAcE,OAAOA;;QACnGD,IAAIhB,UACF,CAAC0C,QAAW,CAAA;gBACVK,eAAe;gBACfC,eAAe7C;gBACf8C,SAASP,MAAMQ,OAAO,CAAC;gBACvBC,cAAc,CAAC,UAAU,EAAET,MAAMC,OAAO,CAACS,OAAO,CAAC,CAAC;gBAClD,0BAA0B;oBACxBtB,UAAU;gBACZ;gBACA,yBAAyB;oBACvB,6DAA6D;oBAC7D,oEAAoE;oBACpE,oDAAoD;oBACpD,4GAA4G;oBAC5GuB,QAAQ;gBACV;YACF,CAAA,GACArC;QAED,GAAGE,IAAI;;AAGd"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelHeader.tsx"],"sourcesContent":["// Copyright 2025 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 { CardHeader, CardHeaderProps, Stack, Typography } from '@mui/material';\nimport { combineSx } from '@perses-dev/components';\nimport { Link } from '@perses-dev/core';\nimport { QueryData, useReplaceVariablesInString } from '@perses-dev/plugin-system';\nimport { ReactElement, ReactNode } from 'react';\nimport { HEADER_ACTIONS_CONTAINER_NAME } from '../../constants';\nimport { PanelActions, PanelActionsProps } from './PanelActions';\n\ntype OmittedProps = 'children' | 'action' | 'title' | 'disableTypography';\n\nexport interface PanelHeaderProps extends Omit<CardHeaderProps, OmittedProps> {\n id: string;\n title: string;\n description?: string;\n links?: Link[];\n extra?: ReactNode;\n queryResults: QueryData[];\n readHandlers?: PanelActionsProps['readHandlers'];\n editHandlers?: PanelActionsProps['editHandlers'];\n}\n\nexport function PanelHeader({\n id,\n title: rawTitle,\n description: rawDescription,\n links,\n queryResults,\n readHandlers,\n editHandlers,\n sx,\n extra,\n ...rest\n}: PanelHeaderProps): ReactElement {\n const titleElementId = `${id}-title`;\n const descriptionTooltipId = `${id}-description`;\n\n const title = useReplaceVariablesInString(rawTitle) as string;\n const description = useReplaceVariablesInString(rawDescription);\n\n return (\n <CardHeader\n id={id}\n component=\"header\"\n aria-labelledby={titleElementId}\n aria-describedby={descriptionTooltipId}\n disableTypography\n title={\n <Stack direction=\"row\">\n <Typography\n id={titleElementId}\n variant=\"subtitle1\"\n sx={{\n // `minHeight` guarantees that the header has the correct height\n // when there is no title (i.e. in the preview)\n lineHeight: '24px',\n minHeight: '26px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {title}\n </Typography>\n <PanelActions\n title={title}\n description={description}\n descriptionTooltipId={descriptionTooltipId}\n links={links}\n queryResults={queryResults}\n readHandlers={readHandlers}\n editHandlers={editHandlers}\n extra={extra}\n />\n </Stack>\n }\n sx={combineSx(\n (theme) => ({\n containerType: 'inline-size',\n containerName: HEADER_ACTIONS_CONTAINER_NAME,\n padding: theme.spacing(1),\n borderBottom: `solid 1px ${theme.palette.divider}`,\n '.MuiCardHeader-content': {\n overflow: 'hidden',\n },\n }),\n sx\n )}\n {...rest}\n />\n );\n}\n"],"names":["CardHeader","Stack","Typography","combineSx","useReplaceVariablesInString","HEADER_ACTIONS_CONTAINER_NAME","PanelActions","PanelHeader","id","title","rawTitle","description","rawDescription","links","queryResults","readHandlers","editHandlers","sx","extra","rest","titleElementId","descriptionTooltipId","component","aria-labelledby","aria-describedby","disableTypography","direction","variant","lineHeight","minHeight","whiteSpace","overflow","textOverflow","theme","containerType","containerName","padding","spacing","borderBottom","palette","divider"],"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,SAASA,UAAU,EAAmBC,KAAK,EAAEC,UAAU,QAAQ,gBAAgB;AAC/E,SAASC,SAAS,QAAQ,yBAAyB;AAEnD,SAAoBC,2BAA2B,QAAQ,4BAA4B;AAEnF,SAASC,6BAA6B,QAAQ,kBAAkB;AAChE,SAASC,YAAY,QAA2B,iBAAiB;AAejE,OAAO,SAASC,YAAY,EAC1BC,EAAE,EACFC,OAAOC,QAAQ,EACfC,aAAaC,cAAc,EAC3BC,KAAK,EACLC,YAAY,EACZC,YAAY,EACZC,YAAY,EACZC,EAAE,EACFC,KAAK,EACL,GAAGC,MACc;IACjB,MAAMC,iBAAiB,GAAGZ,GAAG,MAAM,CAAC;IACpC,MAAMa,uBAAuB,GAAGb,GAAG,YAAY,CAAC;IAEhD,MAAMC,QAAQL,4BAA4BM;IAC1C,MAAMC,cAAcP,4BAA4BQ;IAEhD,qBACE,KAACZ;QACCQ,IAAIA;QACJc,WAAU;QACVC,mBAAiBH;QACjBI,oBAAkBH;QAClBI,iBAAiB;QACjBhB,qBACE,MAACR;YAAMyB,WAAU;;8BACf,KAACxB;oBACCM,IAAIY;oBACJO,SAAQ;oBACRV,IAAI;wBACF,gEAAgE;wBAChE,+CAA+C;wBAC/CW,YAAY;wBACZC,WAAW;wBACXC,YAAY;wBACZC,UAAU;wBACVC,cAAc;oBAChB;8BAECvB;;8BAEH,KAACH;oBACCG,OAAOA;oBACPE,aAAaA;oBACbU,sBAAsBA;oBACtBR,OAAOA;oBACPC,cAAcA;oBACdC,cAAcA;oBACdC,cAAcA;oBACdE,OAAOA;;;;QAIbD,IAAId,UACF,CAAC8B,QAAW,CAAA;gBACVC,eAAe;gBACfC,eAAe9B;gBACf+B,SAASH,MAAMI,OAAO,CAAC;gBACvBC,cAAc,CAAC,UAAU,EAAEL,MAAMM,OAAO,CAACC,OAAO,EAAE;gBAClD,0BAA0B;oBACxBT,UAAU;gBACZ;YACF,CAAA,GACAd;QAED,GAAGE,IAAI;;AAGd"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/PanelLinks.tsx"],"sourcesContent":["// Copyright 2024 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, Link as LinkComponent, Menu, MenuItem, Theme } from '@mui/material';\nimport LaunchIcon from 'mdi-material-ui/Launch';\nimport { Link } from '@perses-dev/core';\nimport { MouseEvent, ReactElement, useState } from 'react';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { useReplaceVariablesInString } from '@perses-dev/plugin-system';\n\nexport function PanelLinks({ links }: { links: Link[] }): ReactElement {\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n const isMenuOpened = Boolean(anchorEl);\n const handleOpenMenu = (event: MouseEvent<HTMLButtonElement>): void => {\n setAnchorEl(event.currentTarget);\n };\n const handleClose = (): void => {\n setAnchorEl(null);\n };\n\n // If there is only one link, show it directly\n if (links.length === 1 && links[0]) {\n const link = links[0];\n return <LinkButton link={link} />;\n }\n\n // Else we show a menu with a list of all links\n return (\n <>\n <InfoTooltip description={`${links.length} links`} enterDelay={100}>\n <IconButton\n aria-label=\"Panel links\"\n size=\"small\"\n onClick={handleOpenMenu}\n sx={(theme) => ({ borderRadius: theme.shape.borderRadius, padding: '4px' })}\n >\n <LaunchIcon\n aria-describedby=\"links-icon\"\n fontSize=\"inherit\"\n sx={{ color: (theme) => theme.palette.text.secondary }}\n />\n </IconButton>\n </InfoTooltip>\n\n <Menu\n anchorEl={anchorEl}\n open={isMenuOpened}\n onClose={handleClose}\n MenuListProps={{\n 'aria-labelledby': 'panel-links',\n }}\n >\n {links.map((link: Link) => (\n <LinkMenuItem key={link.url} link={link} />\n ))}\n </Menu>\n </>\n );\n}\n\nfunction LinkButton({ link }: { link: Link }): ReactElement {\n const { url, name, tooltip, targetBlank } = useLink(link);\n\n return (\n <InfoTooltip description={tooltip ?? url} enterDelay={100}>\n <IconButton\n aria-label={name ?? url}\n size=\"small\"\n href={url}\n target={targetBlank ? '_blank' : '_self'}\n sx={(theme) => ({ borderRadius: theme.shape.borderRadius, padding: '4px' })}\n >\n <LaunchIcon fontSize=\"inherit\" sx={{ color: (theme: Theme) => theme.palette.text.secondary }} />\n </IconButton>\n </InfoTooltip>\n );\n}\n\nfunction LinkMenuItem({ link }: { link: Link }): ReactElement {\n const { url, name, tooltip, targetBlank } = useLink(link);\n\n return (\n <InfoTooltip description={tooltip ?? url} enterDelay={100}>\n <MenuItem component={LinkComponent} href={url} target={targetBlank ? '_blank' : '_self'}>\n {name ?? url}\n </MenuItem>\n </InfoTooltip>\n );\n}\n\nfunction useLink(link: Link): Link {\n const url = useReplaceVariablesInString(link.url) ?? link.url;\n const name = useReplaceVariablesInString(link.name);\n const tooltip = useReplaceVariablesInString(link.tooltip);\n\n if (link.renderVariables === false) {\n return link;\n }\n\n return { ...link, url, name, tooltip };\n}\n"],"names":["IconButton","Link","LinkComponent","Menu","MenuItem","LaunchIcon","useState","InfoTooltip","useReplaceVariablesInString","PanelLinks","links","anchorEl","setAnchorEl","isMenuOpened","Boolean","handleOpenMenu","event","currentTarget","handleClose","length","link","LinkButton","description","enterDelay","aria-label","size","onClick","sx","theme","borderRadius","shape","padding","aria-describedby","fontSize","color","palette","text","secondary","open","onClose","MenuListProps","map","LinkMenuItem","url","name","tooltip","targetBlank","useLink","href","target","component","renderVariables"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelLinks.tsx"],"sourcesContent":["// Copyright 2024 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, Link as LinkComponent, Menu, MenuItem, Theme } from '@mui/material';\nimport LaunchIcon from 'mdi-material-ui/Launch';\nimport { Link } from '@perses-dev/core';\nimport { MouseEvent, ReactElement, useState } from 'react';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { useReplaceVariablesInString } from '@perses-dev/plugin-system';\n\nexport function PanelLinks({ links }: { links: Link[] }): ReactElement {\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n const isMenuOpened = Boolean(anchorEl);\n const handleOpenMenu = (event: MouseEvent<HTMLButtonElement>): void => {\n setAnchorEl(event.currentTarget);\n };\n const handleClose = (): void => {\n setAnchorEl(null);\n };\n\n // If there is only one link, show it directly\n if (links.length === 1 && links[0]) {\n const link = links[0];\n return <LinkButton link={link} />;\n }\n\n // Else we show a menu with a list of all links\n return (\n <>\n <InfoTooltip description={`${links.length} links`} enterDelay={100}>\n <IconButton\n aria-label=\"Panel links\"\n size=\"small\"\n onClick={handleOpenMenu}\n sx={(theme) => ({ borderRadius: theme.shape.borderRadius, padding: '4px' })}\n >\n <LaunchIcon\n aria-describedby=\"links-icon\"\n fontSize=\"inherit\"\n sx={{ color: (theme) => theme.palette.text.secondary }}\n />\n </IconButton>\n </InfoTooltip>\n\n <Menu\n anchorEl={anchorEl}\n open={isMenuOpened}\n onClose={handleClose}\n MenuListProps={{\n 'aria-labelledby': 'panel-links',\n }}\n >\n {links.map((link: Link) => (\n <LinkMenuItem key={link.url} link={link} />\n ))}\n </Menu>\n </>\n );\n}\n\nfunction LinkButton({ link }: { link: Link }): ReactElement {\n const { url, name, tooltip, targetBlank } = useLink(link);\n\n return (\n <InfoTooltip description={tooltip ?? url} enterDelay={100}>\n <IconButton\n aria-label={name ?? url}\n size=\"small\"\n href={url}\n target={targetBlank ? '_blank' : '_self'}\n sx={(theme) => ({ borderRadius: theme.shape.borderRadius, padding: '4px' })}\n >\n <LaunchIcon fontSize=\"inherit\" sx={{ color: (theme: Theme) => theme.palette.text.secondary }} />\n </IconButton>\n </InfoTooltip>\n );\n}\n\nfunction LinkMenuItem({ link }: { link: Link }): ReactElement {\n const { url, name, tooltip, targetBlank } = useLink(link);\n\n return (\n <InfoTooltip description={tooltip ?? url} enterDelay={100}>\n <MenuItem component={LinkComponent} href={url} target={targetBlank ? '_blank' : '_self'}>\n {name ?? url}\n </MenuItem>\n </InfoTooltip>\n );\n}\n\nfunction useLink(link: Link): Link {\n const url = useReplaceVariablesInString(link.url) ?? link.url;\n const name = useReplaceVariablesInString(link.name);\n const tooltip = useReplaceVariablesInString(link.tooltip);\n\n if (link.renderVariables === false) {\n return link;\n }\n\n return { ...link, url, name, tooltip };\n}\n"],"names":["IconButton","Link","LinkComponent","Menu","MenuItem","LaunchIcon","useState","InfoTooltip","useReplaceVariablesInString","PanelLinks","links","anchorEl","setAnchorEl","isMenuOpened","Boolean","handleOpenMenu","event","currentTarget","handleClose","length","link","LinkButton","description","enterDelay","aria-label","size","onClick","sx","theme","borderRadius","shape","padding","aria-describedby","fontSize","color","palette","text","secondary","open","onClose","MenuListProps","map","LinkMenuItem","url","name","tooltip","targetBlank","useLink","href","target","component","renderVariables"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { PanelProps } from '@perses-dev/plugin-system';
2
+ import { UnknownSpec, QueryDataType } from '@perses-dev/core';
3
+ import { ReactElement } from 'react';
4
+ interface PanelPluginProps extends PanelProps<UnknownSpec, QueryDataType> {
5
+ kind: string;
6
+ }
7
+ /**
8
+ * PanelPluginLoader loads the panel plugin specified by the 'kind' prop from the plugin registry and
9
+ * renders its PanelComponent.
10
+ */
11
+ export declare function PanelPluginLoader(props: PanelPluginProps): ReactElement;
12
+ export {};
13
+ //# sourceMappingURL=PanelPluginLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelPluginLoader.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelPluginLoader.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAa,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAGrC,UAAU,gBAAiB,SAAQ,UAAU,CAAC,WAAW,EAAE,aAAa,CAAC;IACvE,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CAsCvE"}
@@ -0,0 +1,51 @@
1
+ // Copyright 2025 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ import { usePlugin } from '@perses-dev/plugin-system';
15
+ import { Skeleton } from '@mui/material';
16
+ /**
17
+ * PanelPluginLoader loads the panel plugin specified by the 'kind' prop from the plugin registry and
18
+ * renders its PanelComponent.
19
+ */ export function PanelPluginLoader(props) {
20
+ const { kind, spec, contentDimensions, definition, queryResults } = props;
21
+ const { data: plugin, isLoading: isPanelLoading } = usePlugin('Panel', kind, {
22
+ throwOnError: true
23
+ });
24
+ const PanelComponent = plugin?.PanelComponent;
25
+ const supportedQueryTypes = plugin?.supportedQueryTypes || [];
26
+ // Show fullsize skeleton if the panel plugin is loading.
27
+ if (isPanelLoading) {
28
+ return /*#__PURE__*/ _jsx(Skeleton, {
29
+ variant: "rectangular",
30
+ width: contentDimensions?.width,
31
+ height: contentDimensions?.height,
32
+ "aria-label": "Loading..."
33
+ });
34
+ }
35
+ if (PanelComponent === undefined) {
36
+ throw new Error(`Missing PanelComponent from panel plugin for kind '${kind}'`);
37
+ }
38
+ for (const queryResult of queryResults){
39
+ if (!supportedQueryTypes.includes(queryResult.definition.kind)) {
40
+ throw new Error(`This panel does not support queries of type '${queryResult.definition.kind}'. Supported query types: ${supportedQueryTypes.join(', ')}.`);
41
+ }
42
+ }
43
+ return /*#__PURE__*/ _jsx(PanelComponent, {
44
+ spec: spec,
45
+ contentDimensions: contentDimensions,
46
+ definition: definition,
47
+ queryResults: queryResults
48
+ });
49
+ }
50
+
51
+ //# sourceMappingURL=PanelPluginLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelPluginLoader.tsx"],"sourcesContent":["// Copyright 2025 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 { UnknownSpec, QueryDataType } from '@perses-dev/core';\nimport { ReactElement } from 'react';\nimport { Skeleton } from '@mui/material';\n\ninterface PanelPluginProps extends PanelProps<UnknownSpec, QueryDataType> {\n kind: string;\n}\n\n/**\n * PanelPluginLoader loads the panel plugin specified by the 'kind' prop from the plugin registry and\n * renders its PanelComponent.\n */\nexport function PanelPluginLoader(props: PanelPluginProps): ReactElement {\n const { kind, spec, contentDimensions, definition, queryResults } = props;\n const { data: plugin, isLoading: isPanelLoading } = usePlugin('Panel', kind, { throwOnError: true });\n const PanelComponent = plugin?.PanelComponent;\n const supportedQueryTypes = plugin?.supportedQueryTypes || [];\n\n // Show fullsize skeleton if the panel plugin is loading.\n if (isPanelLoading) {\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 '${kind}'`);\n }\n\n for (const queryResult of queryResults) {\n if (!supportedQueryTypes.includes(queryResult.definition.kind)) {\n throw new Error(\n `This panel does not support queries of type '${queryResult.definition.kind}'. Supported query types: ${supportedQueryTypes.join(', ')}.`\n );\n }\n }\n\n return (\n <PanelComponent\n spec={spec}\n contentDimensions={contentDimensions}\n definition={definition}\n queryResults={queryResults}\n />\n );\n}\n"],"names":["usePlugin","Skeleton","PanelPluginLoader","props","kind","spec","contentDimensions","definition","queryResults","data","plugin","isLoading","isPanelLoading","throwOnError","PanelComponent","supportedQueryTypes","variant","width","height","aria-label","undefined","Error","queryResult","includes","join"],"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,SAASA,SAAS,QAAoB,4BAA4B;AAGlE,SAASC,QAAQ,QAAQ,gBAAgB;AAMzC;;;CAGC,GACD,OAAO,SAASC,kBAAkBC,KAAuB;IACvD,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAEC,iBAAiB,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGL;IACpE,MAAM,EAAEM,MAAMC,MAAM,EAAEC,WAAWC,cAAc,EAAE,GAAGZ,UAAU,SAASI,MAAM;QAAES,cAAc;IAAK;IAClG,MAAMC,iBAAiBJ,QAAQI;IAC/B,MAAMC,sBAAsBL,QAAQK,uBAAuB,EAAE;IAE7D,yDAAyD;IACzD,IAAIH,gBAAgB;QAClB,qBACE,KAACX;YACCe,SAAQ;YACRC,OAAOX,mBAAmBW;YAC1BC,QAAQZ,mBAAmBY;YAC3BC,cAAW;;IAGjB;IAEA,IAAIL,mBAAmBM,WAAW;QAChC,MAAM,IAAIC,MAAM,CAAC,mDAAmD,EAAEjB,KAAK,CAAC,CAAC;IAC/E;IAEA,KAAK,MAAMkB,eAAed,aAAc;QACtC,IAAI,CAACO,oBAAoBQ,QAAQ,CAACD,YAAYf,UAAU,CAACH,IAAI,GAAG;YAC9D,MAAM,IAAIiB,MACR,CAAC,6CAA6C,EAAEC,YAAYf,UAAU,CAACH,IAAI,CAAC,0BAA0B,EAAEW,oBAAoBS,IAAI,CAAC,MAAM,CAAC,CAAC;QAE7I;IACF;IAEA,qBACE,KAACV;QACCT,MAAMA;QACNC,mBAAmBA;QACnBC,YAAYA;QACZC,cAAcA;;AAGpB"}
@@ -1,2 +1,3 @@
1
1
  export * from './Panel';
2
+ export * from './PanelPluginLoader';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/index.ts"],"names":[],"mappings":"AAaA,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/index.ts"],"names":[],"mappings":"AAaA,cAAc,SAAS,CAAC;AACxB,cAAc,qBAAqB,CAAC"}
@@ -11,5 +11,6 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
  export * from './Panel';
14
+ export * from './PanelPluginLoader';
14
15
 
15
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/index.ts"],"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\nexport * from './Panel';\n"],"names":[],"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,cAAc,UAAU"}
1
+ {"version":3,"sources":["../../../src/components/Panel/index.ts"],"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\nexport * from './Panel';\nexport * from './PanelPluginLoader';\n"],"names":[],"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,cAAc,UAAU;AACxB,cAAc,sBAAsB"}
@@ -1 +1 @@
1
- {"version":3,"file":"PanelEditorForm.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelEditorForm.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAuB,MAAM,OAAO,CAAC;AAE1D,OAAO,EAAE,MAAM,EAAmB,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAgB9E,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,iBAAiB,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CA0NzE;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC"}
1
+ {"version":3,"file":"PanelEditorForm.d.ts","sourceRoot":"","sources":["../../../src/components/PanelDrawer/PanelEditorForm.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAuB,MAAM,OAAO,CAAC;AAE1D,OAAO,EAAE,MAAM,EAAmB,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAgB9E,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,iBAAiB,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC5C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CA8NzE;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC"}
@@ -26,6 +26,12 @@ export function PanelEditorForm(props) {
26
26
  const { panelDefinition, setName, setDescription, setLinks, setQueries, setPlugin, setPanelDefinition } = usePanelEditor(initialValues.panelDefinition);
27
27
  const { plugin } = panelDefinition.spec;
28
28
  const [isDiscardDialogOpened, setDiscardDialogOpened] = useState(false);
29
+ const { panelEditorSchema } = useValidationSchemas();
30
+ const form = useForm({
31
+ resolver: zodResolver(panelEditorSchema),
32
+ mode: 'onBlur',
33
+ defaultValues: initialValues
34
+ });
29
35
  // Use common plugin editor logic even though we've split the inputs up in this form
30
36
  const pluginEditor = usePluginEditor({
31
37
  pluginTypes: [
@@ -54,12 +60,6 @@ export function PanelEditorForm(props) {
54
60
  });
55
61
  const titleAction = getTitleAction(initialAction, true);
56
62
  const submitText = getSubmitText(initialAction, true);
57
- const { panelEditorSchema } = useValidationSchemas();
58
- const form = useForm({
59
- resolver: zodResolver(panelEditorSchema),
60
- mode: 'onBlur',
61
- defaultValues: initialValues
62
- });
63
63
  const links = useWatch({
64
64
  control: form.control,
65
65
  name: 'panelDefinition.spec.links'
@@ -93,6 +93,18 @@ export function PanelEditorForm(props) {
93
93
  }
94
94
  setPanelDefinition(nextPanelDef);
95
95
  };
96
+ const watchedName = useWatch({
97
+ control: form.control,
98
+ name: 'panelDefinition.spec.display.name'
99
+ });
100
+ const watchedDescription = useWatch({
101
+ control: form.control,
102
+ name: 'panelDefinition.spec.display.description'
103
+ });
104
+ const watchedPluginKind = useWatch({
105
+ control: form.control,
106
+ name: 'panelDefinition.spec.plugin.kind'
107
+ });
96
108
  return /*#__PURE__*/ _jsxs(FormProvider, {
97
109
  ...form,
98
110
  children: [
@@ -156,7 +168,7 @@ export function PanelEditorForm(props) {
156
168
  label: "Name",
157
169
  error: !!fieldState.error,
158
170
  helperText: fieldState.error?.message,
159
- value: field.value ?? '',
171
+ value: watchedName ?? '',
160
172
  onChange: (event)=>{
161
173
  field.onChange(event);
162
174
  setName(event.target.value);
@@ -200,7 +212,7 @@ export function PanelEditorForm(props) {
200
212
  label: "Description",
201
213
  error: !!fieldState.error,
202
214
  helperText: fieldState.error?.message,
203
- value: field.value ?? '',
215
+ value: watchedDescription ?? '',
204
216
  onChange: (event)=>{
205
217
  field.onChange(event);
206
218
  setDescription(event.target.value);
@@ -227,7 +239,7 @@ export function PanelEditorForm(props) {
227
239
  helperText: pluginEditor.error?.message ?? fieldState.error?.message,
228
240
  value: {
229
241
  type: 'Panel',
230
- kind: field.value
242
+ kind: watchedPluginKind
231
243
  },
232
244
  onChange: (event)=>{
233
245
  field.onChange(event.kind);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/PanelDrawer/PanelEditorForm.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 { ReactElement, useEffect, useState } from 'react';\nimport { Box, Button, Grid, MenuItem, Stack, TextField, Typography } from '@mui/material';\nimport { Action, PanelDefinition, PanelEditorValues } from '@perses-dev/core';\nimport { DiscardChangesConfirmationDialog, ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport {\n PluginKindSelect,\n usePluginEditor,\n PanelSpecEditor,\n getTitleAction,\n getSubmitText,\n useValidationSchemas,\n} from '@perses-dev/plugin-system';\nimport { Controller, FormProvider, SubmitHandler, useForm, useWatch } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useListPanelGroups } from '../../context';\nimport { PanelPreview } from './PanelPreview';\nimport { usePanelEditor } from './usePanelEditor';\n\nexport interface PanelEditorFormProps {\n initialValues: PanelEditorValues;\n initialAction: Action;\n onSave: (values: PanelEditorValues) => void;\n onClose: () => void;\n}\n\nexport function PanelEditorForm(props: PanelEditorFormProps): ReactElement {\n const { initialValues, initialAction, onSave, onClose } = props;\n const panelGroups = useListPanelGroups();\n const { panelDefinition, setName, setDescription, setLinks, setQueries, setPlugin, setPanelDefinition } =\n usePanelEditor(initialValues.panelDefinition);\n const { plugin } = panelDefinition.spec;\n const [isDiscardDialogOpened, setDiscardDialogOpened] = useState<boolean>(false);\n\n // Use common plugin editor logic even though we've split the inputs up in this form\n const pluginEditor = usePluginEditor({\n pluginTypes: ['Panel'],\n value: { selection: { kind: plugin.kind, type: 'Panel' }, spec: plugin.spec },\n onChange: (plugin) => {\n form.setValue('panelDefinition.spec.plugin', { kind: plugin.selection.kind, spec: plugin.spec });\n setPlugin({\n kind: plugin.selection.kind,\n spec: plugin.spec,\n });\n },\n onHideQueryEditorChange: (isHidden) => {\n setQueries(undefined, isHidden);\n },\n });\n\n const titleAction = getTitleAction(initialAction, true);\n const submitText = getSubmitText(initialAction, true);\n\n const { panelEditorSchema } = useValidationSchemas();\n const form = useForm<PanelEditorValues>({\n resolver: zodResolver(panelEditorSchema),\n mode: 'onBlur',\n defaultValues: initialValues,\n });\n\n const links = useWatch({ control: form.control, name: 'panelDefinition.spec.links' });\n useEffect(() => {\n setLinks(links);\n }, [setLinks, links]);\n\n const processForm: SubmitHandler<PanelEditorValues> = (data) => {\n onSave(data);\n };\n\n // When user click on cancel, several possibilities:\n // - create action: ask for discard approval\n // - update action: ask for discard approval if changed\n // - read action: don´t ask for discard approval\n function handleCancel(): void {\n if (JSON.stringify(initialValues) !== JSON.stringify(form.getValues())) {\n setDiscardDialogOpened(true);\n } else {\n onClose();\n }\n }\n\n const handlePanelDefinitionChange = (nextPanelDefStr: string): void => {\n const nextPanelDef: PanelDefinition = JSON.parse(nextPanelDefStr);\n const { kind: pluginKind, spec: pluginSpec } = nextPanelDef.spec.plugin;\n // if panel plugin kind and spec are modified, then need to save current spec\n if (\n panelDefinition.spec.plugin.kind !== pluginKind &&\n JSON.stringify(panelDefinition.spec.plugin.spec) !== JSON.stringify(pluginSpec)\n ) {\n pluginEditor.rememberCurrentSpecState();\n }\n setPanelDefinition(nextPanelDef);\n };\n\n return (\n <FormProvider {...form}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n padding: (theme) => theme.spacing(1, 2),\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n }}\n >\n <Typography variant=\"h2\">{titleAction} Panel</Typography>\n <Stack direction=\"row\" spacing={1} marginLeft=\"auto\">\n <Button variant=\"contained\" disabled={!form.formState.isValid} onClick={form.handleSubmit(processForm)}>\n {submitText}\n </Button>\n <Button color=\"secondary\" variant=\"outlined\" onClick={handleCancel}>\n Cancel\n </Button>\n </Stack>\n </Box>\n <Box id={panelEditorFormId} sx={{ flex: 1, overflowY: 'scroll', padding: (theme) => theme.spacing(2) }}>\n <Grid container spacing={2}>\n <Grid item xs={8}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.display.name\"\n render={({ field, fieldState }) => (\n <TextField\n {...field}\n required\n fullWidth\n label=\"Name\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n value={field.value ?? ''}\n onChange={(event) => {\n field.onChange(event);\n setName(event.target.value);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={4}>\n <Controller\n control={form.control}\n name=\"groupId\"\n render={({ field, fieldState }) => (\n <TextField\n select\n {...field}\n required\n fullWidth\n label=\"Group\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n onChange={(event) => {\n field.onChange(event);\n }}\n >\n {panelGroups.map((panelGroup, index) => (\n <MenuItem key={panelGroup.id} value={panelGroup.id}>\n {panelGroup.title ?? `Group ${index + 1}`}\n </MenuItem>\n ))}\n </TextField>\n )}\n />\n </Grid>\n <Grid item xs={8}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.display.description\"\n render={({ field, fieldState }) => (\n <TextField\n {...field}\n fullWidth\n label=\"Description\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n value={field.value ?? ''}\n onChange={(event) => {\n field.onChange(event);\n setDescription(event.target.value);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={4}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.plugin.kind\"\n render={({ field, fieldState }) => (\n <PluginKindSelect\n {...field}\n pluginTypes={['Panel']}\n required\n fullWidth\n label=\"Type\"\n disabled={pluginEditor.isLoading}\n error={!!pluginEditor.error || !!fieldState.error}\n helperText={pluginEditor.error?.message ?? fieldState.error?.message}\n value={{ type: 'Panel', kind: field.value }}\n onChange={(event) => {\n field.onChange(event.kind);\n pluginEditor.onSelectionChange(event);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={12}>\n <Typography variant=\"h4\" marginBottom={1}>\n Preview\n </Typography>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelPreview panelDefinition={panelDefinition} />\n </ErrorBoundary>\n </Grid>\n <Grid item xs={12}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelSpecEditor\n control={form.control}\n panelDefinition={panelDefinition}\n onJSONChange={handlePanelDefinitionChange}\n onQueriesChange={(queries) => {\n setQueries(queries);\n }}\n onPluginSpecChange={(spec) => {\n pluginEditor.onSpecChange(spec);\n }}\n />\n </ErrorBoundary>\n </Grid>\n </Grid>\n </Box>\n <DiscardChangesConfirmationDialog\n description=\"You have unapplied changes in this panel. Are you sure you want to discard these changes? Changes cannot be recovered.\"\n isOpen={isDiscardDialogOpened}\n onCancel={() => {\n setDiscardDialogOpened(false);\n }}\n onDiscardChanges={() => {\n setDiscardDialogOpened(false);\n onClose();\n }}\n />\n </FormProvider>\n );\n}\n\n/**\n * The `id` attribute added to the `PanelEditorForm` component, allowing submit buttons to live outside the form.\n */\nexport const panelEditorFormId = 'panel-editor-form';\n"],"names":["useEffect","useState","Box","Button","Grid","MenuItem","Stack","TextField","Typography","DiscardChangesConfirmationDialog","ErrorAlert","ErrorBoundary","PluginKindSelect","usePluginEditor","PanelSpecEditor","getTitleAction","getSubmitText","useValidationSchemas","Controller","FormProvider","useForm","useWatch","zodResolver","useListPanelGroups","PanelPreview","usePanelEditor","PanelEditorForm","props","initialValues","initialAction","onSave","onClose","panelGroups","panelDefinition","setName","setDescription","setLinks","setQueries","setPlugin","setPanelDefinition","plugin","spec","isDiscardDialogOpened","setDiscardDialogOpened","pluginEditor","pluginTypes","value","selection","kind","type","onChange","form","setValue","onHideQueryEditorChange","isHidden","undefined","titleAction","submitText","panelEditorSchema","resolver","mode","defaultValues","links","control","name","processForm","data","handleCancel","JSON","stringify","getValues","handlePanelDefinitionChange","nextPanelDefStr","nextPanelDef","parse","pluginKind","pluginSpec","rememberCurrentSpecState","sx","display","alignItems","padding","theme","spacing","borderBottom","palette","divider","variant","direction","marginLeft","disabled","formState","isValid","onClick","handleSubmit","color","id","panelEditorFormId","flex","overflowY","container","item","xs","render","field","fieldState","required","fullWidth","label","error","helperText","message","event","target","select","map","panelGroup","index","title","isLoading","onSelectionChange","marginBottom","FallbackComponent","onJSONChange","onQueriesChange","queries","onPluginSpecChange","onSpecChange","description","isOpen","onCancel","onDiscardChanges"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/PanelDrawer/PanelEditorForm.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 { ReactElement, useEffect, useState } from 'react';\nimport { Box, Button, Grid, MenuItem, Stack, TextField, Typography } from '@mui/material';\nimport { Action, PanelDefinition, PanelEditorValues } from '@perses-dev/core';\nimport { DiscardChangesConfirmationDialog, ErrorAlert, ErrorBoundary } from '@perses-dev/components';\nimport {\n PluginKindSelect,\n usePluginEditor,\n PanelSpecEditor,\n getTitleAction,\n getSubmitText,\n useValidationSchemas,\n} from '@perses-dev/plugin-system';\nimport { Controller, FormProvider, SubmitHandler, useForm, useWatch } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useListPanelGroups } from '../../context';\nimport { PanelPreview } from './PanelPreview';\nimport { usePanelEditor } from './usePanelEditor';\n\nexport interface PanelEditorFormProps {\n initialValues: PanelEditorValues;\n initialAction: Action;\n onSave: (values: PanelEditorValues) => void;\n onClose: () => void;\n}\n\nexport function PanelEditorForm(props: PanelEditorFormProps): ReactElement {\n const { initialValues, initialAction, onSave, onClose } = props;\n const panelGroups = useListPanelGroups();\n const { panelDefinition, setName, setDescription, setLinks, setQueries, setPlugin, setPanelDefinition } =\n usePanelEditor(initialValues.panelDefinition);\n const { plugin } = panelDefinition.spec;\n const [isDiscardDialogOpened, setDiscardDialogOpened] = useState<boolean>(false);\n\n const { panelEditorSchema } = useValidationSchemas();\n const form = useForm<PanelEditorValues>({\n resolver: zodResolver(panelEditorSchema),\n mode: 'onBlur',\n defaultValues: initialValues,\n });\n\n // Use common plugin editor logic even though we've split the inputs up in this form\n const pluginEditor = usePluginEditor({\n pluginTypes: ['Panel'],\n value: { selection: { kind: plugin.kind, type: 'Panel' }, spec: plugin.spec },\n onChange: (plugin) => {\n form.setValue('panelDefinition.spec.plugin', { kind: plugin.selection.kind, spec: plugin.spec });\n setPlugin({\n kind: plugin.selection.kind,\n spec: plugin.spec,\n });\n },\n onHideQueryEditorChange: (isHidden) => {\n setQueries(undefined, isHidden);\n },\n });\n\n const titleAction = getTitleAction(initialAction, true);\n const submitText = getSubmitText(initialAction, true);\n\n const links = useWatch({ control: form.control, name: 'panelDefinition.spec.links' });\n useEffect(() => {\n setLinks(links);\n }, [setLinks, links]);\n\n const processForm: SubmitHandler<PanelEditorValues> = (data) => {\n onSave(data);\n };\n\n // When user click on cancel, several possibilities:\n // - create action: ask for discard approval\n // - update action: ask for discard approval if changed\n // - read action: don´t ask for discard approval\n function handleCancel(): void {\n if (JSON.stringify(initialValues) !== JSON.stringify(form.getValues())) {\n setDiscardDialogOpened(true);\n } else {\n onClose();\n }\n }\n\n const handlePanelDefinitionChange = (nextPanelDefStr: string): void => {\n const nextPanelDef: PanelDefinition = JSON.parse(nextPanelDefStr);\n const { kind: pluginKind, spec: pluginSpec } = nextPanelDef.spec.plugin;\n // if panel plugin kind and spec are modified, then need to save current spec\n if (\n panelDefinition.spec.plugin.kind !== pluginKind &&\n JSON.stringify(panelDefinition.spec.plugin.spec) !== JSON.stringify(pluginSpec)\n ) {\n pluginEditor.rememberCurrentSpecState();\n }\n setPanelDefinition(nextPanelDef);\n };\n\n const watchedName = useWatch({ control: form.control, name: 'panelDefinition.spec.display.name' });\n const watchedDescription = useWatch({ control: form.control, name: 'panelDefinition.spec.display.description' });\n const watchedPluginKind = useWatch({ control: form.control, name: 'panelDefinition.spec.plugin.kind' });\n\n return (\n <FormProvider {...form}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n padding: (theme) => theme.spacing(1, 2),\n borderBottom: (theme) => `1px solid ${theme.palette.divider}`,\n }}\n >\n <Typography variant=\"h2\">{titleAction} Panel</Typography>\n <Stack direction=\"row\" spacing={1} marginLeft=\"auto\">\n <Button variant=\"contained\" disabled={!form.formState.isValid} onClick={form.handleSubmit(processForm)}>\n {submitText}\n </Button>\n <Button color=\"secondary\" variant=\"outlined\" onClick={handleCancel}>\n Cancel\n </Button>\n </Stack>\n </Box>\n <Box id={panelEditorFormId} sx={{ flex: 1, overflowY: 'scroll', padding: (theme) => theme.spacing(2) }}>\n <Grid container spacing={2}>\n <Grid item xs={8}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.display.name\"\n render={({ field, fieldState }) => (\n <TextField\n {...field}\n required\n fullWidth\n label=\"Name\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n value={watchedName ?? ''}\n onChange={(event) => {\n field.onChange(event);\n setName(event.target.value);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={4}>\n <Controller\n control={form.control}\n name=\"groupId\"\n render={({ field, fieldState }) => (\n <TextField\n select\n {...field}\n required\n fullWidth\n label=\"Group\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n onChange={(event) => {\n field.onChange(event);\n }}\n >\n {panelGroups.map((panelGroup, index) => (\n <MenuItem key={panelGroup.id} value={panelGroup.id}>\n {panelGroup.title ?? `Group ${index + 1}`}\n </MenuItem>\n ))}\n </TextField>\n )}\n />\n </Grid>\n <Grid item xs={8}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.display.description\"\n render={({ field, fieldState }) => (\n <TextField\n {...field}\n fullWidth\n label=\"Description\"\n error={!!fieldState.error}\n helperText={fieldState.error?.message}\n value={watchedDescription ?? ''}\n onChange={(event) => {\n field.onChange(event);\n setDescription(event.target.value);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={4}>\n <Controller\n control={form.control}\n name=\"panelDefinition.spec.plugin.kind\"\n render={({ field, fieldState }) => (\n <PluginKindSelect\n {...field}\n pluginTypes={['Panel']}\n required\n fullWidth\n label=\"Type\"\n disabled={pluginEditor.isLoading}\n error={!!pluginEditor.error || !!fieldState.error}\n helperText={pluginEditor.error?.message ?? fieldState.error?.message}\n value={{ type: 'Panel', kind: watchedPluginKind }}\n onChange={(event) => {\n field.onChange(event.kind);\n pluginEditor.onSelectionChange(event);\n }}\n />\n )}\n />\n </Grid>\n <Grid item xs={12}>\n <Typography variant=\"h4\" marginBottom={1}>\n Preview\n </Typography>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelPreview panelDefinition={panelDefinition} />\n </ErrorBoundary>\n </Grid>\n <Grid item xs={12}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <PanelSpecEditor\n control={form.control}\n panelDefinition={panelDefinition}\n onJSONChange={handlePanelDefinitionChange}\n onQueriesChange={(queries) => {\n setQueries(queries);\n }}\n onPluginSpecChange={(spec) => {\n pluginEditor.onSpecChange(spec);\n }}\n />\n </ErrorBoundary>\n </Grid>\n </Grid>\n </Box>\n <DiscardChangesConfirmationDialog\n description=\"You have unapplied changes in this panel. Are you sure you want to discard these changes? Changes cannot be recovered.\"\n isOpen={isDiscardDialogOpened}\n onCancel={() => {\n setDiscardDialogOpened(false);\n }}\n onDiscardChanges={() => {\n setDiscardDialogOpened(false);\n onClose();\n }}\n />\n </FormProvider>\n );\n}\n\n/**\n * The `id` attribute added to the `PanelEditorForm` component, allowing submit buttons to live outside the form.\n */\nexport const panelEditorFormId = 'panel-editor-form';\n"],"names":["useEffect","useState","Box","Button","Grid","MenuItem","Stack","TextField","Typography","DiscardChangesConfirmationDialog","ErrorAlert","ErrorBoundary","PluginKindSelect","usePluginEditor","PanelSpecEditor","getTitleAction","getSubmitText","useValidationSchemas","Controller","FormProvider","useForm","useWatch","zodResolver","useListPanelGroups","PanelPreview","usePanelEditor","PanelEditorForm","props","initialValues","initialAction","onSave","onClose","panelGroups","panelDefinition","setName","setDescription","setLinks","setQueries","setPlugin","setPanelDefinition","plugin","spec","isDiscardDialogOpened","setDiscardDialogOpened","panelEditorSchema","form","resolver","mode","defaultValues","pluginEditor","pluginTypes","value","selection","kind","type","onChange","setValue","onHideQueryEditorChange","isHidden","undefined","titleAction","submitText","links","control","name","processForm","data","handleCancel","JSON","stringify","getValues","handlePanelDefinitionChange","nextPanelDefStr","nextPanelDef","parse","pluginKind","pluginSpec","rememberCurrentSpecState","watchedName","watchedDescription","watchedPluginKind","sx","display","alignItems","padding","theme","spacing","borderBottom","palette","divider","variant","direction","marginLeft","disabled","formState","isValid","onClick","handleSubmit","color","id","panelEditorFormId","flex","overflowY","container","item","xs","render","field","fieldState","required","fullWidth","label","error","helperText","message","event","target","select","map","panelGroup","index","title","isLoading","onSelectionChange","marginBottom","FallbackComponent","onJSONChange","onQueriesChange","queries","onPluginSpecChange","onSpecChange","description","isOpen","onCancel","onDiscardChanges"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.tsx"],"sourcesContent":["// Copyright 2024 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 { ReactElement, useState } from 'react';\nimport { Checkbox, FormGroup, FormControlLabel, Typography } from '@mui/material';\nimport { useTimeRange } from '@perses-dev/plugin-system';\nimport { isRelativeTimeRange, SAVE_DEFAULTS_DIALOG_TEXT } from '@perses-dev/core';\nimport { Dialog } from '@perses-dev/components';\nimport { useSaveChangesConfirmationDialog, useVariableDefinitionActions } from '../../context';\n\nexport const SaveChangesConfirmationDialog = (): ReactElement => {\n const { saveChangesConfirmationDialog: dialog } = useSaveChangesConfirmationDialog();\n const isSavedDurationModified = dialog?.isSavedDurationModified ?? true;\n const isSavedVariableModified = dialog?.isSavedVariableModified ?? true;\n const [saveDefaultTimeRange, setSaveDefaultTimeRange] = useState(isSavedDurationModified);\n const [saveDefaultVariables, setSaveDefaultVariables] = useState(isSavedVariableModified);\n\n const { getSavedVariablesStatus } = useVariableDefinitionActions();\n const { modifiedVariableNames } = getSavedVariablesStatus();\n\n const isOpen = dialog !== undefined;\n\n const { timeRange } = useTimeRange();\n const currentTimeRangeText = isRelativeTimeRange(timeRange)\n ? `(Last ${timeRange.pastDuration})`\n : '(Absolute time ranges can not be saved)';\n\n const saveTimeRangeText = `Save current time range as new default ${currentTimeRangeText}`;\n\n const saveVariablesText = `Save current variable values as new default (${\n modifiedVariableNames.length > 0 ? modifiedVariableNames.join(', ') : 'No modified variables'\n })`;\n\n return (\n <Dialog open={isOpen}>\n {dialog !== undefined && (\n <>\n <Dialog.Header onClose={() => dialog.onCancel()}>Save Dashboard</Dialog.Header>\n\n <Dialog.Content>\n <Typography marginBottom={2}>{dialog.description || SAVE_DEFAULTS_DIALOG_TEXT}</Typography>\n <FormGroup>\n <FormControlLabel\n control={\n <Checkbox\n disabled={!isSavedDurationModified || !isRelativeTimeRange(timeRange)}\n checked={saveDefaultTimeRange && isSavedDurationModified && isRelativeTimeRange(timeRange)}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSaveDefaultTimeRange(e.target.checked)}\n />\n }\n label={saveTimeRangeText}\n />\n <FormControlLabel\n control={\n <Checkbox\n disabled={!isSavedVariableModified}\n checked={saveDefaultVariables && isSavedVariableModified}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSaveDefaultVariables(e.target.checked)}\n />\n }\n label={saveVariablesText}\n />\n </FormGroup>\n </Dialog.Content>\n\n <Dialog.Actions>\n <Dialog.PrimaryButton\n onClick={() => {\n return dialog.onSaveChanges(saveDefaultTimeRange, saveDefaultVariables);\n }}\n >\n Save Changes\n </Dialog.PrimaryButton>\n <Dialog.SecondaryButton onClick={() => dialog.onCancel()}>Cancel</Dialog.SecondaryButton>\n </Dialog.Actions>\n </>\n )}\n </Dialog>\n );\n};\n"],"names":["useState","Checkbox","FormGroup","FormControlLabel","Typography","useTimeRange","isRelativeTimeRange","SAVE_DEFAULTS_DIALOG_TEXT","Dialog","useSaveChangesConfirmationDialog","useVariableDefinitionActions","SaveChangesConfirmationDialog","saveChangesConfirmationDialog","dialog","isSavedDurationModified","isSavedVariableModified","saveDefaultTimeRange","setSaveDefaultTimeRange","saveDefaultVariables","setSaveDefaultVariables","getSavedVariablesStatus","modifiedVariableNames","isOpen","undefined","timeRange","currentTimeRangeText","pastDuration","saveTimeRangeText","saveVariablesText","length","join","open","Header","onClose","onCancel","Content","marginBottom","description","control","disabled","checked","onChange","e","target","label","Actions","PrimaryButton","onClick","onSaveChanges","SecondaryButton"],"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,SAAuBA,QAAQ,QAAQ,QAAQ;AAC/C,SAASC,QAAQ,EAAEC,SAAS,EAAEC,gBAAgB,EAAEC,UAAU,QAAQ,gBAAgB;AAClF,SAASC,YAAY,QAAQ,4BAA4B;AACzD,SAASC,mBAAmB,EAAEC,yBAAyB,QAAQ,mBAAmB;AAClF,SAASC,MAAM,QAAQ,yBAAyB;AAChD,SAASC,gCAAgC,EAAEC,4BAA4B,QAAQ,gBAAgB;AAE/F,OAAO,MAAMC,gCAAgC;IAC3C,MAAM,EAAEC,+BAA+BC,MAAM,EAAE,GAAGJ;IAClD,MAAMK,0BAA0BD,QAAQC,2BAA2B;IACnE,MAAMC,0BAA0BF,QAAQE,2BAA2B;IACnE,MAAM,CAACC,sBAAsBC,wBAAwB,GAAGjB,SAASc;IACjE,MAAM,CAACI,sBAAsBC,wBAAwB,GAAGnB,SAASe;IAEjE,MAAM,EAAEK,uBAAuB,EAAE,GAAGV;IACpC,MAAM,EAAEW,qBAAqB,EAAE,GAAGD;IAElC,MAAME,SAAST,WAAWU;IAE1B,MAAM,EAAEC,SAAS,EAAE,GAAGnB;IACtB,MAAMoB,uBAAuBnB,oBAAoBkB,aAC7C,CAAC,MAAM,EAAEA,UAAUE,YAAY,CAAC,CAAC,CAAC,GAClC;IAEJ,MAAMC,oBAAoB,CAAC,uCAAuC,EAAEF,qBAAqB,CAAC;IAE1F,MAAMG,oBAAoB,CAAC,6CAA6C,EACtEP,sBAAsBQ,MAAM,GAAG,IAAIR,sBAAsBS,IAAI,CAAC,QAAQ,wBACvE,CAAC,CAAC;IAEH,qBACE,KAACtB;QAAOuB,MAAMT;kBACXT,WAAWU,2BACV;;8BACE,KAACf,OAAOwB,MAAM;oBAACC,SAAS,IAAMpB,OAAOqB,QAAQ;8BAAI;;8BAEjD,MAAC1B,OAAO2B,OAAO;;sCACb,KAAC/B;4BAAWgC,cAAc;sCAAIvB,OAAOwB,WAAW,IAAI9B;;sCACpD,MAACL;;8CACC,KAACC;oCACCmC,uBACE,KAACrC;wCACCsC,UAAU,CAACzB,2BAA2B,CAACR,oBAAoBkB;wCAC3DgB,SAASxB,wBAAwBF,2BAA2BR,oBAAoBkB;wCAChFiB,UAAU,CAACC,IAA2CzB,wBAAwByB,EAAEC,MAAM,CAACH,OAAO;;oCAGlGI,OAAOjB;;8CAET,KAACxB;oCACCmC,uBACE,KAACrC;wCACCsC,UAAU,CAACxB;wCACXyB,SAAStB,wBAAwBH;wCACjC0B,UAAU,CAACC,IAA2CvB,wBAAwBuB,EAAEC,MAAM,CAACH,OAAO;;oCAGlGI,OAAOhB;;;;;;8BAKb,MAACpB,OAAOqC,OAAO;;sCACb,KAACrC,OAAOsC,aAAa;4BACnBC,SAAS;gCACP,OAAOlC,OAAOmC,aAAa,CAAChC,sBAAsBE;4BACpD;sCACD;;sCAGD,KAACV,OAAOyC,eAAe;4BAACF,SAAS,IAAMlC,OAAOqB,QAAQ;sCAAI;;;;;;;AAMtE,EAAE"}
1
+ {"version":3,"sources":["../../../src/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.tsx"],"sourcesContent":["// Copyright 2024 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 { ReactElement, useState } from 'react';\nimport { Checkbox, FormGroup, FormControlLabel, Typography } from '@mui/material';\nimport { useTimeRange } from '@perses-dev/plugin-system';\nimport { isRelativeTimeRange, SAVE_DEFAULTS_DIALOG_TEXT } from '@perses-dev/core';\nimport { Dialog } from '@perses-dev/components';\nimport { useSaveChangesConfirmationDialog, useVariableDefinitionActions } from '../../context';\n\nexport const SaveChangesConfirmationDialog = (): ReactElement => {\n const { saveChangesConfirmationDialog: dialog } = useSaveChangesConfirmationDialog();\n const isSavedDurationModified = dialog?.isSavedDurationModified ?? true;\n const isSavedVariableModified = dialog?.isSavedVariableModified ?? true;\n const [saveDefaultTimeRange, setSaveDefaultTimeRange] = useState(isSavedDurationModified);\n const [saveDefaultVariables, setSaveDefaultVariables] = useState(isSavedVariableModified);\n\n const { getSavedVariablesStatus } = useVariableDefinitionActions();\n const { modifiedVariableNames } = getSavedVariablesStatus();\n\n const isOpen = dialog !== undefined;\n\n const { timeRange } = useTimeRange();\n const currentTimeRangeText = isRelativeTimeRange(timeRange)\n ? `(Last ${timeRange.pastDuration})`\n : '(Absolute time ranges can not be saved)';\n\n const saveTimeRangeText = `Save current time range as new default ${currentTimeRangeText}`;\n\n const saveVariablesText = `Save current variable values as new default (${\n modifiedVariableNames.length > 0 ? modifiedVariableNames.join(', ') : 'No modified variables'\n })`;\n\n return (\n <Dialog open={isOpen}>\n {dialog !== undefined && (\n <>\n <Dialog.Header onClose={() => dialog.onCancel()}>Save Dashboard</Dialog.Header>\n\n <Dialog.Content>\n <Typography marginBottom={2}>{dialog.description || SAVE_DEFAULTS_DIALOG_TEXT}</Typography>\n <FormGroup>\n <FormControlLabel\n control={\n <Checkbox\n disabled={!isSavedDurationModified || !isRelativeTimeRange(timeRange)}\n checked={saveDefaultTimeRange && isSavedDurationModified && isRelativeTimeRange(timeRange)}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSaveDefaultTimeRange(e.target.checked)}\n />\n }\n label={saveTimeRangeText}\n />\n <FormControlLabel\n control={\n <Checkbox\n disabled={!isSavedVariableModified}\n checked={saveDefaultVariables && isSavedVariableModified}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => setSaveDefaultVariables(e.target.checked)}\n />\n }\n label={saveVariablesText}\n />\n </FormGroup>\n </Dialog.Content>\n\n <Dialog.Actions>\n <Dialog.PrimaryButton\n onClick={() => {\n return dialog.onSaveChanges(saveDefaultTimeRange, saveDefaultVariables);\n }}\n >\n Save Changes\n </Dialog.PrimaryButton>\n <Dialog.SecondaryButton onClick={() => dialog.onCancel()}>Cancel</Dialog.SecondaryButton>\n </Dialog.Actions>\n </>\n )}\n </Dialog>\n );\n};\n"],"names":["useState","Checkbox","FormGroup","FormControlLabel","Typography","useTimeRange","isRelativeTimeRange","SAVE_DEFAULTS_DIALOG_TEXT","Dialog","useSaveChangesConfirmationDialog","useVariableDefinitionActions","SaveChangesConfirmationDialog","saveChangesConfirmationDialog","dialog","isSavedDurationModified","isSavedVariableModified","saveDefaultTimeRange","setSaveDefaultTimeRange","saveDefaultVariables","setSaveDefaultVariables","getSavedVariablesStatus","modifiedVariableNames","isOpen","undefined","timeRange","currentTimeRangeText","pastDuration","saveTimeRangeText","saveVariablesText","length","join","open","Header","onClose","onCancel","Content","marginBottom","description","control","disabled","checked","onChange","e","target","label","Actions","PrimaryButton","onClick","onSaveChanges","SecondaryButton"],"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,SAAuBA,QAAQ,QAAQ,QAAQ;AAC/C,SAASC,QAAQ,EAAEC,SAAS,EAAEC,gBAAgB,EAAEC,UAAU,QAAQ,gBAAgB;AAClF,SAASC,YAAY,QAAQ,4BAA4B;AACzD,SAASC,mBAAmB,EAAEC,yBAAyB,QAAQ,mBAAmB;AAClF,SAASC,MAAM,QAAQ,yBAAyB;AAChD,SAASC,gCAAgC,EAAEC,4BAA4B,QAAQ,gBAAgB;AAE/F,OAAO,MAAMC,gCAAgC;IAC3C,MAAM,EAAEC,+BAA+BC,MAAM,EAAE,GAAGJ;IAClD,MAAMK,0BAA0BD,QAAQC,2BAA2B;IACnE,MAAMC,0BAA0BF,QAAQE,2BAA2B;IACnE,MAAM,CAACC,sBAAsBC,wBAAwB,GAAGjB,SAASc;IACjE,MAAM,CAACI,sBAAsBC,wBAAwB,GAAGnB,SAASe;IAEjE,MAAM,EAAEK,uBAAuB,EAAE,GAAGV;IACpC,MAAM,EAAEW,qBAAqB,EAAE,GAAGD;IAElC,MAAME,SAAST,WAAWU;IAE1B,MAAM,EAAEC,SAAS,EAAE,GAAGnB;IACtB,MAAMoB,uBAAuBnB,oBAAoBkB,aAC7C,CAAC,MAAM,EAAEA,UAAUE,YAAY,CAAC,CAAC,CAAC,GAClC;IAEJ,MAAMC,oBAAoB,CAAC,uCAAuC,EAAEF,sBAAsB;IAE1F,MAAMG,oBAAoB,CAAC,6CAA6C,EACtEP,sBAAsBQ,MAAM,GAAG,IAAIR,sBAAsBS,IAAI,CAAC,QAAQ,wBACvE,CAAC,CAAC;IAEH,qBACE,KAACtB;QAAOuB,MAAMT;kBACXT,WAAWU,2BACV;;8BACE,KAACf,OAAOwB,MAAM;oBAACC,SAAS,IAAMpB,OAAOqB,QAAQ;8BAAI;;8BAEjD,MAAC1B,OAAO2B,OAAO;;sCACb,KAAC/B;4BAAWgC,cAAc;sCAAIvB,OAAOwB,WAAW,IAAI9B;;sCACpD,MAACL;;8CACC,KAACC;oCACCmC,uBACE,KAACrC;wCACCsC,UAAU,CAACzB,2BAA2B,CAACR,oBAAoBkB;wCAC3DgB,SAASxB,wBAAwBF,2BAA2BR,oBAAoBkB;wCAChFiB,UAAU,CAACC,IAA2CzB,wBAAwByB,EAAEC,MAAM,CAACH,OAAO;;oCAGlGI,OAAOjB;;8CAET,KAACxB;oCACCmC,uBACE,KAACrC;wCACCsC,UAAU,CAACxB;wCACXyB,SAAStB,wBAAwBH;wCACjC0B,UAAU,CAACC,IAA2CvB,wBAAwBuB,EAAEC,MAAM,CAACH,OAAO;;oCAGlGI,OAAOhB;;;;;;8BAKb,MAACpB,OAAOqC,OAAO;;sCACb,KAACrC,OAAOsC,aAAa;4BACnBC,SAAS;gCACP,OAAOlC,OAAOmC,aAAa,CAAChC,sBAAsBE;4BACpD;sCACD;;sCAGD,KAACV,OAAOyC,eAAe;4BAACF,SAAS,IAAMlC,OAAOqB,QAAQ;sCAAI;;;;;;;AAMtE,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/SaveDashboardButton/SaveDashboardButton.tsx"],"sourcesContent":["// Copyright 2024 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 { ReactElement, useState } from 'react';\nimport { Button, ButtonProps } from '@mui/material';\nimport { isRelativeTimeRange } from '@perses-dev/core';\nimport { useTimeRange } from '@perses-dev/plugin-system';\nimport {\n OnSaveDashboard,\n useDashboard,\n useEditMode,\n useSaveChangesConfirmationDialog,\n useVariableDefinitionActions,\n} from '../../context';\n\nexport interface SaveDashboardButtonProps extends Pick<ButtonProps, 'fullWidth'> {\n onSave?: OnSaveDashboard;\n isDisabled: boolean;\n variant?: 'contained' | 'text' | 'outlined';\n}\n\nexport const SaveDashboardButton = ({\n onSave,\n isDisabled,\n variant = 'contained',\n}: SaveDashboardButtonProps): ReactElement => {\n const [isSavingDashboard, setSavingDashboard] = useState<boolean>(false);\n const { dashboard, setDashboard } = useDashboard();\n const { getSavedVariablesStatus, setVariableDefaultValues } = useVariableDefinitionActions();\n const { isSavedVariableModified } = getSavedVariablesStatus();\n const { timeRange } = useTimeRange();\n const { setEditMode } = useEditMode();\n const { openSaveChangesConfirmationDialog, closeSaveChangesConfirmationDialog } = useSaveChangesConfirmationDialog();\n\n const onSaveButtonClick = (): void => {\n const isSavedDurationModified =\n isRelativeTimeRange(timeRange) && dashboard.spec.duration !== timeRange.pastDuration;\n\n // Save dashboard\n // - if active timeRange from plugin-system is relative and different from currently saved\n // - or if the saved variables are different from currently saved\n if (isSavedDurationModified || isSavedVariableModified) {\n openSaveChangesConfirmationDialog({\n onSaveChanges: (saveDefaultTimeRange, saveDefaultVariables) => {\n if (isRelativeTimeRange(timeRange) && saveDefaultTimeRange === true) {\n dashboard.spec.duration = timeRange.pastDuration;\n }\n if (saveDefaultVariables === true) {\n const variables = setVariableDefaultValues();\n dashboard.spec.variables = variables;\n }\n setDashboard(dashboard);\n saveDashboard();\n },\n onCancel: () => {\n closeSaveChangesConfirmationDialog();\n },\n isSavedDurationModified,\n isSavedVariableModified,\n });\n } else {\n saveDashboard();\n }\n };\n\n const saveDashboard = async (): Promise<void> => {\n if (onSave) {\n try {\n setSavingDashboard(true);\n await onSave(dashboard);\n closeSaveChangesConfirmationDialog();\n setEditMode(false);\n } catch (error) {\n throw new Error(`An error occurred while saving the dashboard. ${error}`);\n } finally {\n setSavingDashboard(false);\n }\n } else {\n setEditMode(false);\n }\n };\n\n return (\n <Button variant={variant} onClick={onSaveButtonClick} disabled={isDisabled || isSavingDashboard}>\n Save\n </Button>\n );\n};\n"],"names":["useState","Button","isRelativeTimeRange","useTimeRange","useDashboard","useEditMode","useSaveChangesConfirmationDialog","useVariableDefinitionActions","SaveDashboardButton","onSave","isDisabled","variant","isSavingDashboard","setSavingDashboard","dashboard","setDashboard","getSavedVariablesStatus","setVariableDefaultValues","isSavedVariableModified","timeRange","setEditMode","openSaveChangesConfirmationDialog","closeSaveChangesConfirmationDialog","onSaveButtonClick","isSavedDurationModified","spec","duration","pastDuration","onSaveChanges","saveDefaultTimeRange","saveDefaultVariables","variables","saveDashboard","onCancel","error","Error","onClick","disabled"],"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,SAAuBA,QAAQ,QAAQ,QAAQ;AAC/C,SAASC,MAAM,QAAqB,gBAAgB;AACpD,SAASC,mBAAmB,QAAQ,mBAAmB;AACvD,SAASC,YAAY,QAAQ,4BAA4B;AACzD,SAEEC,YAAY,EACZC,WAAW,EACXC,gCAAgC,EAChCC,4BAA4B,QACvB,gBAAgB;AAQvB,OAAO,MAAMC,sBAAsB,CAAC,EAClCC,MAAM,EACNC,UAAU,EACVC,UAAU,WAAW,EACI;IACzB,MAAM,CAACC,mBAAmBC,mBAAmB,GAAGb,SAAkB;IAClE,MAAM,EAAEc,SAAS,EAAEC,YAAY,EAAE,GAAGX;IACpC,MAAM,EAAEY,uBAAuB,EAAEC,wBAAwB,EAAE,GAAGV;IAC9D,MAAM,EAAEW,uBAAuB,EAAE,GAAGF;IACpC,MAAM,EAAEG,SAAS,EAAE,GAAGhB;IACtB,MAAM,EAAEiB,WAAW,EAAE,GAAGf;IACxB,MAAM,EAAEgB,iCAAiC,EAAEC,kCAAkC,EAAE,GAAGhB;IAElF,MAAMiB,oBAAoB;QACxB,MAAMC,0BACJtB,oBAAoBiB,cAAcL,UAAUW,IAAI,CAACC,QAAQ,KAAKP,UAAUQ,YAAY;QAEtF,iBAAiB;QACjB,0FAA0F;QAC1F,iEAAiE;QACjE,IAAIH,2BAA2BN,yBAAyB;YACtDG,kCAAkC;gBAChCO,eAAe,CAACC,sBAAsBC;oBACpC,IAAI5B,oBAAoBiB,cAAcU,yBAAyB,MAAM;wBACnEf,UAAUW,IAAI,CAACC,QAAQ,GAAGP,UAAUQ,YAAY;oBAClD;oBACA,IAAIG,yBAAyB,MAAM;wBACjC,MAAMC,YAAYd;wBAClBH,UAAUW,IAAI,CAACM,SAAS,GAAGA;oBAC7B;oBACAhB,aAAaD;oBACbkB;gBACF;gBACAC,UAAU;oBACRX;gBACF;gBACAE;gBACAN;YACF;QACF,OAAO;YACLc;QACF;IACF;IAEA,MAAMA,gBAAgB;QACpB,IAAIvB,QAAQ;YACV,IAAI;gBACFI,mBAAmB;gBACnB,MAAMJ,OAAOK;gBACbQ;gBACAF,YAAY;YACd,EAAE,OAAOc,OAAO;gBACd,MAAM,IAAIC,MAAM,CAAC,8CAA8C,EAAED,MAAM,CAAC;YAC1E,SAAU;gBACRrB,mBAAmB;YACrB;QACF,OAAO;YACLO,YAAY;QACd;IACF;IAEA,qBACE,KAACnB;QAAOU,SAASA;QAASyB,SAASb;QAAmBc,UAAU3B,cAAcE;kBAAmB;;AAIrG,EAAE"}
1
+ {"version":3,"sources":["../../../src/components/SaveDashboardButton/SaveDashboardButton.tsx"],"sourcesContent":["// Copyright 2024 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 { ReactElement, useState } from 'react';\nimport { Button, ButtonProps } from '@mui/material';\nimport { isRelativeTimeRange } from '@perses-dev/core';\nimport { useTimeRange } from '@perses-dev/plugin-system';\nimport {\n OnSaveDashboard,\n useDashboard,\n useEditMode,\n useSaveChangesConfirmationDialog,\n useVariableDefinitionActions,\n} from '../../context';\n\nexport interface SaveDashboardButtonProps extends Pick<ButtonProps, 'fullWidth'> {\n onSave?: OnSaveDashboard;\n isDisabled: boolean;\n variant?: 'contained' | 'text' | 'outlined';\n}\n\nexport const SaveDashboardButton = ({\n onSave,\n isDisabled,\n variant = 'contained',\n}: SaveDashboardButtonProps): ReactElement => {\n const [isSavingDashboard, setSavingDashboard] = useState<boolean>(false);\n const { dashboard, setDashboard } = useDashboard();\n const { getSavedVariablesStatus, setVariableDefaultValues } = useVariableDefinitionActions();\n const { isSavedVariableModified } = getSavedVariablesStatus();\n const { timeRange } = useTimeRange();\n const { setEditMode } = useEditMode();\n const { openSaveChangesConfirmationDialog, closeSaveChangesConfirmationDialog } = useSaveChangesConfirmationDialog();\n\n const onSaveButtonClick = (): void => {\n const isSavedDurationModified =\n isRelativeTimeRange(timeRange) && dashboard.spec.duration !== timeRange.pastDuration;\n\n // Save dashboard\n // - if active timeRange from plugin-system is relative and different from currently saved\n // - or if the saved variables are different from currently saved\n if (isSavedDurationModified || isSavedVariableModified) {\n openSaveChangesConfirmationDialog({\n onSaveChanges: (saveDefaultTimeRange, saveDefaultVariables) => {\n if (isRelativeTimeRange(timeRange) && saveDefaultTimeRange === true) {\n dashboard.spec.duration = timeRange.pastDuration;\n }\n if (saveDefaultVariables === true) {\n const variables = setVariableDefaultValues();\n dashboard.spec.variables = variables;\n }\n setDashboard(dashboard);\n saveDashboard();\n },\n onCancel: () => {\n closeSaveChangesConfirmationDialog();\n },\n isSavedDurationModified,\n isSavedVariableModified,\n });\n } else {\n saveDashboard();\n }\n };\n\n const saveDashboard = async (): Promise<void> => {\n if (onSave) {\n try {\n setSavingDashboard(true);\n await onSave(dashboard);\n closeSaveChangesConfirmationDialog();\n setEditMode(false);\n } catch (error) {\n throw new Error(`An error occurred while saving the dashboard. ${error}`);\n } finally {\n setSavingDashboard(false);\n }\n } else {\n setEditMode(false);\n }\n };\n\n return (\n <Button variant={variant} onClick={onSaveButtonClick} disabled={isDisabled || isSavingDashboard}>\n Save\n </Button>\n );\n};\n"],"names":["useState","Button","isRelativeTimeRange","useTimeRange","useDashboard","useEditMode","useSaveChangesConfirmationDialog","useVariableDefinitionActions","SaveDashboardButton","onSave","isDisabled","variant","isSavingDashboard","setSavingDashboard","dashboard","setDashboard","getSavedVariablesStatus","setVariableDefaultValues","isSavedVariableModified","timeRange","setEditMode","openSaveChangesConfirmationDialog","closeSaveChangesConfirmationDialog","onSaveButtonClick","isSavedDurationModified","spec","duration","pastDuration","onSaveChanges","saveDefaultTimeRange","saveDefaultVariables","variables","saveDashboard","onCancel","error","Error","onClick","disabled"],"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,SAAuBA,QAAQ,QAAQ,QAAQ;AAC/C,SAASC,MAAM,QAAqB,gBAAgB;AACpD,SAASC,mBAAmB,QAAQ,mBAAmB;AACvD,SAASC,YAAY,QAAQ,4BAA4B;AACzD,SAEEC,YAAY,EACZC,WAAW,EACXC,gCAAgC,EAChCC,4BAA4B,QACvB,gBAAgB;AAQvB,OAAO,MAAMC,sBAAsB,CAAC,EAClCC,MAAM,EACNC,UAAU,EACVC,UAAU,WAAW,EACI;IACzB,MAAM,CAACC,mBAAmBC,mBAAmB,GAAGb,SAAkB;IAClE,MAAM,EAAEc,SAAS,EAAEC,YAAY,EAAE,GAAGX;IACpC,MAAM,EAAEY,uBAAuB,EAAEC,wBAAwB,EAAE,GAAGV;IAC9D,MAAM,EAAEW,uBAAuB,EAAE,GAAGF;IACpC,MAAM,EAAEG,SAAS,EAAE,GAAGhB;IACtB,MAAM,EAAEiB,WAAW,EAAE,GAAGf;IACxB,MAAM,EAAEgB,iCAAiC,EAAEC,kCAAkC,EAAE,GAAGhB;IAElF,MAAMiB,oBAAoB;QACxB,MAAMC,0BACJtB,oBAAoBiB,cAAcL,UAAUW,IAAI,CAACC,QAAQ,KAAKP,UAAUQ,YAAY;QAEtF,iBAAiB;QACjB,0FAA0F;QAC1F,iEAAiE;QACjE,IAAIH,2BAA2BN,yBAAyB;YACtDG,kCAAkC;gBAChCO,eAAe,CAACC,sBAAsBC;oBACpC,IAAI5B,oBAAoBiB,cAAcU,yBAAyB,MAAM;wBACnEf,UAAUW,IAAI,CAACC,QAAQ,GAAGP,UAAUQ,YAAY;oBAClD;oBACA,IAAIG,yBAAyB,MAAM;wBACjC,MAAMC,YAAYd;wBAClBH,UAAUW,IAAI,CAACM,SAAS,GAAGA;oBAC7B;oBACAhB,aAAaD;oBACbkB;gBACF;gBACAC,UAAU;oBACRX;gBACF;gBACAE;gBACAN;YACF;QACF,OAAO;YACLc;QACF;IACF;IAEA,MAAMA,gBAAgB;QACpB,IAAIvB,QAAQ;YACV,IAAI;gBACFI,mBAAmB;gBACnB,MAAMJ,OAAOK;gBACbQ;gBACAF,YAAY;YACd,EAAE,OAAOc,OAAO;gBACd,MAAM,IAAIC,MAAM,CAAC,8CAA8C,EAAED,OAAO;YAC1E,SAAU;gBACRrB,mBAAmB;YACrB;QACF,OAAO;YACLO,YAAY;QACd;IACF;IAEA,qBACE,KAACnB;QAAOU,SAASA;QAASyB,SAASb;QAAmBc,UAAU3B,cAAcE;kBAAmB;;AAIrG,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Variables/BuiltinVariableAccordions.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 { BuiltinVariableDefinition } from '@perses-dev/core';\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Typography,\n} from '@mui/material';\nimport ExpandMoreIcon from 'mdi-material-ui/ChevronUp';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { ReactElement, useMemo } from 'react';\n\ntype BuiltinVariableAccordionsProps = {\n builtinVariableDefinitions: BuiltinVariableDefinition[];\n};\n\nexport function BuiltinVariableAccordions({\n builtinVariableDefinitions,\n}: BuiltinVariableAccordionsProps): ReactElement {\n const builtinVariablesBySource = useMemo(() => {\n const result: Record<string, BuiltinVariableDefinition[]> = {};\n for (const definition of builtinVariableDefinitions) {\n const value = result[definition.spec.source];\n if (value) {\n value.push(definition);\n continue;\n }\n result[definition.spec.source] = [definition];\n }\n return result;\n }, [builtinVariableDefinitions]);\n\n const sources = useMemo(() => {\n const result: string[] = [];\n for (const source in builtinVariablesBySource) {\n if (!result.includes(source)) {\n result.push(source);\n }\n }\n return result;\n }, [builtinVariablesBySource]);\n\n return (\n <>\n {sources.map((source) => (\n <Accordion\n key={source}\n sx={(theme) => ({\n '.MuiAccordionSummary-root': {\n backgroundColor: theme.palette.background.lighter,\n },\n '.MuiAccordionDetails-root': {\n backgroundColor: theme.palette.background.lighter,\n },\n })}\n >\n <AccordionSummary expandIcon={<ExpandMoreIcon />} aria-controls=\"builtin\" id=\"builtin\">\n <Typography variant=\"h2\">\n <InfoTooltip\n title={`${source} Built-in Variables`}\n description=\"Variables computed during dashboard rendering.\"\n >\n <span>{source} Built-in Variables</span>\n </InfoTooltip>\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <TableContainer>\n <Table sx={{ minWidth: 650 }} aria-label=\"table of external variables\">\n <TableHead>\n <TableRow>\n <TableCell>Name</TableCell>\n <TableCell>Description</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {(builtinVariablesBySource[source] ?? []).map((v) => (\n <TableRow key={source + '-' + v.spec.name}>\n <TableCell component=\"th\" scope=\"row\" sx={{ fontWeight: 'bold' }}>\n {v.spec.name}\n </TableCell>\n <TableCell>{v.spec.display?.description ?? ''}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </AccordionDetails>\n </Accordion>\n ))}\n </>\n );\n}\n"],"names":["Accordion","AccordionDetails","AccordionSummary","Table","TableBody","TableCell","TableContainer","TableHead","TableRow","Typography","ExpandMoreIcon","InfoTooltip","useMemo","BuiltinVariableAccordions","builtinVariableDefinitions","builtinVariablesBySource","result","definition","value","spec","source","push","sources","includes","map","sx","theme","backgroundColor","palette","background","lighter","expandIcon","aria-controls","id","variant","title","description","span","minWidth","aria-label","v","component","scope","fontWeight","name","display"],"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;;AAGjC,SACEA,SAAS,EACTC,gBAAgB,EAChBC,gBAAgB,EAChBC,KAAK,EACLC,SAAS,EACTC,SAAS,EACTC,cAAc,EACdC,SAAS,EACTC,QAAQ,EACRC,UAAU,QACL,gBAAgB;AACvB,OAAOC,oBAAoB,4BAA4B;AACvD,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAAuBC,OAAO,QAAQ,QAAQ;AAM9C,OAAO,SAASC,0BAA0B,EACxCC,0BAA0B,EACK;IAC/B,MAAMC,2BAA2BH,QAAQ;QACvC,MAAMI,SAAsD,CAAC;QAC7D,KAAK,MAAMC,cAAcH,2BAA4B;YACnD,MAAMI,QAAQF,MAAM,CAACC,WAAWE,IAAI,CAACC,MAAM,CAAC;YAC5C,IAAIF,OAAO;gBACTA,MAAMG,IAAI,CAACJ;gBACX;YACF;YACAD,MAAM,CAACC,WAAWE,IAAI,CAACC,MAAM,CAAC,GAAG;gBAACH;aAAW;QAC/C;QACA,OAAOD;IACT,GAAG;QAACF;KAA2B;IAE/B,MAAMQ,UAAUV,QAAQ;QACtB,MAAMI,SAAmB,EAAE;QAC3B,IAAK,MAAMI,UAAUL,yBAA0B;YAC7C,IAAI,CAACC,OAAOO,QAAQ,CAACH,SAAS;gBAC5BJ,OAAOK,IAAI,CAACD;YACd;QACF;QACA,OAAOJ;IACT,GAAG;QAACD;KAAyB;IAE7B,qBACE;kBACGO,QAAQE,GAAG,CAAC,CAACJ,uBACZ,MAACpB;gBAECyB,IAAI,CAACC,QAAW,CAAA;wBACd,6BAA6B;4BAC3BC,iBAAiBD,MAAME,OAAO,CAACC,UAAU,CAACC,OAAO;wBACnD;wBACA,6BAA6B;4BAC3BH,iBAAiBD,MAAME,OAAO,CAACC,UAAU,CAACC,OAAO;wBACnD;oBACF,CAAA;;kCAEA,KAAC5B;wBAAiB6B,0BAAY,KAACrB;wBAAmBsB,iBAAc;wBAAUC,IAAG;kCAC3E,cAAA,KAACxB;4BAAWyB,SAAQ;sCAClB,cAAA,KAACvB;gCACCwB,OAAO,CAAC,EAAEf,OAAO,mBAAmB,CAAC;gCACrCgB,aAAY;0CAEZ,cAAA,MAACC;;wCAAMjB;wCAAO;;;;;;kCAIpB,KAACnB;kCACC,cAAA,KAACK;sCACC,cAAA,MAACH;gCAAMsB,IAAI;oCAAEa,UAAU;gCAAI;gCAAGC,cAAW;;kDACvC,KAAChC;kDACC,cAAA,MAACC;;8DACC,KAACH;8DAAU;;8DACX,KAACA;8DAAU;;;;;kDAGf,KAACD;kDACE,AAACW,CAAAA,wBAAwB,CAACK,OAAO,IAAI,EAAE,AAAD,EAAGI,GAAG,CAAC,CAACgB,kBAC7C,MAAChC;;kEACC,KAACH;wDAAUoC,WAAU;wDAAKC,OAAM;wDAAMjB,IAAI;4DAAEkB,YAAY;wDAAO;kEAC5DH,EAAErB,IAAI,CAACyB,IAAI;;kEAEd,KAACvC;kEAAWmC,EAAErB,IAAI,CAAC0B,OAAO,EAAET,eAAe;;;+CAJ9BhB,SAAS,MAAMoB,EAAErB,IAAI,CAACyB,IAAI;;;;;;;eA/B9CxB;;AA8Cf"}
1
+ {"version":3,"sources":["../../../src/components/Variables/BuiltinVariableAccordions.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 { BuiltinVariableDefinition } from '@perses-dev/core';\nimport {\n Accordion,\n AccordionDetails,\n AccordionSummary,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n Typography,\n} from '@mui/material';\nimport ExpandMoreIcon from 'mdi-material-ui/ChevronUp';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { ReactElement, useMemo } from 'react';\n\ntype BuiltinVariableAccordionsProps = {\n builtinVariableDefinitions: BuiltinVariableDefinition[];\n};\n\nexport function BuiltinVariableAccordions({\n builtinVariableDefinitions,\n}: BuiltinVariableAccordionsProps): ReactElement {\n const builtinVariablesBySource = useMemo(() => {\n const result: Record<string, BuiltinVariableDefinition[]> = {};\n for (const definition of builtinVariableDefinitions) {\n const value = result[definition.spec.source];\n if (value) {\n value.push(definition);\n continue;\n }\n result[definition.spec.source] = [definition];\n }\n return result;\n }, [builtinVariableDefinitions]);\n\n const sources = useMemo(() => {\n const result: string[] = [];\n for (const source in builtinVariablesBySource) {\n if (!result.includes(source)) {\n result.push(source);\n }\n }\n return result;\n }, [builtinVariablesBySource]);\n\n return (\n <>\n {sources.map((source) => (\n <Accordion\n key={source}\n sx={(theme) => ({\n '.MuiAccordionSummary-root': {\n backgroundColor: theme.palette.background.lighter,\n },\n '.MuiAccordionDetails-root': {\n backgroundColor: theme.palette.background.lighter,\n },\n })}\n >\n <AccordionSummary expandIcon={<ExpandMoreIcon />} aria-controls=\"builtin\" id=\"builtin\">\n <Typography variant=\"h2\">\n <InfoTooltip\n title={`${source} Built-in Variables`}\n description=\"Variables computed during dashboard rendering.\"\n >\n <span>{source} Built-in Variables</span>\n </InfoTooltip>\n </Typography>\n </AccordionSummary>\n <AccordionDetails>\n <TableContainer>\n <Table sx={{ minWidth: 650 }} aria-label=\"table of external variables\">\n <TableHead>\n <TableRow>\n <TableCell>Name</TableCell>\n <TableCell>Description</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {(builtinVariablesBySource[source] ?? []).map((v) => (\n <TableRow key={source + '-' + v.spec.name}>\n <TableCell component=\"th\" scope=\"row\" sx={{ fontWeight: 'bold' }}>\n {v.spec.name}\n </TableCell>\n <TableCell>{v.spec.display?.description ?? ''}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </TableContainer>\n </AccordionDetails>\n </Accordion>\n ))}\n </>\n );\n}\n"],"names":["Accordion","AccordionDetails","AccordionSummary","Table","TableBody","TableCell","TableContainer","TableHead","TableRow","Typography","ExpandMoreIcon","InfoTooltip","useMemo","BuiltinVariableAccordions","builtinVariableDefinitions","builtinVariablesBySource","result","definition","value","spec","source","push","sources","includes","map","sx","theme","backgroundColor","palette","background","lighter","expandIcon","aria-controls","id","variant","title","description","span","minWidth","aria-label","v","component","scope","fontWeight","name","display"],"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;;AAGjC,SACEA,SAAS,EACTC,gBAAgB,EAChBC,gBAAgB,EAChBC,KAAK,EACLC,SAAS,EACTC,SAAS,EACTC,cAAc,EACdC,SAAS,EACTC,QAAQ,EACRC,UAAU,QACL,gBAAgB;AACvB,OAAOC,oBAAoB,4BAA4B;AACvD,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAAuBC,OAAO,QAAQ,QAAQ;AAM9C,OAAO,SAASC,0BAA0B,EACxCC,0BAA0B,EACK;IAC/B,MAAMC,2BAA2BH,QAAQ;QACvC,MAAMI,SAAsD,CAAC;QAC7D,KAAK,MAAMC,cAAcH,2BAA4B;YACnD,MAAMI,QAAQF,MAAM,CAACC,WAAWE,IAAI,CAACC,MAAM,CAAC;YAC5C,IAAIF,OAAO;gBACTA,MAAMG,IAAI,CAACJ;gBACX;YACF;YACAD,MAAM,CAACC,WAAWE,IAAI,CAACC,MAAM,CAAC,GAAG;gBAACH;aAAW;QAC/C;QACA,OAAOD;IACT,GAAG;QAACF;KAA2B;IAE/B,MAAMQ,UAAUV,QAAQ;QACtB,MAAMI,SAAmB,EAAE;QAC3B,IAAK,MAAMI,UAAUL,yBAA0B;YAC7C,IAAI,CAACC,OAAOO,QAAQ,CAACH,SAAS;gBAC5BJ,OAAOK,IAAI,CAACD;YACd;QACF;QACA,OAAOJ;IACT,GAAG;QAACD;KAAyB;IAE7B,qBACE;kBACGO,QAAQE,GAAG,CAAC,CAACJ,uBACZ,MAACpB;gBAECyB,IAAI,CAACC,QAAW,CAAA;wBACd,6BAA6B;4BAC3BC,iBAAiBD,MAAME,OAAO,CAACC,UAAU,CAACC,OAAO;wBACnD;wBACA,6BAA6B;4BAC3BH,iBAAiBD,MAAME,OAAO,CAACC,UAAU,CAACC,OAAO;wBACnD;oBACF,CAAA;;kCAEA,KAAC5B;wBAAiB6B,0BAAY,KAACrB;wBAAmBsB,iBAAc;wBAAUC,IAAG;kCAC3E,cAAA,KAACxB;4BAAWyB,SAAQ;sCAClB,cAAA,KAACvB;gCACCwB,OAAO,GAAGf,OAAO,mBAAmB,CAAC;gCACrCgB,aAAY;0CAEZ,cAAA,MAACC;;wCAAMjB;wCAAO;;;;;;kCAIpB,KAACnB;kCACC,cAAA,KAACK;sCACC,cAAA,MAACH;gCAAMsB,IAAI;oCAAEa,UAAU;gCAAI;gCAAGC,cAAW;;kDACvC,KAAChC;kDACC,cAAA,MAACC;;8DACC,KAACH;8DAAU;;8DACX,KAACA;8DAAU;;;;;kDAGf,KAACD;kDACE,AAACW,CAAAA,wBAAwB,CAACK,OAAO,IAAI,EAAE,AAAD,EAAGI,GAAG,CAAC,CAACgB,kBAC7C,MAAChC;;kEACC,KAACH;wDAAUoC,WAAU;wDAAKC,OAAM;wDAAMjB,IAAI;4DAAEkB,YAAY;wDAAO;kEAC5DH,EAAErB,IAAI,CAACyB,IAAI;;kEAEd,KAACvC;kEAAWmC,EAAErB,IAAI,CAAC0B,OAAO,EAAET,eAAe;;;+CAJ9BhB,SAAS,MAAMoB,EAAErB,IAAI,CAACyB,IAAI;;;;;;;eA/B9CxB;;AA8Cf"}
@@ -191,6 +191,8 @@ function ListVariable({ name, source }) {
191
191
  const { setVariableValue, setVariableLoading, setVariableOptions } = useVariableDefinitionActions();
192
192
  const { selectedOptions, value, loading, options, viewOptions } = useListVariableState(definition?.spec, ctx.state, variablesOptionsQuery);
193
193
  const [inputWidth, setInputWidth] = useState(MIN_VARIABLE_WIDTH);
194
+ // Used for multiple value variables, it will not clear variable input when selecting an option
195
+ const [inputValue, setInputValue] = useState('');
194
196
  const title = definition?.spec.display?.name ?? name;
195
197
  const allowMultiple = definition?.spec.allowMultiple === true;
196
198
  const allowAllValue = definition?.spec.allowAllValue === true;
@@ -241,7 +243,8 @@ function ListVariable({ name, source }) {
241
243
  renderInput: (params)=>{
242
244
  return allowMultiple ? /*#__PURE__*/ _jsx(TextField, {
243
245
  ...params,
244
- label: title
246
+ label: title,
247
+ onChange: (e)=>setInputValue(e.target.value)
245
248
  }) : /*#__PURE__*/ _jsx(TextField, {
246
249
  ...params,
247
250
  label: title,
@@ -266,11 +269,17 @@ function ListVariable({ name, source }) {
266
269
  setVariableValue(name, variableOptionToVariableValue(value), source);
267
270
  }
268
271
  },
272
+ inputValue: allowMultiple ? inputValue : undefined,
269
273
  onInputChange: (_, newInputValue)=>{
270
274
  if (!allowMultiple) {
271
275
  setInputWidth(getWidthPx(newInputValue, 'list'));
272
276
  }
273
277
  },
278
+ onBlur: ()=>{
279
+ if (allowMultiple) {
280
+ setInputValue('');
281
+ }
282
+ },
274
283
  options: viewOptions
275
284
  }),
276
285
  loading && /*#__PURE__*/ _jsx(LinearProgress, {})