@perses-dev/dashboards 0.0.0-snapshot-timeseries-panel-actions-e28c1fe → 0.0.0-snapshot-ts-panel-actions-76080ec

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.
@@ -24,7 +24,6 @@ const _jsxruntime = require("react/jsx-runtime");
24
24
  const _material = require("@mui/material");
25
25
  const _react = require("react");
26
26
  const _components = require("@perses-dev/components");
27
- const _pluginsystem = require("@perses-dev/plugin-system");
28
27
  const _ArrowCollapse = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowCollapse"));
29
28
  const _ArrowExpand = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/ArrowExpand"));
30
29
  const _PencilOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/PencilOutline"));
@@ -48,10 +47,7 @@ const ConditionalBox = (0, _material.styled)(_material.Box)({
48
47
  flexGrow: 1,
49
48
  justifyContent: 'flex-end'
50
49
  });
51
- const PanelActions = ({ editHandlers, readHandlers, extra, title, description, descriptionTooltipId, links, panelContentProps, pluginActions = [] })=>{
52
- const { isFetching, errors } = (0, _pluginsystem.useDataQueriesContext)();
53
- // Only destructure queryResults since we removed panelPluginKind and spec
54
- const { queryResults } = panelContentProps;
50
+ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, descriptionTooltipId, links, queryResults, pluginActions = [] })=>{
55
51
  const descriptionAction = (0, _react.useMemo)(()=>{
56
52
  if (description && description.trim().length > 0) {
57
53
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
@@ -82,45 +78,17 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, d
82
78
  });
83
79
  const extraActions = editHandlers === undefined && extra;
84
80
  const queryStateIndicator = (0, _react.useMemo)(()=>{
85
- // Check if any query is fetching
86
- const isQueryFetching = queryResults.some((q)=>q.isFetching);
87
- // Get query-specific errors
81
+ const hasData = queryResults.some((q)=>q.data);
82
+ const isFetching = queryResults.some((q)=>q.isFetching);
88
83
  const queryErrors = queryResults.filter((q)=>q.error);
89
- // Convert QueryData[] to TimeSeriesData format for data availability check
90
- const timeSeriesData = queryResults && queryResults.length > 0 ? {
91
- series: queryResults.flatMap((q)=>{
92
- // Only extract series if the data type is TimeSeriesData
93
- if (q.data && typeof q.data === 'object' && 'series' in q.data) {
94
- return q.data.series || [];
95
- }
96
- return [];
97
- })
98
- } : undefined;
99
- const hasData = timeSeriesData && timeSeriesData.series && timeSeriesData.series.length > 0;
100
- // Show loading indicator if queries are fetching AND we already have data
101
- if ((isFetching || isQueryFetching) && hasData) {
102
- // If the panel has no data, the panel content will show the loading overlay.
103
- // Therefore, show the circular loading indicator only in case the panel doesn't display the loading overlay already.
84
+ if (isFetching && hasData) {
104
85
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.CircularProgress, {
105
86
  "aria-label": "loading",
106
87
  size: "1.125rem"
107
88
  });
108
- }
109
- // Check for errors from both context and query results
110
- const contextErrors = (errors || []).filter((error)=>error !== null);
111
- const allErrors = [
112
- ...contextErrors,
113
- ...queryErrors.map((q)=>q.error)
114
- ].filter(Boolean);
115
- if (allErrors.length > 0) {
116
- const errorTexts = allErrors.map((e)=>{
117
- if (typeof e === 'string') return e;
118
- if (e && typeof e === 'object') {
119
- const errorObj = e;
120
- return errorObj.message ?? errorObj.toString?.() ?? 'Unknown error';
121
- }
122
- return 'Unknown error';
123
- }).join('\n');
89
+ } else if (queryErrors.length > 0) {
90
+ const errorTexts = queryErrors.map((q)=>q.error).map((e)=>e?.message ?? e?.toString() ?? 'Unknown error') // eslint-disable-line @typescript-eslint/no-explicit-any
91
+ .join('\n');
124
92
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_components.InfoTooltip, {
125
93
  description: errorTexts,
126
94
  children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_HeaderIconButton.HeaderIconButton, {
@@ -133,9 +101,7 @@ const PanelActions = ({ editHandlers, readHandlers, extra, title, description, d
133
101
  });
134
102
  }
135
103
  }, [
136
- queryResults,
137
- isFetching,
138
- errors
104
+ queryResults
139
105
  ]);
140
106
  const readActions = (0, _react.useMemo)(()=>{
141
107
  if (readHandlers !== undefined) {
@@ -24,7 +24,6 @@ const _jsxruntime = require("react/jsx-runtime");
24
24
  const _material = require("@mui/material");
25
25
  const _components = require("@perses-dev/components");
26
26
  const _pluginsystem = require("@perses-dev/plugin-system");
27
- const _react = require("react");
28
27
  const _constants = require("../../constants");
29
28
  const _PanelActions = require("./PanelActions");
30
29
  function PanelHeader({ id, title: rawTitle, description: rawDescription, links, queryResults, readHandlers, editHandlers, sx, extra, pluginActions, ...rest }) {
@@ -32,12 +31,6 @@ function PanelHeader({ id, title: rawTitle, description: rawDescription, links,
32
31
  const descriptionTooltipId = `${id}-description`;
33
32
  const title = (0, _pluginsystem.useReplaceVariablesInString)(rawTitle);
34
33
  const description = (0, _pluginsystem.useReplaceVariablesInString)(rawDescription);
35
- // Create the panelContentProps object with only queryResults
36
- const panelContentProps = (0, _react.useMemo)(()=>({
37
- queryResults
38
- }), [
39
- queryResults
40
- ]);
41
34
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.CardHeader, {
42
35
  id: id,
43
36
  component: "header",
@@ -69,7 +62,7 @@ function PanelHeader({ id, title: rawTitle, description: rawDescription, links,
69
62
  readHandlers: readHandlers,
70
63
  editHandlers: editHandlers,
71
64
  extra: extra,
72
- panelContentProps: panelContentProps,
65
+ queryResults: queryResults,
73
66
  pluginActions: pluginActions
74
67
  })
75
68
  ]
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
+ import { QueryData } from '@perses-dev/plugin-system';
2
3
  import { Link } from '@perses-dev/core';
3
- import { PanelContentProps } from './PanelContent';
4
4
  export interface PanelActionsProps {
5
5
  title: string;
6
6
  description?: string;
@@ -16,7 +16,7 @@ export interface PanelActionsProps {
16
16
  isPanelViewed?: boolean;
17
17
  onViewPanelClick: () => void;
18
18
  };
19
- panelContentProps: Pick<PanelContentProps, 'queryResults'>;
19
+ queryResults: QueryData[];
20
20
  pluginActions?: ReactNode[];
21
21
  }
22
22
  export declare const PanelActions: React.FC<PanelActionsProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"PanelActions.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelActions.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAqC,SAAS,EAAqB,MAAM,OAAO,CAAC;AAYxF,OAAO,EAAE,IAAI,EAAkB,MAAM,kBAAkB,CAAC;AAUxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE;QACb,gBAAgB,EAAE,MAAM,IAAI,CAAC;QAC7B,qBAAqB,EAAE,MAAM,IAAI,CAAC;QAClC,kBAAkB,EAAE,MAAM,IAAI,CAAC;KAChC,CAAC;IACF,YAAY,CAAC,EAAE;QACb,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,IAAI,CAAC;KAC9B,CAAC;IACF,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAC3D,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;CAC7B;AASD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA4OpD,CAAC"}
1
+ {"version":3,"file":"PanelActions.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelActions.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAqC,SAAS,EAAqB,MAAM,OAAO,CAAC;AAExF,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAUtD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAWxC,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE;QACb,gBAAgB,EAAE,MAAM,IAAI,CAAC;QAC7B,qBAAqB,EAAE,MAAM,IAAI,CAAC;QAClC,kBAAkB,EAAE,MAAM,IAAI,CAAC;KAChC,CAAC;IACF,YAAY,CAAC,EAAE;QACb,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,gBAAgB,EAAE,MAAM,IAAI,CAAC;KAC9B,CAAC;IACF,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;CAC7B;AASD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAuMpD,CAAC"}
@@ -14,7 +14,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
14
14
  import { Stack, Box, Popover, CircularProgress, styled } from '@mui/material';
15
15
  import { isValidElement, useMemo, useState } from 'react';
16
16
  import { InfoTooltip } from '@perses-dev/components';
17
- import { useDataQueriesContext } from '@perses-dev/plugin-system';
18
17
  import ArrowCollapseIcon from 'mdi-material-ui/ArrowCollapse';
19
18
  import ArrowExpandIcon from 'mdi-material-ui/ArrowExpand';
20
19
  import PencilIcon from 'mdi-material-ui/PencilOutline';
@@ -33,10 +32,7 @@ const ConditionalBox = styled(Box)({
33
32
  flexGrow: 1,
34
33
  justifyContent: 'flex-end'
35
34
  });
36
- export const PanelActions = ({ editHandlers, readHandlers, extra, title, description, descriptionTooltipId, links, panelContentProps, pluginActions = [] })=>{
37
- const { isFetching, errors } = useDataQueriesContext();
38
- // Only destructure queryResults since we removed panelPluginKind and spec
39
- const { queryResults } = panelContentProps;
35
+ export const PanelActions = ({ editHandlers, readHandlers, extra, title, description, descriptionTooltipId, links, queryResults, pluginActions = [] })=>{
40
36
  const descriptionAction = useMemo(()=>{
41
37
  if (description && description.trim().length > 0) {
42
38
  return /*#__PURE__*/ _jsx(InfoTooltip, {
@@ -67,45 +63,17 @@ export const PanelActions = ({ editHandlers, readHandlers, extra, title, descrip
67
63
  });
68
64
  const extraActions = editHandlers === undefined && extra;
69
65
  const queryStateIndicator = useMemo(()=>{
70
- // Check if any query is fetching
71
- const isQueryFetching = queryResults.some((q)=>q.isFetching);
72
- // Get query-specific errors
66
+ const hasData = queryResults.some((q)=>q.data);
67
+ const isFetching = queryResults.some((q)=>q.isFetching);
73
68
  const queryErrors = queryResults.filter((q)=>q.error);
74
- // Convert QueryData[] to TimeSeriesData format for data availability check
75
- const timeSeriesData = queryResults && queryResults.length > 0 ? {
76
- series: queryResults.flatMap((q)=>{
77
- // Only extract series if the data type is TimeSeriesData
78
- if (q.data && typeof q.data === 'object' && 'series' in q.data) {
79
- return q.data.series || [];
80
- }
81
- return [];
82
- })
83
- } : undefined;
84
- const hasData = timeSeriesData && timeSeriesData.series && timeSeriesData.series.length > 0;
85
- // Show loading indicator if queries are fetching AND we already have data
86
- if ((isFetching || isQueryFetching) && hasData) {
87
- // If the panel has no data, the panel content will show the loading overlay.
88
- // Therefore, show the circular loading indicator only in case the panel doesn't display the loading overlay already.
69
+ if (isFetching && hasData) {
89
70
  return /*#__PURE__*/ _jsx(CircularProgress, {
90
71
  "aria-label": "loading",
91
72
  size: "1.125rem"
92
73
  });
93
- }
94
- // Check for errors from both context and query results
95
- const contextErrors = (errors || []).filter((error)=>error !== null);
96
- const allErrors = [
97
- ...contextErrors,
98
- ...queryErrors.map((q)=>q.error)
99
- ].filter(Boolean);
100
- if (allErrors.length > 0) {
101
- const errorTexts = allErrors.map((e)=>{
102
- if (typeof e === 'string') return e;
103
- if (e && typeof e === 'object') {
104
- const errorObj = e;
105
- return errorObj.message ?? errorObj.toString?.() ?? 'Unknown error';
106
- }
107
- return 'Unknown error';
108
- }).join('\n');
74
+ } else if (queryErrors.length > 0) {
75
+ const errorTexts = queryErrors.map((q)=>q.error).map((e)=>e?.message ?? e?.toString() ?? 'Unknown error') // eslint-disable-line @typescript-eslint/no-explicit-any
76
+ .join('\n');
109
77
  return /*#__PURE__*/ _jsx(InfoTooltip, {
110
78
  description: errorTexts,
111
79
  children: /*#__PURE__*/ _jsx(HeaderIconButton, {
@@ -118,9 +86,7 @@ export const PanelActions = ({ editHandlers, readHandlers, extra, title, descrip
118
86
  });
119
87
  }
120
88
  }, [
121
- queryResults,
122
- isFetching,
123
- errors
89
+ queryResults
124
90
  ]);
125
91
  const readActions = useMemo(()=>{
126
92
  if (readHandlers !== undefined) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/Panel/PanelActions.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 { Stack, Box, Popover, CircularProgress, styled, PopoverPosition } from '@mui/material';\nimport { isValidElement, PropsWithChildren, ReactNode, useMemo, useState } from 'react';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { useDataQueriesContext } from '@perses-dev/plugin-system';\nimport ArrowCollapseIcon from 'mdi-material-ui/ArrowCollapse';\nimport ArrowExpandIcon from 'mdi-material-ui/ArrowExpand';\nimport PencilIcon from 'mdi-material-ui/PencilOutline';\nimport DeleteIcon from 'mdi-material-ui/DeleteOutline';\nimport DragIcon from 'mdi-material-ui/DragVertical';\nimport ContentCopyIcon from 'mdi-material-ui/ContentCopy';\nimport MenuIcon from 'mdi-material-ui/Menu';\nimport AlertIcon from 'mdi-material-ui/Alert';\nimport InformationOutlineIcon from 'mdi-material-ui/InformationOutline';\nimport { Link, TimeSeriesData } from '@perses-dev/core';\nimport {\n ARIA_LABEL_TEXT,\n HEADER_ACTIONS_CONTAINER_NAME,\n HEADER_MEDIUM_WIDTH,\n HEADER_SMALL_WIDTH,\n TOOLTIP_TEXT,\n} from '../../constants';\nimport { HeaderIconButton } from './HeaderIconButton';\nimport { PanelLinks } from './PanelLinks';\nimport { PanelContentProps } from './PanelContent';\n\nexport interface PanelActionsProps {\n title: string;\n description?: string;\n descriptionTooltipId: string;\n links?: Link[];\n extra?: React.ReactNode;\n editHandlers?: {\n onEditPanelClick: () => void;\n onDuplicatePanelClick: () => void;\n onDeletePanelClick: () => void;\n };\n readHandlers?: {\n isPanelViewed?: boolean;\n onViewPanelClick: () => void;\n };\n panelContentProps: Pick<PanelContentProps, 'queryResults'>;\n pluginActions?: ReactNode[];\n}\n\nconst ConditionalBox = styled(Box)({\n display: 'none',\n alignItems: 'center',\n flexGrow: 1,\n justifyContent: 'flex-end',\n});\n\nexport const PanelActions: React.FC<PanelActionsProps> = ({\n editHandlers,\n readHandlers,\n extra,\n title,\n description,\n descriptionTooltipId,\n links,\n panelContentProps,\n pluginActions = [],\n}) => {\n const { isFetching, errors } = useDataQueriesContext();\n\n // Only destructure queryResults since we removed panelPluginKind and spec\n const { queryResults } = panelContentProps;\n\n const descriptionAction = useMemo((): ReactNode | undefined => {\n if (description && description.trim().length > 0) {\n return (\n <InfoTooltip id={descriptionTooltipId} description={description} enterDelay={100}>\n <HeaderIconButton aria-label=\"panel description\" size=\"small\">\n <InformationOutlineIcon\n aria-describedby=\"info-tooltip\"\n aria-hidden={false}\n fontSize=\"inherit\"\n sx={{ color: (theme) => theme.palette.text.secondary }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [descriptionTooltipId, description]);\n\n const linksAction = links && links.length > 0 && <PanelLinks links={links} />;\n const extraActions = editHandlers === undefined && extra;\n\n const queryStateIndicator = useMemo((): ReactNode | undefined => {\n // Check if any query is fetching\n const isQueryFetching = queryResults.some((q) => q.isFetching);\n // Get query-specific errors\n const queryErrors = queryResults.filter((q) => q.error);\n\n // Convert QueryData[] to TimeSeriesData format for data availability check\n const timeSeriesData: TimeSeriesData | undefined =\n queryResults && queryResults.length > 0\n ? {\n series: queryResults.flatMap((q) => {\n // Only extract series if the data type is TimeSeriesData\n if (q.data && typeof q.data === 'object' && 'series' in q.data) {\n return q.data.series || [];\n }\n return [];\n }),\n }\n : undefined;\n\n const hasData = timeSeriesData && timeSeriesData.series && timeSeriesData.series.length > 0;\n\n // Show loading indicator if queries are fetching AND we already have data\n if ((isFetching || isQueryFetching) && hasData) {\n // If the panel has no data, the panel content will show the loading overlay.\n // Therefore, show the circular loading indicator only in case the panel doesn't display the loading overlay already.\n return <CircularProgress aria-label=\"loading\" size=\"1.125rem\" />;\n }\n\n // Check for errors from both context and query results\n const contextErrors = (errors || []).filter((error) => error !== null);\n const allErrors = [...contextErrors, ...queryErrors.map((q) => q.error)].filter(Boolean);\n\n if (allErrors.length > 0) {\n const errorTexts = allErrors\n .map((e: unknown) => {\n if (typeof e === 'string') return e;\n if (e && typeof e === 'object') {\n const errorObj = e as { message?: string; toString?: () => string };\n return errorObj.message ?? errorObj.toString?.() ?? 'Unknown error';\n }\n return 'Unknown error';\n })\n .join('\\n');\n\n return (\n <InfoTooltip description={errorTexts}>\n <HeaderIconButton aria-label=\"panel errors\" size=\"small\">\n <AlertIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n }, [queryResults, isFetching, errors]);\n\n const readActions = useMemo((): ReactNode | undefined => {\n if (readHandlers !== undefined) {\n return (\n <InfoTooltip description={TOOLTIP_TEXT.viewPanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.viewPanel(title)}\n size=\"small\"\n onClick={readHandlers.onViewPanelClick}\n >\n {readHandlers.isPanelViewed ? (\n <ArrowCollapseIcon fontSize=\"inherit\" />\n ) : (\n <ArrowExpandIcon fontSize=\"inherit\" />\n )}\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [readHandlers, title]);\n\n const editActions = useMemo((): ReactNode | undefined => {\n if (editHandlers !== undefined) {\n // If there are edit handlers, always just show the edit buttons\n return (\n <>\n <InfoTooltip description={TOOLTIP_TEXT.editPanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.editPanel(title)}\n size=\"small\"\n onClick={editHandlers.onEditPanelClick}\n >\n <PencilIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n <InfoTooltip description={TOOLTIP_TEXT.duplicatePanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.duplicatePanel(title)}\n size=\"small\"\n onClick={editHandlers.onDuplicatePanelClick}\n >\n <ContentCopyIcon\n fontSize=\"inherit\"\n sx={{\n // Shrink this icon a little bit to look more consistent\n // with the other icons in the header.\n transform: 'scale(0.925)',\n }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n <InfoTooltip description={TOOLTIP_TEXT.deletePanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.deletePanel(title)}\n size=\"small\"\n onClick={editHandlers.onDeletePanelClick}\n >\n <DeleteIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n </>\n );\n }\n return undefined;\n }, [editHandlers, title]);\n\n const moveAction = useMemo((): ReactNode | undefined => {\n if (editActions && !readHandlers?.isPanelViewed) {\n return (\n <InfoTooltip description={TOOLTIP_TEXT.movePanel}>\n <HeaderIconButton aria-label={ARIA_LABEL_TEXT.movePanel(title)} size=\"small\">\n <DragIcon className=\"drag-handle\" sx={{ cursor: 'grab' }} fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [editActions, readHandlers, title]);\n\n const divider = <Box sx={{ flexGrow: 1 }}></Box>;\n\n // if the panel is in non-editing, non-fullscreen mode, show certain icons only on hover\n const OnHover = ({ children }: PropsWithChildren): ReactNode =>\n editHandlers === undefined && !readHandlers?.isPanelViewed ? (\n <Box sx={{ display: 'var(--panel-hover, none)' }}>{children}</Box>\n ) : (\n <>{children}</>\n );\n\n return (\n <>\n {/* small panel width: move all icons except move/grab to overflow menu */}\n <ConditionalBox\n sx={(theme) => ({\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).between(0, HEADER_SMALL_WIDTH)]: { display: 'flex' },\n })}\n >\n {divider}\n <OnHover>\n <OverflowMenu title={title}>\n {descriptionAction} {linksAction} {queryStateIndicator} {extraActions} {readActions} {editActions}\n </OverflowMenu>\n {pluginActions}\n {moveAction}\n </OnHover>\n </ConditionalBox>\n\n {/* medium panel width: move edit icons to overflow menu */}\n <ConditionalBox\n sx={(theme) => ({\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).between(HEADER_SMALL_WIDTH, HEADER_MEDIUM_WIDTH)]: {\n display: 'flex',\n },\n })}\n >\n <OnHover>\n {descriptionAction} {linksAction}\n </OnHover>\n {divider} {queryStateIndicator}\n <OnHover>\n {extraActions} {readActions} {pluginActions}\n <OverflowMenu title={title}>{editActions}</OverflowMenu>\n {moveAction}\n </OnHover>\n </ConditionalBox>\n\n {/* large panel width: show all icons in panel header */}\n <ConditionalBox\n sx={(theme) => ({\n // flip the logic here; if the browser (or jsdom) does not support container queries, always show all icons\n display: 'flex',\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).down(HEADER_MEDIUM_WIDTH)]: { display: 'none' },\n })}\n >\n <OnHover>\n {descriptionAction} {linksAction}\n </OnHover>\n {divider} {queryStateIndicator}\n <OnHover>\n {extraActions} {readActions} {pluginActions} {editActions} {moveAction}\n </OnHover>\n </ConditionalBox>\n </>\n );\n};\n\nconst OverflowMenu: React.FC<PropsWithChildren<{ title: string }>> = ({ children, title }) => {\n const [anchorPosition, setAnchorPosition] = useState<PopoverPosition>();\n\n // do not show overflow menu if there is no content (for example, edit actions are hidden)\n const hasContent = isValidElement(children) || (Array.isArray(children) && children.some(isValidElement));\n if (!hasContent) {\n return undefined;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLElement>): void => {\n setAnchorPosition(event.currentTarget.getBoundingClientRect());\n };\n\n const handleClose = (): void => {\n setAnchorPosition(undefined);\n };\n\n const open = Boolean(anchorPosition);\n const id = open ? 'actions-menu' : undefined;\n\n return (\n <>\n <HeaderIconButton\n className=\"show-actions\"\n aria-describedby={id}\n onClick={handleClick}\n aria-label={ARIA_LABEL_TEXT.showPanelActions(title)}\n size=\"small\"\n >\n <MenuIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n <Popover\n id={id}\n open={open}\n anchorReference=\"anchorPosition\"\n anchorPosition={anchorPosition}\n onClose={handleClose}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left',\n }}\n >\n <Stack direction=\"row\" alignItems=\"center\" sx={{ padding: 1 }} onClick={handleClose}>\n {children}\n </Stack>\n </Popover>\n </>\n );\n};\n"],"names":["Stack","Box","Popover","CircularProgress","styled","isValidElement","useMemo","useState","InfoTooltip","useDataQueriesContext","ArrowCollapseIcon","ArrowExpandIcon","PencilIcon","DeleteIcon","DragIcon","ContentCopyIcon","MenuIcon","AlertIcon","InformationOutlineIcon","ARIA_LABEL_TEXT","HEADER_ACTIONS_CONTAINER_NAME","HEADER_MEDIUM_WIDTH","HEADER_SMALL_WIDTH","TOOLTIP_TEXT","HeaderIconButton","PanelLinks","ConditionalBox","display","alignItems","flexGrow","justifyContent","PanelActions","editHandlers","readHandlers","extra","title","description","descriptionTooltipId","links","panelContentProps","pluginActions","isFetching","errors","queryResults","descriptionAction","trim","length","id","enterDelay","aria-label","size","aria-describedby","aria-hidden","fontSize","sx","color","theme","palette","text","secondary","undefined","linksAction","extraActions","queryStateIndicator","isQueryFetching","some","q","queryErrors","filter","error","timeSeriesData","series","flatMap","data","hasData","contextErrors","allErrors","map","Boolean","errorTexts","e","errorObj","message","toString","join","readActions","viewPanel","onClick","onViewPanelClick","isPanelViewed","editActions","editPanel","onEditPanelClick","duplicatePanel","onDuplicatePanelClick","transform","deletePanel","onDeletePanelClick","moveAction","movePanel","className","cursor","divider","OnHover","children","containerQueries","between","OverflowMenu","down","anchorPosition","setAnchorPosition","hasContent","Array","isArray","handleClick","event","currentTarget","getBoundingClientRect","handleClose","open","showPanelActions","anchorReference","onClose","anchorOrigin","vertical","horizontal","direction","padding"],"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,KAAK,EAAEC,GAAG,EAAEC,OAAO,EAAEC,gBAAgB,EAAEC,MAAM,QAAyB,gBAAgB;AAC/F,SAASC,cAAc,EAAgCC,OAAO,EAAEC,QAAQ,QAAQ,QAAQ;AACxF,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAASC,qBAAqB,QAAQ,4BAA4B;AAClE,OAAOC,uBAAuB,gCAAgC;AAC9D,OAAOC,qBAAqB,8BAA8B;AAC1D,OAAOC,gBAAgB,gCAAgC;AACvD,OAAOC,gBAAgB,gCAAgC;AACvD,OAAOC,cAAc,+BAA+B;AACpD,OAAOC,qBAAqB,8BAA8B;AAC1D,OAAOC,cAAc,uBAAuB;AAC5C,OAAOC,eAAe,wBAAwB;AAC9C,OAAOC,4BAA4B,qCAAqC;AAExE,SACEC,eAAe,EACfC,6BAA6B,EAC7BC,mBAAmB,EACnBC,kBAAkB,EAClBC,YAAY,QACP,kBAAkB;AACzB,SAASC,gBAAgB,QAAQ,qBAAqB;AACtD,SAASC,UAAU,QAAQ,eAAe;AAsB1C,MAAMC,iBAAiBtB,OAAOH,KAAK;IACjC0B,SAAS;IACTC,YAAY;IACZC,UAAU;IACVC,gBAAgB;AAClB;AAEA,OAAO,MAAMC,eAA4C,CAAC,EACxDC,YAAY,EACZC,YAAY,EACZC,KAAK,EACLC,KAAK,EACLC,WAAW,EACXC,oBAAoB,EACpBC,KAAK,EACLC,iBAAiB,EACjBC,gBAAgB,EAAE,EACnB;IACC,MAAM,EAAEC,UAAU,EAAEC,MAAM,EAAE,GAAGjC;IAE/B,0EAA0E;IAC1E,MAAM,EAAEkC,YAAY,EAAE,GAAGJ;IAEzB,MAAMK,oBAAoBtC,QAAQ;QAChC,IAAI8B,eAAeA,YAAYS,IAAI,GAAGC,MAAM,GAAG,GAAG;YAChD,qBACE,KAACtC;gBAAYuC,IAAIV;gBAAsBD,aAAaA;gBAAaY,YAAY;0BAC3E,cAAA,KAACxB;oBAAiByB,cAAW;oBAAoBC,MAAK;8BACpD,cAAA,KAAChC;wBACCiC,oBAAiB;wBACjBC,eAAa;wBACbC,UAAS;wBACTC,IAAI;4BAAEC,OAAO,CAACC,QAAUA,MAAMC,OAAO,CAACC,IAAI,CAACC,SAAS;wBAAC;;;;QAK/D;QACA,OAAOC;IACT,GAAG;QAACvB;QAAsBD;KAAY;IAEtC,MAAMyB,cAAcvB,SAASA,MAAMQ,MAAM,GAAG,mBAAK,KAACrB;QAAWa,OAAOA;;IACpE,MAAMwB,eAAe9B,iBAAiB4B,aAAa1B;IAEnD,MAAM6B,sBAAsBzD,QAAQ;QAClC,iCAAiC;QACjC,MAAM0D,kBAAkBrB,aAAasB,IAAI,CAAC,CAACC,IAAMA,EAAEzB,UAAU;QAC7D,4BAA4B;QAC5B,MAAM0B,cAAcxB,aAAayB,MAAM,CAAC,CAACF,IAAMA,EAAEG,KAAK;QAEtD,2EAA2E;QAC3E,MAAMC,iBACJ3B,gBAAgBA,aAAaG,MAAM,GAAG,IAClC;YACEyB,QAAQ5B,aAAa6B,OAAO,CAAC,CAACN;gBAC5B,yDAAyD;gBACzD,IAAIA,EAAEO,IAAI,IAAI,OAAOP,EAAEO,IAAI,KAAK,YAAY,YAAYP,EAAEO,IAAI,EAAE;oBAC9D,OAAOP,EAAEO,IAAI,CAACF,MAAM,IAAI,EAAE;gBAC5B;gBACA,OAAO,EAAE;YACX;QACF,IACAX;QAEN,MAAMc,UAAUJ,kBAAkBA,eAAeC,MAAM,IAAID,eAAeC,MAAM,CAACzB,MAAM,GAAG;QAE1F,0EAA0E;QAC1E,IAAI,AAACL,CAAAA,cAAcuB,eAAc,KAAMU,SAAS;YAC9C,6EAA6E;YAC7E,qHAAqH;YACrH,qBAAO,KAACvE;gBAAiB8C,cAAW;gBAAUC,MAAK;;QACrD;QAEA,uDAAuD;QACvD,MAAMyB,gBAAgB,AAACjC,CAAAA,UAAU,EAAE,AAAD,EAAG0B,MAAM,CAAC,CAACC,QAAUA,UAAU;QACjE,MAAMO,YAAY;eAAID;eAAkBR,YAAYU,GAAG,CAAC,CAACX,IAAMA,EAAEG,KAAK;SAAE,CAACD,MAAM,CAACU;QAEhF,IAAIF,UAAU9B,MAAM,GAAG,GAAG;YACxB,MAAMiC,aAAaH,UAChBC,GAAG,CAAC,CAACG;gBACJ,IAAI,OAAOA,MAAM,UAAU,OAAOA;gBAClC,IAAIA,KAAK,OAAOA,MAAM,UAAU;oBAC9B,MAAMC,WAAWD;oBACjB,OAAOC,SAASC,OAAO,IAAID,SAASE,QAAQ,QAAQ;gBACtD;gBACA,OAAO;YACT,GACCC,IAAI,CAAC;YAER,qBACE,KAAC5E;gBAAY4B,aAAa2C;0BACxB,cAAA,KAACvD;oBAAiByB,cAAW;oBAAeC,MAAK;8BAC/C,cAAA,KAACjC;wBAAUoC,UAAS;;;;QAI5B;IACF,GAAG;QAACV;QAAcF;QAAYC;KAAO;IAErC,MAAM2C,cAAc/E,QAAQ;QAC1B,IAAI2B,iBAAiB2B,WAAW;YAC9B,qBACE,KAACpD;gBAAY4B,aAAab,aAAa+D,SAAS;0BAC9C,cAAA,KAAC9D;oBACCyB,cAAY9B,gBAAgBmE,SAAS,CAACnD;oBACtCe,MAAK;oBACLqC,SAAStD,aAAauD,gBAAgB;8BAErCvD,aAAawD,aAAa,iBACzB,KAAC/E;wBAAkB2C,UAAS;uCAE5B,KAAC1C;wBAAgB0C,UAAS;;;;QAKpC;QACA,OAAOO;IACT,GAAG;QAAC3B;QAAcE;KAAM;IAExB,MAAMuD,cAAcpF,QAAQ;QAC1B,IAAI0B,iBAAiB4B,WAAW;YAC9B,gEAAgE;YAChE,qBACE;;kCACE,KAACpD;wBAAY4B,aAAab,aAAaoE,SAAS;kCAC9C,cAAA,KAACnE;4BACCyB,cAAY9B,gBAAgBwE,SAAS,CAACxD;4BACtCe,MAAK;4BACLqC,SAASvD,aAAa4D,gBAAgB;sCAEtC,cAAA,KAAChF;gCAAWyC,UAAS;;;;kCAGzB,KAAC7C;wBAAY4B,aAAab,aAAasE,cAAc;kCACnD,cAAA,KAACrE;4BACCyB,cAAY9B,gBAAgB0E,cAAc,CAAC1D;4BAC3Ce,MAAK;4BACLqC,SAASvD,aAAa8D,qBAAqB;sCAE3C,cAAA,KAAC/E;gCACCsC,UAAS;gCACTC,IAAI;oCACF,wDAAwD;oCACxD,sCAAsC;oCACtCyC,WAAW;gCACb;;;;kCAIN,KAACvF;wBAAY4B,aAAab,aAAayE,WAAW;kCAChD,cAAA,KAACxE;4BACCyB,cAAY9B,gBAAgB6E,WAAW,CAAC7D;4BACxCe,MAAK;4BACLqC,SAASvD,aAAaiE,kBAAkB;sCAExC,cAAA,KAACpF;gCAAWwC,UAAS;;;;;;QAK/B;QACA,OAAOO;IACT,GAAG;QAAC5B;QAAcG;KAAM;IAExB,MAAM+D,aAAa5F,QAAQ;QACzB,IAAIoF,eAAe,CAACzD,cAAcwD,eAAe;YAC/C,qBACE,KAACjF;gBAAY4B,aAAab,aAAa4E,SAAS;0BAC9C,cAAA,KAAC3E;oBAAiByB,cAAY9B,gBAAgBgF,SAAS,CAAChE;oBAAQe,MAAK;8BACnE,cAAA,KAACpC;wBAASsF,WAAU;wBAAc9C,IAAI;4BAAE+C,QAAQ;wBAAO;wBAAGhD,UAAS;;;;QAI3E;QACA,OAAOO;IACT,GAAG;QAAC8B;QAAazD;QAAcE;KAAM;IAErC,MAAMmE,wBAAU,KAACrG;QAAIqD,IAAI;YAAEzB,UAAU;QAAE;;IAEvC,wFAAwF;IACxF,MAAM0E,UAAU,CAAC,EAAEC,QAAQ,EAAqB,GAC9CxE,iBAAiB4B,aAAa,CAAC3B,cAAcwD,8BAC3C,KAACxF;YAAIqD,IAAI;gBAAE3B,SAAS;YAA2B;sBAAI6E;2BAEnD;sBAAGA;;IAGP,qBACE;;0BAEE,MAAC9E;gBACC4B,IAAI,CAACE,QAAW,CAAA;wBACd,CAACA,MAAMiD,gBAAgB,CAACrF,+BAA+BsF,OAAO,CAAC,GAAGpF,oBAAoB,EAAE;4BAAEK,SAAS;wBAAO;oBAC5G,CAAA;;oBAEC2E;kCACD,MAACC;;0CACC,MAACI;gCAAaxE,OAAOA;;oCAClBS;oCAAkB;oCAAEiB;oCAAY;oCAAEE;oCAAoB;oCAAED;oCAAa;oCAAEuB;oCAAY;oCAAEK;;;4BAEvFlD;4BACA0D;;;;;0BAKL,MAACxE;gBACC4B,IAAI,CAACE,QAAW,CAAA;wBACd,CAACA,MAAMiD,gBAAgB,CAACrF,+BAA+BsF,OAAO,CAACpF,oBAAoBD,qBAAqB,EAAE;4BACxGM,SAAS;wBACX;oBACF,CAAA;;kCAEA,MAAC4E;;4BACE3D;4BAAkB;4BAAEiB;;;oBAEtByC;oBAAQ;oBAAEvC;kCACX,MAACwC;;4BACEzC;4BAAa;4BAAEuB;4BAAY;4BAAE7C;0CAC9B,KAACmE;gCAAaxE,OAAOA;0CAAQuD;;4BAC5BQ;;;;;0BAKL,MAACxE;gBACC4B,IAAI,CAACE,QAAW,CAAA;wBACd,2GAA2G;wBAC3G7B,SAAS;wBACT,CAAC6B,MAAMiD,gBAAgB,CAACrF,+BAA+BwF,IAAI,CAACvF,qBAAqB,EAAE;4BAAEM,SAAS;wBAAO;oBACvG,CAAA;;kCAEA,MAAC4E;;4BACE3D;4BAAkB;4BAAEiB;;;oBAEtByC;oBAAQ;oBAAEvC;kCACX,MAACwC;;4BACEzC;4BAAa;4BAAEuB;4BAAY;4BAAE7C;4BAAc;4BAAEkD;4BAAY;4BAAEQ;;;;;;;AAKtE,EAAE;AAEF,MAAMS,eAA+D,CAAC,EAAEH,QAAQ,EAAErE,KAAK,EAAE;IACvF,MAAM,CAAC0E,gBAAgBC,kBAAkB,GAAGvG;IAE5C,0FAA0F;IAC1F,MAAMwG,2BAAa1G,eAAemG,aAAcQ,MAAMC,OAAO,CAACT,aAAaA,SAASvC,IAAI,CAAC5D;IACzF,IAAI,CAAC0G,YAAY;QACf,OAAOnD;IACT;IAEA,MAAMsD,cAAc,CAACC;QACnBL,kBAAkBK,MAAMC,aAAa,CAACC,qBAAqB;IAC7D;IAEA,MAAMC,cAAc;QAClBR,kBAAkBlD;IACpB;IAEA,MAAM2D,OAAOzC,QAAQ+B;IACrB,MAAM9D,KAAKwE,OAAO,iBAAiB3D;IAEnC,qBACE;;0BACE,KAACpC;gBACC4E,WAAU;gBACVjD,oBAAkBJ;gBAClBwC,SAAS2B;gBACTjE,cAAY9B,gBAAgBqG,gBAAgB,CAACrF;gBAC7Ce,MAAK;0BAEL,cAAA,KAAClC;oBAASqC,UAAS;;;0BAErB,KAACnD;gBACC6C,IAAIA;gBACJwE,MAAMA;gBACNE,iBAAgB;gBAChBZ,gBAAgBA;gBAChBa,SAASJ;gBACTK,cAAc;oBACZC,UAAU;oBACVC,YAAY;gBACd;0BAEA,cAAA,KAAC7H;oBAAM8H,WAAU;oBAAMlG,YAAW;oBAAS0B,IAAI;wBAAEyE,SAAS;oBAAE;oBAAGxC,SAAS+B;8BACrEd;;;;;AAKX"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelActions.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 { Stack, Box, Popover, CircularProgress, styled, PopoverPosition } from '@mui/material';\nimport { isValidElement, PropsWithChildren, ReactNode, useMemo, useState } from 'react';\nimport { InfoTooltip } from '@perses-dev/components';\nimport { QueryData } from '@perses-dev/plugin-system';\nimport ArrowCollapseIcon from 'mdi-material-ui/ArrowCollapse';\nimport ArrowExpandIcon from 'mdi-material-ui/ArrowExpand';\nimport PencilIcon from 'mdi-material-ui/PencilOutline';\nimport DeleteIcon from 'mdi-material-ui/DeleteOutline';\nimport DragIcon from 'mdi-material-ui/DragVertical';\nimport ContentCopyIcon from 'mdi-material-ui/ContentCopy';\nimport MenuIcon from 'mdi-material-ui/Menu';\nimport AlertIcon from 'mdi-material-ui/Alert';\nimport InformationOutlineIcon from 'mdi-material-ui/InformationOutline';\nimport { Link } from '@perses-dev/core';\nimport {\n ARIA_LABEL_TEXT,\n HEADER_ACTIONS_CONTAINER_NAME,\n HEADER_MEDIUM_WIDTH,\n HEADER_SMALL_WIDTH,\n TOOLTIP_TEXT,\n} from '../../constants';\nimport { HeaderIconButton } from './HeaderIconButton';\nimport { PanelLinks } from './PanelLinks';\n\nexport interface PanelActionsProps {\n title: string;\n description?: string;\n descriptionTooltipId: string;\n links?: Link[];\n extra?: React.ReactNode;\n editHandlers?: {\n onEditPanelClick: () => void;\n onDuplicatePanelClick: () => void;\n onDeletePanelClick: () => void;\n };\n readHandlers?: {\n isPanelViewed?: boolean;\n onViewPanelClick: () => void;\n };\n queryResults: QueryData[];\n pluginActions?: ReactNode[];\n}\n\nconst ConditionalBox = styled(Box)({\n display: 'none',\n alignItems: 'center',\n flexGrow: 1,\n justifyContent: 'flex-end',\n});\n\nexport const PanelActions: React.FC<PanelActionsProps> = ({\n editHandlers,\n readHandlers,\n extra,\n title,\n description,\n descriptionTooltipId,\n links,\n queryResults,\n pluginActions = [],\n}) => {\n const descriptionAction = useMemo((): ReactNode | undefined => {\n if (description && description.trim().length > 0) {\n return (\n <InfoTooltip id={descriptionTooltipId} description={description} enterDelay={100}>\n <HeaderIconButton aria-label=\"panel description\" size=\"small\">\n <InformationOutlineIcon\n aria-describedby=\"info-tooltip\"\n aria-hidden={false}\n fontSize=\"inherit\"\n sx={{ color: (theme) => theme.palette.text.secondary }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [descriptionTooltipId, description]);\n\n const linksAction = links && links.length > 0 && <PanelLinks links={links} />;\n const extraActions = editHandlers === undefined && extra;\n\n const queryStateIndicator = useMemo((): ReactNode | undefined => {\n const hasData = queryResults.some((q) => q.data);\n const isFetching = queryResults.some((q) => q.isFetching);\n const queryErrors = queryResults.filter((q) => q.error);\n\n if (isFetching && hasData) {\n return <CircularProgress aria-label=\"loading\" size=\"1.125rem\" />;\n } else if (queryErrors.length > 0) {\n const errorTexts = queryErrors\n .map((q) => q.error)\n .map((e: any) => e?.message ?? e?.toString() ?? 'Unknown error') // eslint-disable-line @typescript-eslint/no-explicit-any\n .join('\\n');\n\n return (\n <InfoTooltip description={errorTexts}>\n <HeaderIconButton aria-label=\"panel errors\" size=\"small\">\n <AlertIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n }, [queryResults]);\n\n const readActions = useMemo((): ReactNode | undefined => {\n if (readHandlers !== undefined) {\n return (\n <InfoTooltip description={TOOLTIP_TEXT.viewPanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.viewPanel(title)}\n size=\"small\"\n onClick={readHandlers.onViewPanelClick}\n >\n {readHandlers.isPanelViewed ? (\n <ArrowCollapseIcon fontSize=\"inherit\" />\n ) : (\n <ArrowExpandIcon fontSize=\"inherit\" />\n )}\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [readHandlers, title]);\n\n const editActions = useMemo((): ReactNode | undefined => {\n if (editHandlers !== undefined) {\n // If there are edit handlers, always just show the edit buttons\n return (\n <>\n <InfoTooltip description={TOOLTIP_TEXT.editPanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.editPanel(title)}\n size=\"small\"\n onClick={editHandlers.onEditPanelClick}\n >\n <PencilIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n <InfoTooltip description={TOOLTIP_TEXT.duplicatePanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.duplicatePanel(title)}\n size=\"small\"\n onClick={editHandlers.onDuplicatePanelClick}\n >\n <ContentCopyIcon\n fontSize=\"inherit\"\n sx={{\n // Shrink this icon a little bit to look more consistent\n // with the other icons in the header.\n transform: 'scale(0.925)',\n }}\n />\n </HeaderIconButton>\n </InfoTooltip>\n <InfoTooltip description={TOOLTIP_TEXT.deletePanel}>\n <HeaderIconButton\n aria-label={ARIA_LABEL_TEXT.deletePanel(title)}\n size=\"small\"\n onClick={editHandlers.onDeletePanelClick}\n >\n <DeleteIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n </>\n );\n }\n return undefined;\n }, [editHandlers, title]);\n\n const moveAction = useMemo((): ReactNode | undefined => {\n if (editActions && !readHandlers?.isPanelViewed) {\n return (\n <InfoTooltip description={TOOLTIP_TEXT.movePanel}>\n <HeaderIconButton aria-label={ARIA_LABEL_TEXT.movePanel(title)} size=\"small\">\n <DragIcon className=\"drag-handle\" sx={{ cursor: 'grab' }} fontSize=\"inherit\" />\n </HeaderIconButton>\n </InfoTooltip>\n );\n }\n return undefined;\n }, [editActions, readHandlers, title]);\n\n const divider = <Box sx={{ flexGrow: 1 }}></Box>;\n\n // if the panel is in non-editing, non-fullscreen mode, show certain icons only on hover\n const OnHover = ({ children }: PropsWithChildren): ReactNode =>\n editHandlers === undefined && !readHandlers?.isPanelViewed ? (\n <Box sx={{ display: 'var(--panel-hover, none)' }}>{children}</Box>\n ) : (\n <>{children}</>\n );\n\n return (\n <>\n {/* small panel width: move all icons except move/grab to overflow menu */}\n <ConditionalBox\n sx={(theme) => ({\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).between(0, HEADER_SMALL_WIDTH)]: { display: 'flex' },\n })}\n >\n {divider}\n <OnHover>\n <OverflowMenu title={title}>\n {descriptionAction} {linksAction} {queryStateIndicator} {extraActions} {readActions} {editActions}\n </OverflowMenu>\n {pluginActions}\n {moveAction}\n </OnHover>\n </ConditionalBox>\n\n {/* medium panel width: move edit icons to overflow menu */}\n <ConditionalBox\n sx={(theme) => ({\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).between(HEADER_SMALL_WIDTH, HEADER_MEDIUM_WIDTH)]: {\n display: 'flex',\n },\n })}\n >\n <OnHover>\n {descriptionAction} {linksAction}\n </OnHover>\n {divider} {queryStateIndicator}\n <OnHover>\n {extraActions} {readActions} {pluginActions}\n <OverflowMenu title={title}>{editActions}</OverflowMenu>\n {moveAction}\n </OnHover>\n </ConditionalBox>\n\n {/* large panel width: show all icons in panel header */}\n <ConditionalBox\n sx={(theme) => ({\n // flip the logic here; if the browser (or jsdom) does not support container queries, always show all icons\n display: 'flex',\n [theme.containerQueries(HEADER_ACTIONS_CONTAINER_NAME).down(HEADER_MEDIUM_WIDTH)]: { display: 'none' },\n })}\n >\n <OnHover>\n {descriptionAction} {linksAction}\n </OnHover>\n {divider} {queryStateIndicator}\n <OnHover>\n {extraActions} {readActions} {pluginActions} {editActions} {moveAction}\n </OnHover>\n </ConditionalBox>\n </>\n );\n};\n\nconst OverflowMenu: React.FC<PropsWithChildren<{ title: string }>> = ({ children, title }) => {\n const [anchorPosition, setAnchorPosition] = useState<PopoverPosition>();\n\n // do not show overflow menu if there is no content (for example, edit actions are hidden)\n const hasContent = isValidElement(children) || (Array.isArray(children) && children.some(isValidElement));\n if (!hasContent) {\n return undefined;\n }\n\n const handleClick = (event: React.MouseEvent<HTMLElement>): void => {\n setAnchorPosition(event.currentTarget.getBoundingClientRect());\n };\n\n const handleClose = (): void => {\n setAnchorPosition(undefined);\n };\n\n const open = Boolean(anchorPosition);\n const id = open ? 'actions-menu' : undefined;\n\n return (\n <>\n <HeaderIconButton\n className=\"show-actions\"\n aria-describedby={id}\n onClick={handleClick}\n aria-label={ARIA_LABEL_TEXT.showPanelActions(title)}\n size=\"small\"\n >\n <MenuIcon fontSize=\"inherit\" />\n </HeaderIconButton>\n <Popover\n id={id}\n open={open}\n anchorReference=\"anchorPosition\"\n anchorPosition={anchorPosition}\n onClose={handleClose}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left',\n }}\n >\n <Stack direction=\"row\" alignItems=\"center\" sx={{ padding: 1 }} onClick={handleClose}>\n {children}\n </Stack>\n </Popover>\n </>\n );\n};\n"],"names":["Stack","Box","Popover","CircularProgress","styled","isValidElement","useMemo","useState","InfoTooltip","ArrowCollapseIcon","ArrowExpandIcon","PencilIcon","DeleteIcon","DragIcon","ContentCopyIcon","MenuIcon","AlertIcon","InformationOutlineIcon","ARIA_LABEL_TEXT","HEADER_ACTIONS_CONTAINER_NAME","HEADER_MEDIUM_WIDTH","HEADER_SMALL_WIDTH","TOOLTIP_TEXT","HeaderIconButton","PanelLinks","ConditionalBox","display","alignItems","flexGrow","justifyContent","PanelActions","editHandlers","readHandlers","extra","title","description","descriptionTooltipId","links","queryResults","pluginActions","descriptionAction","trim","length","id","enterDelay","aria-label","size","aria-describedby","aria-hidden","fontSize","sx","color","theme","palette","text","secondary","undefined","linksAction","extraActions","queryStateIndicator","hasData","some","q","data","isFetching","queryErrors","filter","error","errorTexts","map","e","message","toString","join","readActions","viewPanel","onClick","onViewPanelClick","isPanelViewed","editActions","editPanel","onEditPanelClick","duplicatePanel","onDuplicatePanelClick","transform","deletePanel","onDeletePanelClick","moveAction","movePanel","className","cursor","divider","OnHover","children","containerQueries","between","OverflowMenu","down","anchorPosition","setAnchorPosition","hasContent","Array","isArray","handleClick","event","currentTarget","getBoundingClientRect","handleClose","open","Boolean","showPanelActions","anchorReference","onClose","anchorOrigin","vertical","horizontal","direction","padding"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PanelHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelHeader.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAc,eAAe,EAAqB,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,SAAS,EAA+B,MAAM,2BAA2B,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAW,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAgB,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEjE,KAAK,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,mBAAmB,CAAC;AAE1E,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IACjD,YAAY,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,EAAE,EACF,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,cAAc,EAC3B,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,EAAE,EACF,KAAK,EACL,aAAa,EACb,GAAG,IAAI,EACR,EAAE,gBAAgB,GAAG,YAAY,CAmEjC"}
1
+ {"version":3,"file":"PanelHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Panel/PanelHeader.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAc,eAAe,EAAqB,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,SAAS,EAA+B,MAAM,2BAA2B,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEhD,OAAO,EAAgB,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEjE,KAAK,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,mBAAmB,CAAC;AAE1E,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC;IAC3E,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IACjD,YAAY,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,EAC1B,EAAE,EACF,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,cAAc,EAC3B,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,EAAE,EACF,KAAK,EACL,aAAa,EACb,GAAG,IAAI,EACR,EAAE,gBAAgB,GAAG,YAAY,CA2DjC"}
@@ -14,7 +14,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  import { CardHeader, Stack, Typography } from '@mui/material';
15
15
  import { combineSx } from '@perses-dev/components';
16
16
  import { useReplaceVariablesInString } from '@perses-dev/plugin-system';
17
- import { useMemo } from 'react';
18
17
  import { HEADER_ACTIONS_CONTAINER_NAME } from '../../constants';
19
18
  import { PanelActions } from './PanelActions';
20
19
  export function PanelHeader({ id, title: rawTitle, description: rawDescription, links, queryResults, readHandlers, editHandlers, sx, extra, pluginActions, ...rest }) {
@@ -22,12 +21,6 @@ export function PanelHeader({ id, title: rawTitle, description: rawDescription,
22
21
  const descriptionTooltipId = `${id}-description`;
23
22
  const title = useReplaceVariablesInString(rawTitle);
24
23
  const description = useReplaceVariablesInString(rawDescription);
25
- // Create the panelContentProps object with only queryResults
26
- const panelContentProps = useMemo(()=>({
27
- queryResults
28
- }), [
29
- queryResults
30
- ]);
31
24
  return /*#__PURE__*/ _jsx(CardHeader, {
32
25
  id: id,
33
26
  component: "header",
@@ -59,7 +52,7 @@ export function PanelHeader({ id, title: rawTitle, description: rawDescription,
59
52
  readHandlers: readHandlers,
60
53
  editHandlers: editHandlers,
61
54
  extra: extra,
62
- panelContentProps: panelContentProps,
55
+ queryResults: queryResults,
63
56
  pluginActions: pluginActions
64
57
  })
65
58
  ]
@@ -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 { 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, useMemo } 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 pluginActions?: ReactNode[]; // Add pluginActions prop\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 pluginActions,\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 // Create the panelContentProps object with only queryResults\n const panelContentProps = useMemo(\n () => ({\n queryResults,\n }),\n [queryResults]\n );\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 readHandlers={readHandlers}\n editHandlers={editHandlers}\n extra={extra}\n panelContentProps={panelContentProps}\n pluginActions={pluginActions}\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","useMemo","HEADER_ACTIONS_CONTAINER_NAME","PanelActions","PanelHeader","id","title","rawTitle","description","rawDescription","links","queryResults","readHandlers","editHandlers","sx","extra","pluginActions","rest","titleElementId","descriptionTooltipId","panelContentProps","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;AACnF,SAAkCC,OAAO,QAAQ,QAAQ;AACzD,SAASC,6BAA6B,QAAQ,kBAAkB;AAChE,SAASC,YAAY,QAA2B,iBAAiB;AAgBjE,OAAO,SAASC,YAAY,EAC1BC,EAAE,EACFC,OAAOC,QAAQ,EACfC,aAAaC,cAAc,EAC3BC,KAAK,EACLC,YAAY,EACZC,YAAY,EACZC,YAAY,EACZC,EAAE,EACFC,KAAK,EACLC,aAAa,EACb,GAAGC,MACc;IACjB,MAAMC,iBAAiB,GAAGb,GAAG,MAAM,CAAC;IACpC,MAAMc,uBAAuB,GAAGd,GAAG,YAAY,CAAC;IAEhD,MAAMC,QAAQN,4BAA4BO;IAC1C,MAAMC,cAAcR,4BAA4BS;IAEhD,6DAA6D;IAC7D,MAAMW,oBAAoBnB,QACxB,IAAO,CAAA;YACLU;QACF,CAAA,GACA;QAACA;KAAa;IAGhB,qBACE,KAACf;QACCS,IAAIA;QACJgB,WAAU;QACVC,mBAAiBJ;QACjBK,oBAAkBJ;QAClBK,iBAAiB;QACjBlB,qBACE,MAACT;YAAM4B,WAAU;;8BACf,KAAC3B;oBACCO,IAAIa;oBACJQ,SAAQ;oBACRZ,IAAI;wBACF,gEAAgE;wBAChE,+CAA+C;wBAC/Ca,YAAY;wBACZC,WAAW;wBACXC,YAAY;wBACZC,UAAU;wBACVC,cAAc;oBAChB;8BAECzB;;8BAEH,KAACH;oBACCG,OAAOA;oBACPE,aAAaA;oBACbW,sBAAsBA;oBACtBT,OAAOA;oBACPE,cAAcA;oBACdC,cAAcA;oBACdE,OAAOA;oBACPK,mBAAmBA;oBACnBJ,eAAeA;;;;QAIrBF,IAAIf,UACF,CAACiC,QAAW,CAAA;gBACVC,eAAe;gBACfC,eAAehC;gBACfiC,SAASH,MAAMI,OAAO,CAAC;gBACvBC,cAAc,CAAC,UAAU,EAAEL,MAAMM,OAAO,CAACC,OAAO,EAAE;gBAClD,0BAA0B;oBACxBT,UAAU;gBACZ;YACF,CAAA,GACAhB;QAED,GAAGG,IAAI;;AAGd"}
1
+ {"version":3,"sources":["../../../src/components/Panel/PanelHeader.tsx"],"sourcesContent":["// Copyright 2025 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { CardHeader, CardHeaderProps, Stack, Typography } from '@mui/material';\nimport { combineSx } from '@perses-dev/components';\nimport { Link } from '@perses-dev/core';\nimport { QueryData, useReplaceVariablesInString } from '@perses-dev/plugin-system';\nimport { ReactElement, ReactNode } from 'react';\nimport { HEADER_ACTIONS_CONTAINER_NAME } from '../../constants';\nimport { PanelActions, PanelActionsProps } from './PanelActions';\n\ntype OmittedProps = 'children' | 'action' | 'title' | 'disableTypography';\n\nexport interface PanelHeaderProps extends Omit<CardHeaderProps, OmittedProps> {\n id: string;\n title: string;\n description?: string;\n links?: Link[];\n extra?: ReactNode;\n queryResults: QueryData[];\n readHandlers?: PanelActionsProps['readHandlers'];\n editHandlers?: PanelActionsProps['editHandlers'];\n pluginActions?: ReactNode[]; // Add pluginActions prop\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 pluginActions,\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 readHandlers={readHandlers}\n editHandlers={editHandlers}\n extra={extra}\n queryResults={queryResults}\n pluginActions={pluginActions}\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","pluginActions","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;AAgBjE,OAAO,SAASC,YAAY,EAC1BC,EAAE,EACFC,OAAOC,QAAQ,EACfC,aAAaC,cAAc,EAC3BC,KAAK,EACLC,YAAY,EACZC,YAAY,EACZC,YAAY,EACZC,EAAE,EACFC,KAAK,EACLC,aAAa,EACb,GAAGC,MACc;IACjB,MAAMC,iBAAiB,GAAGb,GAAG,MAAM,CAAC;IACpC,MAAMc,uBAAuB,GAAGd,GAAG,YAAY,CAAC;IAEhD,MAAMC,QAAQL,4BAA4BM;IAC1C,MAAMC,cAAcP,4BAA4BQ;IAEhD,qBACE,KAACZ;QACCQ,IAAIA;QACJe,WAAU;QACVC,mBAAiBH;QACjBI,oBAAkBH;QAClBI,iBAAiB;QACjBjB,qBACE,MAACR;YAAM0B,WAAU;;8BACf,KAACzB;oBACCM,IAAIa;oBACJO,SAAQ;oBACRX,IAAI;wBACF,gEAAgE;wBAChE,+CAA+C;wBAC/CY,YAAY;wBACZC,WAAW;wBACXC,YAAY;wBACZC,UAAU;wBACVC,cAAc;oBAChB;8BAECxB;;8BAEH,KAACH;oBACCG,OAAOA;oBACPE,aAAaA;oBACbW,sBAAsBA;oBACtBT,OAAOA;oBACPE,cAAcA;oBACdC,cAAcA;oBACdE,OAAOA;oBACPJ,cAAcA;oBACdK,eAAeA;;;;QAIrBF,IAAId,UACF,CAAC+B,QAAW,CAAA;gBACVC,eAAe;gBACfC,eAAe/B;gBACfgC,SAASH,MAAMI,OAAO,CAAC;gBACvBC,cAAc,CAAC,UAAU,EAAEL,MAAMM,OAAO,CAACC,OAAO,EAAE;gBAClD,0BAA0B;oBACxBT,UAAU;gBACZ;YACF,CAAA,GACAf;QAED,GAAGG,IAAI;;AAGd"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@perses-dev/dashboards",
3
- "version": "0.0.0-snapshot-timeseries-panel-actions-e28c1fe",
3
+ "version": "0.0.0-snapshot-ts-panel-actions-76080ec",
4
4
  "description": "The dashboards feature in Perses",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/perses/perses/blob/main/README.md",
@@ -29,9 +29,9 @@
29
29
  "lint:fix": "eslint --fix src --ext .ts,.tsx"
30
30
  },
31
31
  "dependencies": {
32
- "@perses-dev/components": "0.0.0-snapshot-timeseries-panel-actions-e28c1fe",
33
- "@perses-dev/core": "0.0.0-snapshot-timeseries-panel-actions-e28c1fe",
34
- "@perses-dev/plugin-system": "0.0.0-snapshot-timeseries-panel-actions-e28c1fe",
32
+ "@perses-dev/components": "0.0.0-snapshot-ts-panel-actions-76080ec",
33
+ "@perses-dev/core": "0.0.0-snapshot-ts-panel-actions-76080ec",
34
+ "@perses-dev/plugin-system": "0.0.0-snapshot-ts-panel-actions-76080ec",
35
35
  "@types/react-grid-layout": "^1.3.2",
36
36
  "date-fns": "^4.1.0",
37
37
  "immer": "^10.1.1",
@@ -46,7 +46,7 @@
46
46
  "zustand": "^4.3.3"
47
47
  },
48
48
  "devDependencies": {
49
- "@perses-dev/internal-utils": "0.0.0-snapshot-timeseries-panel-actions-e28c1fe",
49
+ "@perses-dev/internal-utils": "0.0.0-snapshot-ts-panel-actions-76080ec",
50
50
  "history": "^5.3.0",
51
51
  "intersection-observer": "^0.12.2"
52
52
  },