From d7d0c104ab0f4fb7dd52f20a1bec096cc09d586f Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Thu, 4 Dec 2025 16:19:25 +0000 Subject: [PATCH] React 19: non-breaking type and test changes (#114760) non-breaking type and test changes needed for react 19 --- .../AutoSaveField/AutoSaveField.tsx | 2 +- .../src/components/Button/Button.tsx | 9 ++- .../grafana-ui/src/components/Card/Card.tsx | 4 +- .../src/components/Combobox/Combobox.test.tsx | 4 +- .../ConfirmButton/ConfirmButton.tsx | 2 +- .../src/components/Dropdown/Dropdown.tsx | 2 +- .../grafana-ui/src/components/Forms/Field.tsx | 4 +- .../src/components/QueryField/QueryField.tsx | 3 +- .../src/components/Select/SelectMenu.tsx | 2 +- .../grafana-ui/src/components/Text/Text.tsx | 5 +- .../components/transitions/FadeTransition.tsx | 2 +- .../transitions/SlideOutTransition.tsx | 2 +- .../src/graveyard/GraphNG/GraphNG.tsx | 4 +- packages/grafana-ui/src/utils/reactUtils.ts | 2 +- .../SendResetMailPage.test.tsx | 6 +- .../app/core/components/GraphNG/GraphNG.tsx | 4 +- .../alerting/unified/components/HoverCard.tsx | 2 +- .../NotificationPreview.tsx | 2 +- .../features/commandPalette/KBarResults.tsx | 2 +- .../sharing/ShareDrawer/ShareDrawer.test.tsx | 2 +- .../PanelEditor/OptionsPaneItemDescriptor.tsx | 2 +- .../containers/DashboardPageProxy.test.tsx | 56 +++++++------------ .../PublicDashboardPageProxy.test.tsx | 5 +- .../components/picker/DataSourceCard.tsx | 2 +- .../components/picker/DataSourceLogo.tsx | 2 +- .../TraceView/components/common/Popover.tsx | 2 +- .../components/common/SearchBarInput.tsx | 2 +- .../components/ExpressionTypeDropdown.tsx | 2 +- .../VizTypePicker/PanelTypeCard.tsx | 6 +- .../extensions/ExtensionErrorBoundary.tsx | 1 - .../plugins/extensions/utils.test.tsx | 4 -- .../regression/regressionEditor.tsx | 10 +++- .../ConfigEditor/DefaultSubscription.tsx | 2 +- .../QueryEditor/EditorField.tsx | 2 +- .../SearchTraceQLEditor/InlineSearchField.tsx | 2 +- 35 files changed, 82 insertions(+), 83 deletions(-) diff --git a/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.tsx b/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.tsx index f78262d0548..2cd0527bd12 100644 --- a/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.tsx +++ b/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.tsx @@ -19,7 +19,7 @@ export interface Props extends Omit { /** Custom error message to display on saving */ saveErrorMessage?: string; /** Input that will save its value on change */ - children: (onChange: (newValue: T) => void) => React.ReactElement; + children: (onChange: (newValue: T) => void) => React.ReactElement>; } /** diff --git a/packages/grafana-ui/src/components/Button/Button.tsx b/packages/grafana-ui/src/components/Button/Button.tsx index d8e6e54d3fa..19c9b704934 100644 --- a/packages/grafana-ui/src/components/Button/Button.tsx +++ b/packages/grafana-ui/src/components/Button/Button.tsx @@ -22,7 +22,7 @@ type BaseProps = { size?: ComponentSize; variant?: ButtonVariant; fill?: ButtonFill; - icon?: IconName | React.ReactElement; + icon?: IconName | React.ReactElement; className?: string; fullWidth?: boolean; type?: string; @@ -207,8 +207,13 @@ export const LinkButton = React.forwardRef( LinkButton.displayName = 'LinkButton'; +type IconElementProps = { + className?: string; + size?: IconSize; +}; + interface IconRendererProps { - icon?: IconName | React.ReactElement<{ className?: string; size?: IconSize }>; + icon?: IconName | React.ReactElement; size?: IconSize; className?: string; iconType?: IconType; diff --git a/packages/grafana-ui/src/components/Card/Card.tsx b/packages/grafana-ui/src/components/Card/Card.tsx index e30781db632..cf61b8e7bae 100644 --- a/packages/grafana-ui/src/components/Card/Card.tsx +++ b/packages/grafana-ui/src/components/Card/Card.tsx @@ -316,7 +316,9 @@ const BaseActions = ({ children, disabled, variant, className }: ActionsProps) = return (
{React.Children.map(children, (child) => { - return React.isValidElement(child) ? cloneElement(child, { disabled: isDisabled, ...child.props }) : null; + return React.isValidElement>(child) + ? cloneElement(child, child.type !== React.Fragment ? { disabled: isDisabled, ...child.props } : undefined) + : null; })}
); diff --git a/packages/grafana-ui/src/components/Combobox/Combobox.test.tsx b/packages/grafana-ui/src/components/Combobox/Combobox.test.tsx index b99e58a447b..3de37fd265b 100644 --- a/packages/grafana-ui/src/components/Combobox/Combobox.test.tsx +++ b/packages/grafana-ui/src/components/Combobox/Combobox.test.tsx @@ -530,8 +530,8 @@ describe('Combobox', () => { const input = screen.getByRole('combobox'); await user.click(input); + await user.type(input, 'fir'); await act(async () => { - await user.type(input, 'fir'); jest.advanceTimersByTime(500); // Custom value while typing }); @@ -604,8 +604,8 @@ describe('Combobox', () => { const input = screen.getByRole('combobox'); await user.click(input); + await user.type(input, 'Opt'); await act(async () => { - await user.type(input, 'Opt'); jest.advanceTimersByTime(500); // Custom value while typing }); diff --git a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx index 0a5e3db8688..b6a2b626325 100644 --- a/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx +++ b/packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx @@ -12,7 +12,7 @@ import { Button, ButtonVariant } from '../Button/Button'; export interface Props { /** Confirm action callback */ onConfirm(): void; - children: string | ReactElement; + children: string | ReactElement>; /** Custom button styles */ className?: string; /** Button size */ diff --git a/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx b/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx index b098665db7b..7251d2ed85c 100644 --- a/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx +++ b/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx @@ -24,7 +24,7 @@ import { TooltipPlacement } from '../Tooltip/types'; export interface Props { overlay: React.ReactElement | (() => React.ReactElement); placement?: TooltipPlacement; - children: React.ReactElement; + children: React.ReactElement>; root?: HTMLElement; /** Amount in pixels to nudge the dropdown vertically and horizontally, respectively. */ offset?: [number, number]; diff --git a/packages/grafana-ui/src/components/Forms/Field.tsx b/packages/grafana-ui/src/components/Forms/Field.tsx index 6c5884e04c9..1152f223cc2 100644 --- a/packages/grafana-ui/src/components/Forms/Field.tsx +++ b/packages/grafana-ui/src/components/Forms/Field.tsx @@ -12,7 +12,7 @@ import { Label } from './Label'; export interface FieldProps extends HTMLAttributes { /** Form input element, i.e Input or Switch */ - children: React.ReactElement; + children: React.ReactElement>; /** Label for the field */ label?: React.ReactNode; /** Description of the field */ @@ -85,7 +85,7 @@ export const Field = React.forwardRef(
{labelElement}
-
{React.cloneElement(children, childProps)}
+
{React.cloneElement(children, children.type !== React.Fragment ? childProps : undefined)}
{invalid && error && !horizontal && (
{ - this.editor = editor!; + this.editor = editor; }} schema={SCHEMA} autoCorrect={false} readOnly={this.props.disabled} onBlur={this.handleBlur} onClick={this.props.onClick} - // onKeyDown={this.onKeyDown} onChange={(change: { value: Value }) => { this.onChange(change.value, false); }} diff --git a/packages/grafana-ui/src/components/Select/SelectMenu.tsx b/packages/grafana-ui/src/components/Select/SelectMenu.tsx index 37bd1452e91..bdd0d446fd3 100644 --- a/packages/grafana-ui/src/components/Select/SelectMenu.tsx +++ b/packages/grafana-ui/src/components/Select/SelectMenu.tsx @@ -197,7 +197,7 @@ export const VirtualizedSelectMenu = ({ // check if a child has array children (and is therefore a react-select group) // we need to flatten these so the correct count and elements are passed to the virtualized list const hasArrayChildren = (child: React.ReactNode) => { - return React.isValidElement(child) && Array.isArray(child.props.children); + return React.isValidElement>(child) && Array.isArray(child.props.children); }; VirtualizedSelectMenu.displayName = 'VirtualizedSelectMenu'; diff --git a/packages/grafana-ui/src/components/Text/Text.tsx b/packages/grafana-ui/src/components/Text/Text.tsx index 56cb2b529bb..79313d32a6b 100644 --- a/packages/grafana-ui/src/components/Text/Text.tsx +++ b/packages/grafana-ui/src/components/Text/Text.tsx @@ -1,5 +1,6 @@ import { css } from '@emotion/css'; -import { createElement, CSSProperties } from 'react'; +import { CSSObject } from '@emotion/serialize'; +import { createElement } from 'react'; import * as React from 'react'; import { GrafanaTheme2, ThemeTypographyVariantTypes } from '@grafana/data'; @@ -25,7 +26,7 @@ export interface TextProps extends Omit, 'clas /** If true, numbers will have fixed width, useful for displaying tabular data. False by default */ tabular?: boolean; /** Whether to align the text to left, center or right */ - textAlignment?: CSSProperties['textAlign']; + textAlignment?: CSSObject['textAlign']; children: NonNullable; } diff --git a/packages/grafana-ui/src/components/transitions/FadeTransition.tsx b/packages/grafana-ui/src/components/transitions/FadeTransition.tsx index a50e650a77b..a3de969f0b8 100644 --- a/packages/grafana-ui/src/components/transitions/FadeTransition.tsx +++ b/packages/grafana-ui/src/components/transitions/FadeTransition.tsx @@ -8,7 +8,7 @@ import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '../../themes/ThemeContext'; type Props = { - children: React.ReactElement; + children: React.ReactElement>; visible: boolean; duration?: number; }; diff --git a/packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx b/packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx index 18151b51757..b32659a7648 100644 --- a/packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx +++ b/packages/grafana-ui/src/components/transitions/SlideOutTransition.tsx @@ -8,7 +8,7 @@ import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '../../themes/ThemeContext'; type Props = { - children: React.ReactElement; + children: React.ReactElement>; visible: boolean; size: number; diff --git a/packages/grafana-ui/src/graveyard/GraphNG/GraphNG.tsx b/packages/grafana-ui/src/graveyard/GraphNG/GraphNG.tsx index c7e87d55ba5..b5b2aaba1bd 100644 --- a/packages/grafana-ui/src/graveyard/GraphNG/GraphNG.tsx +++ b/packages/grafana-ui/src/graveyard/GraphNG/GraphNG.tsx @@ -19,7 +19,7 @@ import { import { VizLegendOptions } from '@grafana/schema'; import { PanelContext, PanelContextRoot } from '../../components/PanelChrome/PanelContext'; -import { VizLayout } from '../../components/VizLayout/VizLayout'; +import { VizLayout, VizLayoutLegendProps } from '../../components/VizLayout/VizLayout'; import { UPlotChart } from '../../components/uPlot/Plot'; import { AxisProps } from '../../components/uPlot/config/UPlotAxisBuilder'; import { Renderers, UPlotConfigBuilder } from '../../components/uPlot/config/UPlotConfigBuilder'; @@ -54,7 +54,7 @@ export interface GraphNGProps extends Themeable2 { prepConfig: (alignedFrame: DataFrame, allFrames: DataFrame[], getTimeRange: () => TimeRange) => UPlotConfigBuilder; propsToDiff?: Array; preparePlotFrame?: (frames: DataFrame[], dimFields: XYFieldMatchers) => DataFrame | null; - renderLegend: (config: UPlotConfigBuilder) => React.ReactElement | null; + renderLegend: (config: UPlotConfigBuilder) => React.ReactElement | null; /** * needed for propsToDiff to re-init the plot & config diff --git a/packages/grafana-ui/src/utils/reactUtils.ts b/packages/grafana-ui/src/utils/reactUtils.ts index 3a4b1ede950..5004b2934e3 100644 --- a/packages/grafana-ui/src/utils/reactUtils.ts +++ b/packages/grafana-ui/src/utils/reactUtils.ts @@ -2,7 +2,7 @@ import { ReactElement } from 'react'; import * as React from 'react'; /** Returns the ID value of the first, and only, child element */ -export function getChildId(children: ReactElement): string | undefined { +export function getChildId(children: ReactElement>): string | undefined { let inputId: unknown; // Get the first, and only, child to retrieve form input's id diff --git a/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx b/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx index 85500867968..6c83dd6aded 100644 --- a/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx +++ b/public/app/core/components/ForgottenPassword/SendResetMailPage.test.tsx @@ -1,4 +1,4 @@ -import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { SendResetMailPage } from './SendResetMailPage'; @@ -38,7 +38,7 @@ describe('VerifyEmail Page', () => { it('should pass validation checks for email field', async () => { render(); - fireEvent.click(screen.getByRole('button', { name: 'Send reset email' })); + await userEvent.click(screen.getByRole('button', { name: 'Send reset email' })); expect(await screen.findByText('Email or username is required')).toBeInTheDocument(); await userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com'); @@ -49,7 +49,7 @@ describe('VerifyEmail Page', () => { render(); await userEvent.type(screen.getByRole('textbox', { name: /User Enter your information/i }), 'test@gmail.com'); - fireEvent.click(screen.getByRole('button', { name: 'Send reset email' })); + await userEvent.click(screen.getByRole('button', { name: 'Send reset email' })); await waitFor(() => expect(postMock).toHaveBeenCalledWith('/api/user/password/send-reset-email', { userOrEmail: 'test@gmail.com', diff --git a/public/app/core/components/GraphNG/GraphNG.tsx b/public/app/core/components/GraphNG/GraphNG.tsx index 7094c137501..bb4df705772 100644 --- a/public/app/core/components/GraphNG/GraphNG.tsx +++ b/public/app/core/components/GraphNG/GraphNG.tsx @@ -15,7 +15,7 @@ import { TimeZone, } from '@grafana/data'; import { DashboardCursorSync, VizLegendOptions } from '@grafana/schema'; -import { Themeable2, VizLayout } from '@grafana/ui'; +import { Themeable2, VizLayout, VizLayoutLegendProps } from '@grafana/ui'; import { AxisProps, pluginLog, Renderers, ScaleProps, UPlotChart, UPlotConfigBuilder } from '@grafana/ui/internal'; import { GraphNGLegendEvent, XYFieldMatchers } from './types'; @@ -48,7 +48,7 @@ export interface GraphNGProps extends Themeable2 { ) => UPlotConfigBuilder; propsToDiff?: Array; preparePlotFrame?: (frames: DataFrame[], dimFields: XYFieldMatchers) => DataFrame | null; - renderLegend: (config: UPlotConfigBuilder) => React.ReactElement | null; + renderLegend: (config: UPlotConfigBuilder) => React.ReactElement | null; replaceVariables: InterpolateFunction; dataLinkPostProcessor?: DataLinkPostProcessor; cursorSync?: DashboardCursorSync; diff --git a/public/app/features/alerting/unified/components/HoverCard.tsx b/public/app/features/alerting/unified/components/HoverCard.tsx index 6c5577df37b..69d95fe11a6 100644 --- a/public/app/features/alerting/unified/components/HoverCard.tsx +++ b/public/app/features/alerting/unified/components/HoverCard.tsx @@ -7,7 +7,7 @@ import { GrafanaTheme2 } from '@grafana/data'; import { Popover as GrafanaPopover, PopoverController, Stack, useStyles2 } from '@grafana/ui'; export interface PopupCardProps { - children: ReactElement; + children: ReactElement>; header?: ReactNode; content: ReactElement; footer?: ReactNode; diff --git a/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.tsx b/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.tsx index 71b05c172cb..97f73b75b43 100644 --- a/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationPreview.tsx @@ -140,7 +140,7 @@ export const NotificationPreview = ({
Alertmanager: - + {alertManagerSource.name}
diff --git a/public/app/features/commandPalette/KBarResults.tsx b/public/app/features/commandPalette/KBarResults.tsx index 020c57ec42f..72a308b7971 100644 --- a/public/app/features/commandPalette/KBarResults.tsx +++ b/public/app/features/commandPalette/KBarResults.tsx @@ -19,7 +19,7 @@ interface RenderParams { interface KBarResultsProps { // eslint-disable-next-line @typescript-eslint/no-explicit-any items: any[]; - onRender: (params: RenderParams) => React.ReactElement; + onRender: (params: RenderParams) => React.ReactElement>; maxHeight?: number; } diff --git a/public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawer.test.tsx b/public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawer.test.tsx index 35eaec800d1..2c22cd5e88b 100644 --- a/public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawer.test.tsx +++ b/public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawer.test.tsx @@ -38,7 +38,7 @@ describe('ShareDrawer', () => { expect(locationService.getSearch().get('shareView')).toBe('link'); expect(await screen.findByText('Share externally')).toBeInTheDocument(); const closeButton = await screen.findByTestId(selectors.components.Drawer.General.close); - await act(() => userEvent.click(closeButton)); + await userEvent.click(closeButton); expect(locationService.getSearch().get('shareView')).toBe(null); }); diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx index 570461c3921..14de02d3c68 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor.tsx @@ -16,7 +16,7 @@ export interface OptionsPaneItemInfo { value?: any; description?: string; popularRank?: number; - render: (descriptor: OptionsPaneItemDescriptor) => React.ReactElement; + render: (descriptor: OptionsPaneItemDescriptor) => React.ReactElement>; skipField?: boolean; showIf?: () => boolean; /** Hook for controlling visibility */ diff --git a/public/app/features/dashboard/containers/DashboardPageProxy.test.tsx b/public/app/features/dashboard/containers/DashboardPageProxy.test.tsx index e26b1099d2d..5083affcf22 100644 --- a/public/app/features/dashboard/containers/DashboardPageProxy.test.tsx +++ b/public/app/features/dashboard/containers/DashboardPageProxy.test.tsx @@ -1,4 +1,4 @@ -import { act, screen, waitFor } from '@testing-library/react'; +import { screen, waitFor } from '@testing-library/react'; import { useParams } from 'react-router-dom-v5-compat'; import { Props } from 'react-virtualized-auto-sizer'; import { render } from 'test/test-utils'; @@ -120,10 +120,8 @@ describe('DashboardPageProxy', () => { it('home dashboard', async () => { getDashboardScenePageStateManager().setDashboardCache(HOME_DASHBOARD_CACHE_KEY, dashMock); - act(() => { - setup({ - route: { routeName: DashboardRoutes.Home, component: () => null, path: '/' }, - }); + setup({ + route: { routeName: DashboardRoutes.Home, component: () => null, path: '/' }, }); await waitFor(() => { @@ -134,11 +132,9 @@ describe('DashboardPageProxy', () => { it('uid dashboard', async () => { getDashboardScenePageStateManager().setDashboardCache('abc-def', dashMock); - act(() => { - setup({ - route: { routeName: DashboardRoutes.Normal, component: () => null, path: '/' }, - uid: 'abc-def', - }); + setup({ + route: { routeName: DashboardRoutes.Normal, component: () => null, path: '/' }, + uid: 'abc-def', }); await waitFor(() => { @@ -156,11 +152,9 @@ describe('DashboardPageProxy', () => { describe('when user can edit a dashboard ', () => { it('should not render DashboardScenePage if route is Home', async () => { getDashboardScenePageStateManager().setDashboardCache(HOME_DASHBOARD_CACHE_KEY, homeMockEditable); - act(() => { - setup({ - route: { routeName: DashboardRoutes.Home, component: () => null, path: '/' }, - uid: '', - }); + setup({ + route: { routeName: DashboardRoutes.Home, component: () => null, path: '/' }, + uid: '', }); await waitFor(() => { @@ -170,11 +164,9 @@ describe('DashboardPageProxy', () => { it('should not render DashboardScenePage if route is Normal and has uid', async () => { getDashboardScenePageStateManager().setDashboardCache('abc-def', dashMockEditable); - act(() => { - setup({ - route: { routeName: DashboardRoutes.Normal, component: () => null, path: '/' }, - uid: 'abc-def', - }); + setup({ + route: { routeName: DashboardRoutes.Normal, component: () => null, path: '/' }, + uid: 'abc-def', }); await waitFor(() => { expect(screen.queryAllByTestId('dashboard-scene-page')).toHaveLength(0); @@ -185,11 +177,9 @@ describe('DashboardPageProxy', () => { describe('when user can only view a dashboard ', () => { it('should render DashboardScenePage if route is Home', async () => { getDashboardScenePageStateManager().setDashboardCache(HOME_DASHBOARD_CACHE_KEY, homeMock); - act(() => { - setup({ - route: { routeName: DashboardRoutes.Home, component: () => null, path: '/' }, - uid: '', - }); + setup({ + route: { routeName: DashboardRoutes.Home, component: () => null, path: '/' }, + uid: '', }); await waitFor(() => { @@ -199,11 +189,9 @@ describe('DashboardPageProxy', () => { it('should render DashboardScenePage if route is Normal and has uid', async () => { getDashboardScenePageStateManager().setDashboardCache('uid', dashMock); - act(() => { - setup({ - route: { routeName: DashboardRoutes.Normal, component: () => null, path: '/' }, - uid: 'uid', - }); + setup({ + route: { routeName: DashboardRoutes.Normal, component: () => null, path: '/' }, + uid: 'uid', }); await waitFor(() => { expect(screen.queryAllByTestId('dashboard-scene-page')).toHaveLength(1); @@ -212,11 +200,9 @@ describe('DashboardPageProxy', () => { it('should render not DashboardScenePage if dashboard UID does not match route UID', async () => { getDashboardScenePageStateManager().setDashboardCache('uid', dashMock); - act(() => { - setup({ - route: { routeName: DashboardRoutes.Normal, component: () => null, path: '/' }, - uid: 'wrongUID', - }); + setup({ + route: { routeName: DashboardRoutes.Normal, component: () => null, path: '/' }, + uid: 'wrongUID', }); await waitFor(() => { expect(screen.queryAllByTestId('dashboard-scene-page')).toHaveLength(0); diff --git a/public/app/features/dashboard/containers/PublicDashboardPageProxy.test.tsx b/public/app/features/dashboard/containers/PublicDashboardPageProxy.test.tsx index 0bb44738440..495532e5951 100644 --- a/public/app/features/dashboard/containers/PublicDashboardPageProxy.test.tsx +++ b/public/app/features/dashboard/containers/PublicDashboardPageProxy.test.tsx @@ -5,7 +5,7 @@ import { render } from 'test/test-utils'; import { selectors as e2eSelectors } from '@grafana/e2e-selectors'; import { config, locationService } from '@grafana/runtime'; import { backendSrv } from 'app/core/services/backend_srv'; -import { DashboardRoutes } from 'app/types/dashboard'; +import { DashboardDTO, DashboardRoutes } from 'app/types/dashboard'; import PublicDashboardPageProxy, { PublicDashboardPageProxyProps } from './PublicDashboardPageProxy'; @@ -56,8 +56,7 @@ describe('PublicDashboardPageProxy', () => { // Mock the dashboard UID response so we don't get any refused connection errors // from this test (as the fetch polyfill means this logic would actually try and call the API) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - jest.spyOn(backendSrv, 'getPublicDashboardByUid').mockResolvedValue({ dashboard: {}, meta: {} } as any); + jest.spyOn(backendSrv, 'getPublicDashboardByUid').mockResolvedValue({ dashboard: {}, meta: {} } as DashboardDTO); }); describe('when scene feature enabled', () => { diff --git a/public/app/features/datasources/components/picker/DataSourceCard.tsx b/public/app/features/datasources/components/picker/DataSourceCard.tsx index 4f30c07d894..d85547fef49 100644 --- a/public/app/features/datasources/components/picker/DataSourceCard.tsx +++ b/public/app/features/datasources/components/picker/DataSourceCard.tsx @@ -54,7 +54,7 @@ export function DataSourceCard({
- {`${ds.meta.name} + {`${ds.meta.name} ); diff --git a/public/app/features/datasources/components/picker/DataSourceLogo.tsx b/public/app/features/datasources/components/picker/DataSourceLogo.tsx index c8bfcc4601d..69c43bc2898 100644 --- a/public/app/features/datasources/components/picker/DataSourceLogo.tsx +++ b/public/app/features/datasources/components/picker/DataSourceLogo.tsx @@ -20,7 +20,7 @@ export function DataSourceLogo(props: DataSourceLogoProps) { {`${dataSource.meta.name} ); } diff --git a/public/app/features/explore/TraceView/components/common/Popover.tsx b/public/app/features/explore/TraceView/components/common/Popover.tsx index adb3c052f10..9334491ec25 100644 --- a/public/app/features/explore/TraceView/components/common/Popover.tsx +++ b/public/app/features/explore/TraceView/components/common/Popover.tsx @@ -3,7 +3,7 @@ import { cloneElement, ReactElement, useRef } from 'react'; import { Popover as GrafanaPopover, PopoverController } from '@grafana/ui'; export type PopoverProps = { - children: ReactElement; + children: ReactElement>; content: ReactElement; overlayClassName?: string; }; diff --git a/public/app/features/explore/TraceView/components/common/SearchBarInput.tsx b/public/app/features/explore/TraceView/components/common/SearchBarInput.tsx index a6527ca1c0e..831aa856dbf 100644 --- a/public/app/features/explore/TraceView/components/common/SearchBarInput.tsx +++ b/public/app/features/explore/TraceView/components/common/SearchBarInput.tsx @@ -22,7 +22,7 @@ type Props = { onChange: (value: string) => void; }; -const SearchBarInput = memo(({ value, onChange }: Props) => { +const SearchBarInput = memo(({ value = '', onChange }: Props) => { const clearUiFind = () => { onChange(''); }; diff --git a/public/app/features/expressions/components/ExpressionTypeDropdown.tsx b/public/app/features/expressions/components/ExpressionTypeDropdown.tsx index bb84dcd076c..83d2b249441 100644 --- a/public/app/features/expressions/components/ExpressionTypeDropdown.tsx +++ b/public/app/features/expressions/components/ExpressionTypeDropdown.tsx @@ -15,7 +15,7 @@ const EXPRESSION_ICON_MAP = { } as const satisfies Record; interface ExpressionTypeDropdownProps { - children: ReactElement; + children: ReactElement>; handleOnSelect: (value: ExpressionQueryType) => void; } diff --git a/public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx b/public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx index 8070854ab9d..2125e645e60 100644 --- a/public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx +++ b/public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx @@ -55,7 +55,11 @@ const PanelTypeCardComponent = ({ isCurrent ? t('panel.panel-type-card.title-click-to-close', 'Click again to close this section') : plugin.name } > - +
{title}
diff --git a/public/app/features/plugins/extensions/ExtensionErrorBoundary.tsx b/public/app/features/plugins/extensions/ExtensionErrorBoundary.tsx index 5d85e16eee1..99886edf488 100644 --- a/public/app/features/plugins/extensions/ExtensionErrorBoundary.tsx +++ b/public/app/features/plugins/extensions/ExtensionErrorBoundary.tsx @@ -25,7 +25,6 @@ export const ExtensionErrorBoundary = ({ log.error(`Extension "${pluginId}/${extensionTitle}" failed to load.`, { message: error.message, componentStack: errorInfo.componentStack ?? '', - digest: errorInfo.digest ?? '', }); }} fallback={() => { diff --git a/public/app/features/plugins/extensions/utils.test.tsx b/public/app/features/plugins/extensions/utils.test.tsx index 2c1563f8f6c..4e00a80cf27 100644 --- a/public/app/features/plugins/extensions/utils.test.tsx +++ b/public/app/features/plugins/extensions/utils.test.tsx @@ -785,7 +785,6 @@ describe('Plugin Extensions / Utils', () => { expect(log.error).toHaveBeenCalledWith(`Extension "${pluginId}/${extensionTitle}" failed to load.`, { message: 'Test error', componentStack: expect.any(String), - digest: expect.any(String), }); expect(screen.getByText(`Extension failed to load: "${pluginId}/${extensionTitle}"`)).toBeVisible(); @@ -818,7 +817,6 @@ describe('Plugin Extensions / Utils', () => { expect(log.error).toHaveBeenCalledWith(`Extension "${pluginId}/${extensionTitle}" failed to load.`, { message: 'Test error', componentStack: expect.any(String), - digest: expect.any(String), }); expect(screen.getByText(`Extension failed to load: "${pluginId}/${extensionTitle}"`)).toBeVisible(); @@ -965,7 +963,6 @@ describe('Plugin Extensions / Utils', () => { expect(log.error).toHaveBeenCalledWith(`Extension "${pluginId}/${extensionTitle}" failed to load.`, { message: 'Test error', componentStack: expect.any(String), - digest: expect.any(String), }); }); @@ -995,7 +992,6 @@ describe('Plugin Extensions / Utils', () => { expect(log.error).toHaveBeenCalledWith(`Extension "${pluginId}/${extensionTitle}" failed to load.`, { message: 'Test error', componentStack: expect.any(String), - digest: expect.any(String), }); }); }); diff --git a/public/app/features/transformers/regression/regressionEditor.tsx b/public/app/features/transformers/regression/regressionEditor.tsx index 909e2b69285..a1a27af1d39 100644 --- a/public/app/features/transformers/regression/regressionEditor.tsx +++ b/public/app/features/transformers/regression/regressionEditor.tsx @@ -120,7 +120,15 @@ export const RegressionTransformerEditor = ({ ); }; -const RegressionField = ({ label, tooltip, children }: { label: string; tooltip?: string; children: ReactElement }) => ( +const RegressionField = ({ + label, + tooltip, + children, +}: { + label: string; + tooltip?: string; + children: ReactElement>; +}) => ( {children} diff --git a/public/app/plugins/datasource/azuremonitor/components/ConfigEditor/DefaultSubscription.tsx b/public/app/plugins/datasource/azuremonitor/components/ConfigEditor/DefaultSubscription.tsx index 0bd33039bda..91f5240a4b8 100644 --- a/public/app/plugins/datasource/azuremonitor/components/ConfigEditor/DefaultSubscription.tsx +++ b/public/app/plugins/datasource/azuremonitor/components/ConfigEditor/DefaultSubscription.tsx @@ -39,7 +39,7 @@ export const DefaultSubscription = (props: Props) => { let canceled = false; getSubscriptions().then((result) => { if (!canceled) { - updateSubscriptions(result, loadSubscriptionsClicked); + updateSubscriptions(result, Boolean(loadSubscriptionsClicked)); } }); return () => { diff --git a/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/EditorField.tsx b/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/EditorField.tsx index dd5b27f56c1..401a3ed4d5c 100644 --- a/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/EditorField.tsx +++ b/public/app/plugins/datasource/grafana-pyroscope-datasource/QueryEditor/EditorField.tsx @@ -7,7 +7,7 @@ import { Field, Icon, PopoverContent, ReactUtils, Tooltip, useStyles2 } from '@g interface EditorFieldProps extends ComponentProps { label: string; - children: React.ReactElement; + children: React.ReactElement>; width?: number | string; optional?: boolean; tooltip?: PopoverContent; diff --git a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/InlineSearchField.tsx b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/InlineSearchField.tsx index d4b0678069f..3f139f8c898 100644 --- a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/InlineSearchField.tsx +++ b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/InlineSearchField.tsx @@ -5,7 +5,7 @@ import { InlineFieldRow, InlineField } from '@grafana/ui'; interface Props { label: string; tooltip?: string; - children: React.ReactElement; + children: React.ReactElement>; } const SearchField = ({ label, tooltip, children }: Props) => { return (