@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.
- package/dist/cjs/components/DashboardToolbar/DashboardToolbar.js +3 -3
- package/dist/cjs/components/DeletePanelDialog/DeletePanelDialog.js +2 -0
- package/dist/cjs/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +2 -0
- package/dist/cjs/components/DownloadButton/DownloadButton.js +135 -29
- package/dist/cjs/components/GridLayout/GridItemContent.js +3 -2
- package/dist/cjs/components/GridLayout/GridLayout.js +6 -10
- package/dist/cjs/components/Panel/Panel.js +6 -2
- package/dist/cjs/components/Panel/PanelActions.js +204 -55
- package/dist/cjs/components/Panel/PanelContent.js +56 -10
- package/dist/cjs/components/Panel/PanelHeader.js +10 -46
- package/dist/cjs/components/Panel/PanelPluginLoader.js +56 -0
- package/dist/cjs/components/Panel/index.js +1 -0
- package/dist/cjs/components/PanelDrawer/PanelEditorForm.js +21 -9
- package/dist/cjs/components/Variables/Variable.js +10 -1
- package/dist/cjs/constants/styles.js +7 -3
- package/dist/cjs/constants/user-interface-text.js +1 -2
- package/dist/cjs/context/DashboardProvider/dashboard-provider-api.js +12 -1
- package/dist/cjs/context/VariableProvider/VariableProvider.js +16 -20
- package/dist/cjs/test/datasource-provider.js +1 -1
- package/dist/cjs/test/plugin-registry.js +4 -1
- package/dist/cjs/views/ViewDashboard/DashboardApp.js +3 -1
- package/dist/cjs/views/ViewDashboard/ViewDashboard.js +3 -1
- package/dist/components/DashboardToolbar/DashboardToolbar.d.ts +2 -0
- package/dist/components/DashboardToolbar/DashboardToolbar.d.ts.map +1 -1
- package/dist/components/DashboardToolbar/DashboardToolbar.js +3 -3
- package/dist/components/DashboardToolbar/DashboardToolbar.js.map +1 -1
- package/dist/components/Datasources/DatasourceEditor.js.map +1 -1
- package/dist/components/DeletePanelDialog/DeletePanelDialog.js +3 -1
- package/dist/components/DeletePanelDialog/DeletePanelDialog.js.map +1 -1
- package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.d.ts.map +1 -1
- package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js +3 -1
- package/dist/components/DeletePanelGroupDialog/DeletePanelGroupDialog.js.map +1 -1
- package/dist/components/DownloadButton/DownloadButton.d.ts +1 -5
- package/dist/components/DownloadButton/DownloadButton.d.ts.map +1 -1
- package/dist/components/DownloadButton/DownloadButton.js +94 -29
- package/dist/components/DownloadButton/DownloadButton.js.map +1 -1
- package/dist/components/GridLayout/GridContainer.js.map +1 -1
- package/dist/components/GridLayout/GridItemContent.d.ts.map +1 -1
- package/dist/components/GridLayout/GridItemContent.js +4 -3
- package/dist/components/GridLayout/GridItemContent.js.map +1 -1
- package/dist/components/GridLayout/GridLayout.d.ts.map +1 -1
- package/dist/components/GridLayout/GridLayout.js +8 -12
- package/dist/components/GridLayout/GridLayout.js.map +1 -1
- package/dist/components/GridLayout/GridTitle.js.map +1 -1
- package/dist/components/Panel/HeaderIconButton.d.ts +1 -1
- package/dist/components/Panel/HeaderIconButton.d.ts.map +1 -1
- package/dist/components/Panel/Panel.d.ts +5 -0
- package/dist/components/Panel/Panel.d.ts.map +1 -1
- package/dist/components/Panel/Panel.js +11 -2
- package/dist/components/Panel/Panel.js.map +1 -1
- package/dist/components/Panel/PanelActions.d.ts +8 -2
- package/dist/components/Panel/PanelActions.d.ts.map +1 -1
- package/dist/components/Panel/PanelActions.js +208 -59
- package/dist/components/Panel/PanelActions.js.map +1 -1
- package/dist/components/Panel/PanelContent.d.ts +5 -4
- package/dist/components/Panel/PanelContent.d.ts.map +1 -1
- package/dist/components/Panel/PanelContent.js +58 -12
- package/dist/components/Panel/PanelContent.js.map +1 -1
- package/dist/components/Panel/PanelHeader.d.ts +3 -1
- package/dist/components/Panel/PanelHeader.d.ts.map +1 -1
- package/dist/components/Panel/PanelHeader.js +12 -43
- package/dist/components/Panel/PanelHeader.js.map +1 -1
- package/dist/components/Panel/PanelLinks.js.map +1 -1
- package/dist/components/Panel/PanelPluginLoader.d.ts +13 -0
- package/dist/components/Panel/PanelPluginLoader.d.ts.map +1 -0
- package/dist/components/Panel/PanelPluginLoader.js +51 -0
- package/dist/components/Panel/PanelPluginLoader.js.map +1 -0
- package/dist/components/Panel/index.d.ts +1 -0
- package/dist/components/Panel/index.d.ts.map +1 -1
- package/dist/components/Panel/index.js +1 -0
- package/dist/components/Panel/index.js.map +1 -1
- package/dist/components/PanelDrawer/PanelEditorForm.d.ts.map +1 -1
- package/dist/components/PanelDrawer/PanelEditorForm.js +21 -9
- package/dist/components/PanelDrawer/PanelEditorForm.js.map +1 -1
- package/dist/components/SaveChangesConfirmationDialog/SaveChangesConfirmationDialog.js.map +1 -1
- package/dist/components/SaveDashboardButton/SaveDashboardButton.js.map +1 -1
- package/dist/components/Variables/BuiltinVariableAccordions.js.map +1 -1
- package/dist/components/Variables/Variable.js +10 -1
- package/dist/components/Variables/Variable.js.map +1 -1
- package/dist/components/Variables/VariableEditor.js.map +1 -1
- package/dist/components/Variables/VariableList.js.map +1 -1
- package/dist/constants/styles.d.ts +2 -1
- package/dist/constants/styles.d.ts.map +1 -1
- package/dist/constants/styles.js +2 -1
- package/dist/constants/styles.js.map +1 -1
- package/dist/constants/user-interface-text.d.ts +0 -1
- package/dist/constants/user-interface-text.d.ts.map +1 -1
- package/dist/constants/user-interface-text.js +1 -2
- package/dist/constants/user-interface-text.js.map +1 -1
- package/dist/context/DashboardProvider/dashboard-provider-api.d.ts +11 -2
- package/dist/context/DashboardProvider/dashboard-provider-api.d.ts.map +1 -1
- package/dist/context/DashboardProvider/dashboard-provider-api.js +12 -2
- package/dist/context/DashboardProvider/dashboard-provider-api.js.map +1 -1
- package/dist/context/DashboardProvider/delete-panel-slice.js.map +1 -1
- package/dist/context/DashboardProvider/duplicate-panel-slice.js.map +1 -1
- package/dist/context/DashboardProvider/panel-editor-slice.js.map +1 -1
- package/dist/context/DashboardProvider/panel-group-slice.d.ts +1 -1
- package/dist/context/DashboardProvider/panel-group-slice.d.ts.map +1 -1
- package/dist/context/DashboardProvider/panel-group-slice.js.map +1 -1
- package/dist/context/DatasourceStoreProvider.js.map +1 -1
- package/dist/context/VariableProvider/VariableProvider.d.ts.map +1 -1
- package/dist/context/VariableProvider/VariableProvider.js +13 -12
- package/dist/context/VariableProvider/VariableProvider.js.map +1 -1
- package/dist/context/VariableProvider/query-params.js.map +1 -1
- package/dist/context/useDashboard.js.map +1 -1
- package/dist/test/datasource-provider.d.ts +1 -1
- package/dist/test/datasource-provider.d.ts.map +1 -1
- package/dist/test/datasource-provider.js +1 -1
- package/dist/test/datasource-provider.js.map +1 -1
- package/dist/test/plugin-registry.d.ts.map +1 -1
- package/dist/test/plugin-registry.js +4 -1
- package/dist/test/plugin-registry.js.map +1 -1
- package/dist/utils/panelUtils.js.map +1 -1
- package/dist/views/ViewDashboard/DashboardApp.d.ts +2 -0
- package/dist/views/ViewDashboard/DashboardApp.d.ts.map +1 -1
- package/dist/views/ViewDashboard/DashboardApp.js +3 -1
- package/dist/views/ViewDashboard/DashboardApp.js.map +1 -1
- package/dist/views/ViewDashboard/ViewDashboard.d.ts.map +1 -1
- package/dist/views/ViewDashboard/ViewDashboard.js +3 -1
- package/dist/views/ViewDashboard/ViewDashboard.js.map +1 -1
- package/package.json +9 -9
- package/dist/cjs/stories/decorators/WithDashboard.js +0 -41
- package/dist/cjs/stories/decorators/WithDatasourceStore.js +0 -39
- package/dist/cjs/stories/decorators/WithVariables.js +0 -37
- package/dist/cjs/stories/decorators/constants.js +0 -39
- package/dist/cjs/stories/decorators/index.js +0 -33
- package/dist/stories/decorators/WithDashboard.js +0 -33
- package/dist/stories/decorators/WithDashboard.js.map +0 -1
- package/dist/stories/decorators/WithDatasourceStore.js +0 -31
- package/dist/stories/decorators/WithDatasourceStore.js.map +0 -1
- package/dist/stories/decorators/WithVariables.js +0 -29
- package/dist/stories/decorators/WithVariables.js.map +0 -1
- package/dist/stories/decorators/constants.js +0 -31
- package/dist/stories/decorators/constants.js.map +0 -1
- package/dist/stories/decorators/index.js +0 -18
- 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 {
|
|
15
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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 {
|
|
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":"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,EAAEC,QAAQC,aAAa,EAAEC,IAAI,EAAEC,QAAQ,QAAe,gBAAgB;AACzF,OAAOC,gBAAgB,yBAAyB;AAEhD,SAAmCC,QAAQ,QAAQ,QAAQ;AAC3D,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAASC,2BAA2B,QAAQ,4BAA4B;AAExE,OAAO,SAASC,WAAW,EAAEC,KAAK,EAAqB;IACrD,MAAM,CAACC,UAAUC,YAAY,GAAGN,SAA6B;IAC7D,MAAMO,eAAeC,QAAQH;IAC7B,MAAMI,iBAAiB,CAACC;QACtBJ,YAAYI,MAAMC,aAAa;IACjC;IACA,MAAMC,cAAc;QAClBN,YAAY;IACd;IAEA,8CAA8C;IAC9C,IAAIF,MAAMS,MAAM,KAAK,KAAKT,KAAK,CAAC,EAAE,EAAE;QAClC,MAAMU,OAAOV,KAAK,CAAC,EAAE;QACrB,qBAAO,KAACW;YAAWD,MAAMA;;IAC3B;IAEA,+CAA+C;IAC/C,qBACE;;0BACE,KAACb;gBAAYe,aAAa,
|
|
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 +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"}
|
|
@@ -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,
|
|
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:
|
|
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:
|
|
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:
|
|
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,
|
|
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,
|
|
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,
|
|
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, {})
|