Chore: Avoid explicit React.FC<Props> when possible (#64722)

This commit is contained in:
Ryan McKinley
2023-03-14 16:38:21 +02:00
committed by GitHub
parent cde1b5b162
commit d710507bc5
213 changed files with 485 additions and 498 deletions
+2 -2
View File
@@ -13,12 +13,12 @@ To access the theme in your styles, use the `useStyles` hook. It provides basic
> Please remember to put `getStyles` function at the end of the file! > Please remember to put `getStyles` function at the end of the file!
```tsx ```tsx
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '@grafana/ui'; import { useStyles2 } from '@grafana/ui';
import { css } from '@emotion/css'; import { css } from '@emotion/css';
const Foo: FC<FooProps> = () => { const Foo = (props: FooProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
// Use styles with classNames // Use styles with classNames
@@ -48,7 +48,7 @@ Wait a minute. Manipulating documents based on data? That's sounds an awful lot
In **SimplePanel.tsx**, change `SimplePanel` to return an `svg` with a `rect` element. In **SimplePanel.tsx**, change `SimplePanel` to return an `svg` with a `rect` element.
```ts ```ts
export const SimplePanel: React.FC<Props> = ({ options, data, width, height }) => { export const SimplePanel = ({ options, data, width, height }: Props) => {
const theme = useTheme(); const theme = useTheme();
return ( return (
@@ -196,7 +196,7 @@ import * as d3 from 'd3';
interface Props extends PanelProps<SimpleOptions> {} interface Props extends PanelProps<SimpleOptions> {}
export const SimplePanel: React.FC<Props> = ({ options, data, width, height }) => { export const SimplePanel = ({ options, data, width, height }: Props) => {
const theme = useTheme(); const theme = useTheme();
const values = [4, 8, 15, 16, 23, 42]; const values = [4, 8, 15, 16, 23, 42];
@@ -65,9 +65,9 @@ Let's add a tab for managing server instances.
```ts ```ts
import { AppRootProps } from '@grafana/data'; import { AppRootProps } from '@grafana/data';
import React, { FC } from 'react'; import React from 'react';
export const Instances: FC<AppRootProps> = ({ query, path, meta }) => { export const Instances = ({ query, path, meta }: AppRootProps) => {
return <p>Hello</p>; return <p>Hello</p>;
}; };
``` ```
@@ -1,8 +1,8 @@
export const componentTpl = `import React, { FC } from 'react'; export const componentTpl = `import React from 'react';
export interface Props {}; export interface Props {};
export const <%= name %>: FC<Props> = (props) => { export const <%= name %> = (props: Props) => {
return ( return (
<div>Hello world!</div> <div>Hello world!</div>
) )
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { DataFrame, DataLink, GrafanaTheme2 } from '@grafana/data'; import { DataFrame, DataLink, GrafanaTheme2 } from '@grafana/data';
@@ -18,7 +18,7 @@ export interface DataLinksListItemProps {
isEditing?: boolean; isEditing?: boolean;
} }
export const DataLinksListItem: FC<DataLinksListItemProps> = ({ link, onEdit, onRemove }) => { export const DataLinksListItem = ({ link, onEdit, onRemove }: DataLinksListItemProps) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getDataLinkListItemStyles(theme); const styles = getDataLinkListItemStyles(theme);
const { title = '', url = '' } = link; const { title = '', url = '' } = link;
@@ -1,4 +1,4 @@
import React, { ChangeEvent, MouseEvent, FC } from 'react'; import React, { ChangeEvent, MouseEvent } from 'react';
import { Button } from '../Button'; import { Button } from '../Button';
import { InlineField } from '../Forms/InlineField'; import { InlineField } from '../Forms/InlineField';
@@ -15,7 +15,7 @@ interface Props {
onClick: (event: MouseEvent<HTMLButtonElement>) => void; onClick: (event: MouseEvent<HTMLButtonElement>) => void;
} }
export const CertificationKey: FC<Props> = ({ hasCert, label, onChange, onClick, placeholder }) => { export const CertificationKey = ({ hasCert, label, onChange, onClick, placeholder }: Props) => {
return ( return (
<InlineFieldRow> <InlineFieldRow>
<InlineField label={label} labelWidth={14} disabled={hasCert}> <InlineField label={label} labelWidth={14} disabled={hasCert}>
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, FormEvent, MouseEvent, useState } from 'react'; import React, { FormEvent, MouseEvent, useState } from 'react';
import { dateMath, dateTime, getDefaultTimeRange, GrafanaTheme2, TimeRange, TimeZone } from '@grafana/data'; import { dateMath, dateTime, getDefaultTimeRange, GrafanaTheme2, TimeRange, TimeZone } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@@ -35,7 +35,7 @@ export interface TimeRangeInputProps {
const noop = () => {}; const noop = () => {};
export const TimeRangeInput: FC<TimeRangeInputProps> = ({ export const TimeRangeInput = ({
value, value,
onChange, onChange,
onChangeTimeZone = noop, onChangeTimeZone = noop,
@@ -46,7 +46,7 @@ export const TimeRangeInput: FC<TimeRangeInputProps> = ({
isReversed = true, isReversed = true,
hideQuickRanges = false, hideQuickRanges = false,
disabled = false, disabled = false,
}) => { }: TimeRangeInputProps) => {
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme, disabled); const styles = getStyles(theme, disabled);
@@ -1,6 +1,6 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import { isString } from 'lodash'; import { isString } from 'lodash';
import React, { FC, useCallback, useState } from 'react'; import React, { useCallback, useState } from 'react';
import { getTimeZoneInfo, GrafanaTheme2, TimeZone } from '@grafana/data'; import { getTimeZoneInfo, GrafanaTheme2, TimeZone } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@@ -23,7 +23,7 @@ interface Props {
onChangeFiscalYearStartMonth?: (month: number) => void; onChangeFiscalYearStartMonth?: (month: number) => void;
} }
export const TimePickerFooter: FC<Props> = (props) => { export const TimePickerFooter = (props: Props) => {
const { const {
timeZone, timeZone,
fiscalYearStartMonth, fiscalYearStartMonth,
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
@@ -9,7 +9,7 @@ export interface Props {
children: JSX.Element | string; children: JSX.Element | string;
} }
const EmptySearchResult: FC<Props> = ({ children }) => { const EmptySearchResult = ({ children }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return <div className={styles.container}>{children}</div>; return <div className={styles.container}>{children}</div>;
}; };
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, HTMLProps } from 'react'; import React, { HTMLProps } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
@@ -13,7 +13,7 @@ export interface Props extends Omit<HTMLProps<HTMLFieldSetElement>, 'label'> {
label?: React.ReactNode; label?: React.ReactNode;
} }
export const FieldSet: FC<Props> = ({ label, children, className, ...rest }) => { export const FieldSet = ({ label, children, className, ...rest }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme); const styles = getStyles(theme);
@@ -1,5 +1,5 @@
import { cx, css } from '@emotion/css'; import { cx, css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
@@ -29,7 +29,7 @@ export interface Props extends Omit<FieldProps, 'css' | 'horizontal' | 'descript
interactive?: boolean; interactive?: boolean;
} }
export const InlineField: FC<Props> = ({ export const InlineField = ({
children, children,
label, label,
tooltip, tooltip,
@@ -46,7 +46,7 @@ export const InlineField: FC<Props> = ({
transparent, transparent,
interactive, interactive,
...htmlProps ...htmlProps
}) => { }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme, grow, shrink); const styles = getStyles(theme, grow, shrink);
const inputId = htmlFor ?? getChildId(children); const inputId = htmlFor ?? getChildId(children);
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, ReactNode } from 'react'; import React, { ReactNode } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@@ -28,7 +28,7 @@ export interface Props {
} }
/** @alpha */ /** @alpha */
export const PageToolbar: FC<Props> = React.memo( export const PageToolbar = React.memo(
({ ({
title, title,
section, section,
@@ -44,7 +44,7 @@ export const PageToolbar: FC<Props> = React.memo(
/** main nav-container aria-label **/ /** main nav-container aria-label **/
'aria-label': ariaLabel, 'aria-label': ariaLabel,
buttonOverflowAlignment = 'right', buttonOverflowAlignment = 'right',
}) => { }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
/** /**
@@ -1,5 +1,5 @@
import { cx, css } from '@emotion/css'; import { cx, css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { stylesFactory } from '../../themes'; import { stylesFactory } from '../../themes';
import { Icon } from '../Icon/Icon'; import { Icon } from '../Icon/Icon';
@@ -28,8 +28,7 @@ export type Props = {
/** /**
* @public * @public
*/ */
export const Spinner: FC<Props> = (props: Props) => { export const Spinner = ({ className, inline = false, iconClassName, style, size = 16 }: Props) => {
const { className, inline = false, iconClassName, style, size = 16 } = props;
const styles = getStyles(size, inline); const styles = getStyles(size, inline);
return ( return (
<div data-testid="Spinner" style={style} className={cx(styles.wrapper, className)}> <div data-testid="Spinner" style={style} className={cx(styles.wrapper, className)}>
@@ -1,5 +1,5 @@
import { isFunction } from 'lodash'; import { isFunction } from 'lodash';
import React, { FC } from 'react'; import React from 'react';
import { ThresholdsConfig, ThresholdsMode, VizOrientation, getFieldConfigWithMinMax } from '@grafana/data'; import { ThresholdsConfig, ThresholdsMode, VizOrientation, getFieldConfigWithMinMax } from '@grafana/data';
import { BarGaugeDisplayMode, BarGaugeValueMode } from '@grafana/schema'; import { BarGaugeDisplayMode, BarGaugeValueMode } from '@grafana/schema';
@@ -24,7 +24,7 @@ const defaultScale: ThresholdsConfig = {
], ],
}; };
export const BarGaugeCell: FC<TableCellProps> = (props) => { export const BarGaugeCell = (props: TableCellProps) => {
const { field, innerWidth, tableStyles, cell, cellProps, row } = props; const { field, innerWidth, tableStyles, cell, cellProps, row } = props;
const displayValue = field.display!(cell.value); const displayValue = field.display!(cell.value);
const cellOptions = getCellOptions(field); const cellOptions = getCellOptions(field);
@@ -1,5 +1,5 @@
import { cx } from '@emotion/css'; import { cx } from '@emotion/css';
import React, { FC, ReactElement } from 'react'; import React, { ReactElement } from 'react';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import { DisplayValue, formattedValueToString } from '@grafana/data'; import { DisplayValue, formattedValueToString } from '@grafana/data';
@@ -15,7 +15,7 @@ import { TableStyles } from './styles';
import { TableCellDisplayMode, TableCellProps, TableFieldOptions } from './types'; import { TableCellDisplayMode, TableCellProps, TableFieldOptions } from './types';
import { getCellOptions } from './utils'; import { getCellOptions } from './utils';
export const DefaultCell: FC<TableCellProps> = (props) => { export const DefaultCell = (props: TableCellProps) => {
const { field, cell, tableStyles, row, cellProps } = props; const { field, cell, tableStyles, row, cellProps } = props;
const inspectEnabled = Boolean((field.config.custom as TableFieldOptions)?.inspect); const inspectEnabled = Boolean((field.config.custom as TableFieldOptions)?.inspect);
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, useCallback, useMemo, useRef, useState } from 'react'; import React, { useCallback, useMemo, useRef, useState } from 'react';
import { Field, GrafanaTheme2 } from '@grafana/data'; import { Field, GrafanaTheme2 } from '@grafana/data';
@@ -16,7 +16,7 @@ interface Props {
field?: Field; field?: Field;
} }
export const Filter: FC<Props> = ({ column, field, tableStyles }) => { export const Filter = ({ column, field, tableStyles }: Props) => {
const ref = useRef<HTMLButtonElement>(null); const ref = useRef<HTMLButtonElement>(null);
const [isPopoverVisible, setPopoverVisible] = useState<boolean>(false); const [isPopoverVisible, setPopoverVisible] = useState<boolean>(false);
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { FixedSizeList as List } from 'react-window'; import { FixedSizeList as List } from 'react-window';
import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { GrafanaTheme2, SelectableValue } from '@grafana/data';
@@ -17,7 +17,7 @@ interface Props {
const ITEM_HEIGHT = 28; const ITEM_HEIGHT = 28;
const MIN_HEIGHT = ITEM_HEIGHT * 5; const MIN_HEIGHT = ITEM_HEIGHT * 5;
export const FilterList: FC<Props> = ({ options, values, caseSensitive, onChange }) => { export const FilterList = ({ options, values, caseSensitive, onChange }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getStyles(theme); const styles = getStyles(theme);
const [searchFilter, setSearchFilter] = useState(''); const [searchFilter, setSearchFilter] = useState('');
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import { Field, GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Field, GrafanaTheme2, SelectableValue } from '@grafana/data';
@@ -17,7 +17,7 @@ interface Props {
field?: Field; field?: Field;
} }
export const FilterPopup: FC<Props> = ({ column: { preFilteredRows, filterValue, setFilter }, onClose, field }) => { export const FilterPopup = ({ column: { preFilteredRows, filterValue, setFilter }, onClose, field }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const uniqueValues = useMemo(() => calculateUniqueFieldValues(preFilteredRows, field), [preFilteredRows, field]); const uniqueValues = useMemo(() => calculateUniqueFieldValues(preFilteredRows, field), [preFilteredRows, field]);
const options = useMemo(() => valuesToOptions(uniqueValues), [uniqueValues]); const options = useMemo(() => valuesToOptions(uniqueValues), [uniqueValues]);
@@ -1,5 +1,5 @@
import { cx } from '@emotion/css'; import { cx } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { useStyles2 } from '../../themes'; import { useStyles2 } from '../../themes';
import { getCellLinks } from '../../utils'; import { getCellLinks } from '../../utils';
@@ -8,7 +8,7 @@ import { DataLinksContextMenu } from '../DataLinks/DataLinksContextMenu';
import { TableCellProps } from './types'; import { TableCellProps } from './types';
export const ImageCell: FC<TableCellProps> = (props) => { export const ImageCell = (props: TableCellProps) => {
const { field, cell, tableStyles, row, cellProps } = props; const { field, cell, tableStyles, row, cellProps } = props;
const displayValue = field.display!(cell.value); const displayValue = field.display!(cell.value);
@@ -1,5 +1,5 @@
import { isArray } from 'lodash'; import { isArray } from 'lodash';
import React, { FC } from 'react'; import React from 'react';
import { import {
ArrayVector, ArrayVector,
@@ -37,7 +37,7 @@ export const defaultSparklineCellConfig: GraphFieldConfig = {
showPoints: VisibilityMode.Never, showPoints: VisibilityMode.Never,
}; };
export const SparklineCell: FC<TableCellProps> = (props) => { export const SparklineCell = (props: TableCellProps) => {
const { field, innerWidth, tableStyles, cell, cellProps } = props; const { field, innerWidth, tableStyles, cell, cellProps } = props;
const sparkline = getSparkline(cell.value); const sparkline = getSparkline(cell.value);
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Cell } from 'react-table'; import { Cell } from 'react-table';
import { TableStyles } from './styles'; import { TableStyles } from './styles';
@@ -13,7 +13,7 @@ export interface Props {
userProps?: object; userProps?: object;
} }
export const TableCell: FC<Props> = ({ cell, tableStyles, onCellFilterAdded, userProps }) => { export const TableCell = ({ cell, tableStyles, onCellFilterAdded, userProps }: Props) => {
const cellProps = cell.getCellProps(); const cellProps = cell.getCellProps();
const field = (cell.column as unknown as GrafanaTableColumn).field; const field = (cell.column as unknown as GrafanaTableColumn).field;
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2, locale } from '@grafana/data'; import { GrafanaTheme2, locale } from '@grafana/data';
@@ -24,7 +24,7 @@ export interface CounterProps {
value: number; value: number;
} }
export const Counter: FC<CounterProps> = ({ value }) => { export const Counter = ({ value }: CounterProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return <span className={styles.counter}>{locale(value, 0).text}</span>; return <span className={styles.counter}>{locale(value, 0).text}</span>;
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, HTMLAttributes, ReactNode } from 'react'; import React, { HTMLAttributes, ReactNode } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
@@ -17,7 +17,7 @@ const getTabContentStyle = stylesFactory((theme: GrafanaTheme2) => {
}; };
}); });
export const TabContent: FC<Props> = ({ children, className, ...restProps }) => { export const TabContent = ({ children, className, ...restProps }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const styles = getTabContentStyle(theme); const styles = getTabContentStyle(theme);
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { useTheme2 } from '../../themes'; import { useTheme2 } from '../../themes';
@@ -7,7 +7,7 @@ export interface Props {
children?: React.ReactNode; children?: React.ReactNode;
} }
export const DashboardStoryCanvas: FC<Props> = ({ children }) => { export const DashboardStoryCanvas = ({ children }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const style = css` const style = css`
width: 100%; width: 100%;
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { useTheme2 } from '../../themes/ThemeContext'; import { useTheme2 } from '../../themes/ThemeContext';
@@ -8,7 +8,7 @@ export interface Props {
children?: React.ReactNode; children?: React.ReactNode;
} }
export const StoryExample: FC<Props> = ({ name, children }) => { export const StoryExample = ({ name, children }: Props) => {
const theme = useTheme2(); const theme = useTheme2();
const style = css` const style = css`
width: 100%; width: 100%;
@@ -1,4 +1,4 @@
import React, { FC, CSSProperties } from 'react'; import React, { CSSProperties } from 'react';
import Transition, { ExitHandler } from 'react-transition-group/Transition'; import Transition, { ExitHandler } from 'react-transition-group/Transition';
interface Props { interface Props {
@@ -9,7 +9,7 @@ interface Props {
onExited?: ExitHandler<HTMLDivElement>; onExited?: ExitHandler<HTMLDivElement>;
} }
export const FadeIn: FC<Props> = (props) => { export const FadeIn = (props: Props) => {
const defaultStyle: CSSProperties = { const defaultStyle: CSSProperties = {
transition: `opacity ${props.duration}ms linear`, transition: `opacity ${props.duration}ms linear`,
opacity: 0, opacity: 0,
@@ -1,4 +1,4 @@
import React, { FC, SyntheticEvent } from 'react'; import React, { SyntheticEvent } from 'react';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { Tooltip, Form, Field, VerticalGroup, Button } from '@grafana/ui'; import { Tooltip, Form, Field, VerticalGroup, Button } from '@grafana/ui';
@@ -15,7 +15,7 @@ interface PasswordDTO {
confirmNew: string; confirmNew: string;
} }
export const ChangePassword: FC<Props> = ({ onSubmit, onSkip }) => { export const ChangePassword = ({ onSubmit, onSkip }: Props) => {
const submit = (passwords: PasswordDTO) => { const submit = (passwords: PasswordDTO) => {
onSubmit(passwords.newPassword); onSubmit(passwords.newPassword);
}; };
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { GrafanaRouteComponentProps } from 'app/core/navigation/types'; import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
@@ -9,7 +9,7 @@ import { ChangePassword } from './ChangePassword';
export interface Props extends GrafanaRouteComponentProps<{}, { code: string }> {} export interface Props extends GrafanaRouteComponentProps<{}, { code: string }> {}
export const ChangePasswordPage: FC<Props> = (props) => { export const ChangePasswordPage = (props: Props) => {
return ( return (
<LoginLayout> <LoginLayout>
<InnerBox> <InnerBox>
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, ReactElement } from 'react'; import React, { ReactElement } from 'react';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { Button, Form, Input, Field } from '@grafana/ui'; import { Button, Form, Input, Field } from '@grafana/ui';
@@ -26,7 +26,7 @@ export const submitButton = css`
width: 100%; width: 100%;
`; `;
export const LoginForm: FC<Props> = ({ children, onSubmit, isLoggingIn, passwordHint, loginHint }) => { export const LoginForm = ({ children, onSubmit, isLoggingIn, passwordHint, loginHint }: Props) => {
return ( return (
<div className={wrapperStyles}> <div className={wrapperStyles}>
<Form onSubmit={onSubmit} validateOn="onChange"> <Form onSubmit={onSubmit} validateOn="onChange">
@@ -1,10 +1,10 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { LinkButton, VerticalGroup } from '@grafana/ui'; import { LinkButton, VerticalGroup } from '@grafana/ui';
import { getConfig } from 'app/core/config'; import { getConfig } from 'app/core/config';
export const UserSignup: FC<{}> = () => { export const UserSignup = () => {
const href = getConfig().verifyEmailEnabled ? `${getConfig().appSubUrl}/verify` : `${getConfig().appSubUrl}/signup`; const href = getConfig().verifyEmailEnabled ? `${getConfig().appSubUrl}/verify` : `${getConfig().appSubUrl}/signup`;
const paddingTop = css({ paddingTop: '16px' }); const paddingTop = css({ paddingTop: '16px' });
@@ -1,5 +1,5 @@
import debounce from 'debounce-promise'; import debounce from 'debounce-promise';
import React, { FC } from 'react'; import React from 'react';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { AsyncSelect } from '@grafana/ui'; import { AsyncSelect } from '@grafana/ui';
@@ -31,7 +31,7 @@ interface Props {
/** /**
* @deprecated prefer using dashboard uid rather than id * @deprecated prefer using dashboard uid rather than id
*/ */
export const DashboardPickerByID: FC<Props> = ({ export const DashboardPickerByID = ({
onChange: propsOnChange, onChange: propsOnChange,
value, value,
width, width,
@@ -41,7 +41,7 @@ export const DashboardPickerByID: FC<Props> = ({
id, id,
optionLabel = 'label', optionLabel = 'label',
excludedDashboards, excludedDashboards,
}) => { }: Props) => {
const debouncedSearch = debounce((query: string) => getDashboards(query || '', optionLabel, excludedDashboards), 300); const debouncedSearch = debounce((query: string) => getDashboards(query || '', optionLabel, excludedDashboards), 300);
const option = value ? { value, [optionLabel]: value[optionLabel] } : undefined; const option = value ? { value, [optionLabel]: value[optionLabel] } : undefined;
const onChange = (item: SelectableValue<DashboardPickerItem>) => { const onChange = (item: SelectableValue<DashboardPickerItem>) => {
@@ -1,6 +1,6 @@
// Libraries // Libraries
import { cx } from '@emotion/css'; import { cx } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
// Components // Components
import PageLoader from '../PageLoader/PageLoader'; import PageLoader from '../PageLoader/PageLoader';
@@ -11,6 +11,6 @@ interface Props {
className?: string; className?: string;
} }
export const PageContents: FC<Props> = ({ isLoading, children, className }) => { export const PageContents = ({ isLoading, children, className }: Props) => {
return <div className={cx('page-container', 'page-body', className)}>{isLoading ? <PageLoader /> : children}</div>; return <div className={cx('page-container', 'page-body', className)}>{isLoading ? <PageLoader /> : children}</div>;
}; };
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { NavModelItem, NavModelBreadcrumb, GrafanaTheme2 } from '@grafana/data'; import { NavModelItem, NavModelBreadcrumb, GrafanaTheme2 } from '@grafana/data';
import { Tab, TabsBar, Icon, useStyles2, toIconName } from '@grafana/ui'; import { Tab, TabsBar, Icon, useStyles2, toIconName } from '@grafana/ui';
@@ -86,7 +86,7 @@ const Navigation = ({ children }: { children: NavModelItem[] }) => {
); );
}; };
export const PageHeader: FC<Props> = ({ navItem: model, renderTitle, actions, info, subTitle }) => { export const PageHeader = ({ navItem: model, renderTitle, actions, info, subTitle }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
if (!model) { if (!model) {
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { LoadingPlaceholder } from '@grafana/ui'; import { LoadingPlaceholder } from '@grafana/ui';
@@ -6,7 +6,7 @@ interface Props {
pageName?: string; pageName?: string;
} }
const PageLoader: FC<Props> = ({ pageName = '' }) => { const PageLoader = ({ pageName = '' }: Props) => {
const loadingText = `Loading ${pageName}...`; const loadingText = `Loading ${pageName}...`;
return ( return (
<div className="page-loader-wrapper"> <div className="page-loader-wrapper">
@@ -1,5 +1,5 @@
// Libraries // Libraries
import React, { FC } from 'react'; import React from 'react';
import PageLoader from '../PageLoader/PageLoader'; import PageLoader from '../PageLoader/PageLoader';
@@ -9,7 +9,7 @@ interface Props {
className?: string; className?: string;
} }
export const PageContents: FC<Props> = ({ isLoading, children, className }) => { export const PageContents = ({ isLoading, children, className }: Props) => {
let content = className ? <div className={className}>{children}</div> : children; let content = className ? <div className={className}>{children}</div> : children;
return <>{isLoading ? <PageLoader /> : content}</>; return <>{isLoading ? <PageLoader /> : content}</>;
@@ -1,4 +1,4 @@
import React, { FC, useState } from 'react'; import React, { useState } from 'react';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { Input, IconButton } from '@grafana/ui'; import { Input, IconButton } from '@grafana/ui';
@@ -10,7 +10,7 @@ export interface Props {
passwordHint?: string; passwordHint?: string;
} }
export const PasswordField: FC<Props> = React.forwardRef<HTMLInputElement, Props>( export const PasswordField = React.forwardRef<HTMLInputElement, Props>(
({ autoComplete, autoFocus, id, passwordHint, ...props }, ref) => { ({ autoComplete, autoFocus, id, passwordHint, ...props }, ref) => {
const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
@@ -1,4 +1,4 @@
import React, { FC, useEffect } from 'react'; import React, { useEffect } from 'react';
import { useAsyncFn } from 'react-use'; import { useAsyncFn } from 'react-use';
import { contextSrv } from 'app/core/core'; import { contextSrv } from 'app/core/core';
@@ -29,7 +29,7 @@ export interface Props {
maxWidth?: string | number; maxWidth?: string | number;
} }
export const TeamRolePicker: FC<Props> = ({ export const TeamRolePicker = ({
teamId, teamId,
roleOptions, roleOptions,
disabled, disabled,
@@ -37,7 +37,7 @@ export const TeamRolePicker: FC<Props> = ({
pendingRoles, pendingRoles,
apply = false, apply = false,
maxWidth, maxWidth,
}) => { }: Props) => {
const [{ loading, value: appliedRoles = [] }, getTeamRoles] = useAsyncFn(async () => { const [{ loading, value: appliedRoles = [] }, getTeamRoles] = useAsyncFn(async () => {
try { try {
if (apply && Boolean(pendingRoles?.length)) { if (apply && Boolean(pendingRoles?.length)) {
@@ -1,4 +1,4 @@
import React, { FC, useEffect } from 'react'; import React, { useEffect } from 'react';
import { useAsyncFn } from 'react-use'; import { useAsyncFn } from 'react-use';
import { contextSrv } from 'app/core/core'; import { contextSrv } from 'app/core/core';
@@ -32,7 +32,7 @@ export interface Props {
maxWidth?: string | number; maxWidth?: string | number;
} }
export const UserRolePicker: FC<Props> = ({ export const UserRolePicker = ({
basicRole, basicRole,
userId, userId,
orgId, orgId,
@@ -44,7 +44,7 @@ export const UserRolePicker: FC<Props> = ({
onApplyRoles, onApplyRoles,
pendingRoles, pendingRoles,
maxWidth, maxWidth,
}) => { }: Props) => {
const [{ loading, value: appliedRoles = [] }, getUserRoles] = useAsyncFn(async () => { const [{ loading, value: appliedRoles = [] }, getUserRoles] = useAsyncFn(async () => {
try { try {
if (apply && Boolean(pendingRoles?.length)) { if (apply && Boolean(pendingRoles?.length)) {
@@ -1,5 +1,5 @@
import { flatten } from 'lodash'; import { flatten } from 'lodash';
import React, { useMemo, useCallback, FC } from 'react'; import React, { useMemo, useCallback } from 'react';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { LegacyForms } from '@grafana/ui'; import { LegacyForms } from '@grafana/ui';
@@ -16,7 +16,7 @@ export interface Props {
variables?: Variable[]; variables?: Variable[];
} }
export const MetricSelect: FC<Props> = (props) => { export const MetricSelect = (props: Props) => {
const { value, placeholder, className, isSearchable, onChange } = props; const { value, placeholder, className, isSearchable, onChange } = props;
const options = useSelectOptions(props); const options = useSelectOptions(props);
const selected = useSelectedOption(options, value); const selected = useSelectedOption(options, value);
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { getBackendSrv } from '@grafana/runtime'; import { getBackendSrv } from '@grafana/runtime';
import { Form, Field, Input, Button, HorizontalGroup, LinkButton, FormAPI } from '@grafana/ui'; import { Form, Field, Input, Button, HorizontalGroup, LinkButton, FormAPI } from '@grafana/ui';
@@ -27,7 +27,7 @@ interface QueryParams {
interface Props extends GrafanaRouteComponentProps<{}, QueryParams> {} interface Props extends GrafanaRouteComponentProps<{}, QueryParams> {}
export const SignupPage: FC<Props> = (props) => { export const SignupPage = (props: Props) => {
const notifyApp = useAppNotification(); const notifyApp = useAppNotification();
const onSubmit = async (formData: SignupDTO) => { const onSubmit = async (formData: SignupDTO) => {
if (formData.name === '') { if (formData.name === '') {
+2 -2
View File
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, PureComponent, useRef, useState } from 'react'; import React, { PureComponent, useRef, useState } from 'react';
import { Button, ConfirmButton, ConfirmModal, Input, LegacyInputStatus } from '@grafana/ui'; import { Button, ConfirmButton, ConfirmModal, Input, LegacyInputStatus } from '@grafana/ui';
import { contextSrv } from 'app/core/core'; import { contextSrv } from 'app/core/core';
@@ -303,7 +303,7 @@ interface LockedRowProps {
lockMessage?: string; lockMessage?: string;
} }
export const LockedRow: FC<LockedRowProps> = ({ label, value, lockMessage }) => { export const LockedRow = ({ label, value, lockMessage }: LockedRowProps) => {
const lockMessageClass = css` const lockMessageClass = css`
font-style: italic; font-style: italic;
margin-right: 0.6rem; margin-right: 0.6rem;
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Alert, Icon } from '@grafana/ui'; import { Alert, Icon } from '@grafana/ui';
import { AppNotificationSeverity, LdapConnectionInfo, LdapServerInfo } from 'app/types'; import { AppNotificationSeverity, LdapConnectionInfo, LdapServerInfo } from 'app/types';
@@ -7,7 +7,7 @@ interface Props {
ldapConnectionInfo: LdapConnectionInfo; ldapConnectionInfo: LdapConnectionInfo;
} }
export const LdapConnectionStatus: FC<Props> = ({ ldapConnectionInfo }) => { export const LdapConnectionStatus = ({ ldapConnectionInfo }: Props) => {
return ( return (
<> <>
<h3 className="page-heading">LDAP Connection</h3> <h3 className="page-heading">LDAP Connection</h3>
@@ -50,7 +50,7 @@ interface LdapConnectionErrorProps {
ldapConnectionInfo: LdapConnectionInfo; ldapConnectionInfo: LdapConnectionInfo;
} }
export const LdapErrorBox: FC<LdapConnectionErrorProps> = ({ ldapConnectionInfo }) => { export const LdapErrorBox = ({ ldapConnectionInfo }: LdapConnectionErrorProps) => {
const hasError = ldapConnectionInfo.some((info) => info.error); const hasError = ldapConnectionInfo.some((info) => info.error);
if (!hasError) { if (!hasError) {
return null; return null;
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Tooltip, Icon } from '@grafana/ui'; import { Tooltip, Icon } from '@grafana/ui';
import { LdapRole } from 'app/types'; import { LdapRole } from 'app/types';
@@ -8,7 +8,7 @@ interface Props {
showAttributeMapping?: boolean; showAttributeMapping?: boolean;
} }
export const LdapUserGroups: FC<Props> = ({ groups, showAttributeMapping }) => { export const LdapUserGroups = ({ groups, showAttributeMapping }: Props) => {
const items = showAttributeMapping ? groups : groups.filter((item) => item.orgRole); const items = showAttributeMapping ? groups : groups.filter((item) => item.orgRole);
return ( return (
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { LdapUser } from 'app/types'; import { LdapUser } from 'app/types';
@@ -12,7 +12,7 @@ interface Props {
showAttributeMapping?: boolean; showAttributeMapping?: boolean;
} }
export const LdapUserInfo: FC<Props> = ({ ldapUser, showAttributeMapping }) => { export const LdapUserInfo = ({ ldapUser, showAttributeMapping }: Props) => {
return ( return (
<> <>
<LdapUserMappingInfo info={ldapUser.info} showAttributeMapping={showAttributeMapping} /> <LdapUserMappingInfo info={ldapUser.info} showAttributeMapping={showAttributeMapping} />
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { LdapUserInfo } from 'app/types'; import { LdapUserInfo } from 'app/types';
@@ -7,7 +7,7 @@ interface Props {
showAttributeMapping?: boolean; showAttributeMapping?: boolean;
} }
export const LdapUserMappingInfo: FC<Props> = ({ info, showAttributeMapping }) => { export const LdapUserMappingInfo = ({ info, showAttributeMapping }: Props) => {
return ( return (
<div className="gf-form-group"> <div className="gf-form-group">
<div className="gf-form"> <div className="gf-form">
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Icon } from '@grafana/ui'; import { Icon } from '@grafana/ui';
import { LdapPermissions } from 'app/types'; import { LdapPermissions } from 'app/types';
@@ -7,7 +7,7 @@ interface Props {
permissions: LdapPermissions; permissions: LdapPermissions;
} }
export const LdapUserPermissions: FC<Props> = ({ permissions }) => { export const LdapUserPermissions = ({ permissions }: Props) => {
return ( return (
<div className="gf-form-group"> <div className="gf-form-group">
<div className="gf-form"> <div className="gf-form">
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Tooltip, Icon } from '@grafana/ui'; import { Tooltip, Icon } from '@grafana/ui';
import { LdapTeam } from 'app/types'; import { LdapTeam } from 'app/types';
@@ -8,7 +8,7 @@ interface Props {
showAttributeMapping?: boolean; showAttributeMapping?: boolean;
} }
export const LdapUserTeams: FC<Props> = ({ teams, showAttributeMapping }) => { export const LdapUserTeams = ({ teams, showAttributeMapping }: Props) => {
const items = showAttributeMapping ? teams : teams.filter((item) => item.teamName); const items = showAttributeMapping ? teams : teams.filter((item) => item.teamName);
return ( return (
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { Field, Input, InputControl, Select } from '@grafana/ui'; import { Field, Input, InputControl, Select } from '@grafana/ui';
@@ -15,7 +15,7 @@ interface Props extends NotificationSettingsProps {
resetSecureField: (key: string) => void; resetSecureField: (key: string) => void;
} }
export const BasicSettings: FC<Props> = ({ export const BasicSettings = ({
control, control,
currentFormValues, currentFormValues,
errors, errors,
@@ -24,7 +24,7 @@ export const BasicSettings: FC<Props> = ({
channels, channels,
register, register,
resetSecureField, resetSecureField,
}) => { }: Props) => {
return ( return (
<> <>
<Field label="Name" invalid={!!errors.name} error={errors.name && errors.name.message}> <Field label="Name" invalid={!!errors.name} error={errors.name && errors.name.message}>
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Alert, CollapsableSection } from '@grafana/ui'; import { Alert, CollapsableSection } from '@grafana/ui';
@@ -13,7 +13,7 @@ interface Props extends NotificationSettingsProps {
resetSecureField: (key: string) => void; resetSecureField: (key: string) => void;
} }
export const ChannelSettings: FC<Props> = ({ export const ChannelSettings = ({
control, control,
currentFormValues, currentFormValues,
errors, errors,
@@ -21,7 +21,7 @@ export const ChannelSettings: FC<Props> = ({
secureFields, secureFields,
register, register,
resetSecureField, resetSecureField,
}) => { }: Props) => {
return ( return (
<CollapsableSection label={`Optional ${selectedChannel.heading}`} isOpen={false}> <CollapsableSection label={`Optional ${selectedChannel.heading}`} isOpen={false}>
{selectedChannel.info !== '' && <Alert severity="info" title={selectedChannel.info ?? ''} />} {selectedChannel.info !== '' && <Alert severity="info" title={selectedChannel.info ?? ''} />}
@@ -1,10 +1,10 @@
import React, { FC } from 'react'; import React from 'react';
import { Alert } from '@grafana/ui'; import { Alert } from '@grafana/ui';
export const LOCAL_STORAGE_KEY = 'grafana.legacyalerting.unifiedalertingpromo'; export const LOCAL_STORAGE_KEY = 'grafana.legacyalerting.unifiedalertingpromo';
const DeprecationNotice: FC<{}> = () => ( const DeprecationNotice = () => (
<Alert severity="warning" title="Grafana legacy alerting is going away soon"> <Alert severity="warning" title="Grafana legacy alerting is going away soon">
<p> <p>
You are using Grafana legacy alerting, it has been deprecated and will be removed in the next major version of You are using Grafana legacy alerting, it has been deprecated and will be removed in the next major version of
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, useEffect } from 'react'; import React, { useEffect } from 'react';
import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Button, FormAPI, HorizontalGroup, Spinner, useStyles2 } from '@grafana/ui'; import { Button, FormAPI, HorizontalGroup, Spinner, useStyles2 } from '@grafana/ui';
@@ -26,7 +26,7 @@ export interface NotificationSettingsProps
currentFormValues: NotificationChannelDTO; currentFormValues: NotificationChannelDTO;
} }
export const NotificationChannelForm: FC<Props> = ({ export const NotificationChannelForm = ({
control, control,
errors, errors,
selectedChannel, selectedChannel,
@@ -38,7 +38,7 @@ export const NotificationChannelForm: FC<Props> = ({
onTestChannel, onTestChannel,
resetSecureField, resetSecureField,
secureFields, secureFields,
}) => { }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
useEffect(() => { useEffect(() => {
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { Button, Checkbox, Field, Input } from '@grafana/ui'; import { Button, Checkbox, Field, Input } from '@grafana/ui';
@@ -16,7 +16,7 @@ interface Props extends NotificationSettingsProps {
onResetSecureField: (key: string) => void; onResetSecureField: (key: string) => void;
} }
export const NotificationChannelOptions: FC<Props> = ({ export const NotificationChannelOptions = ({
control, control,
currentFormValues, currentFormValues,
errors, errors,
@@ -24,7 +24,7 @@ export const NotificationChannelOptions: FC<Props> = ({
register, register,
onResetSecureField, onResetSecureField,
secureFields, secureFields,
}) => { }: Props) => {
return ( return (
<> <>
{selectedChannelOptions.map((option: NotificationChannelOption, index: number) => { {selectedChannelOptions.map((option: NotificationChannelOption, index: number) => {
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Checkbox, CollapsableSection, Field, InfoBox, Input } from '@grafana/ui'; import { Checkbox, CollapsableSection, Field, InfoBox, Input } from '@grafana/ui';
@@ -8,7 +8,7 @@ interface Props extends NotificationSettingsProps {
imageRendererAvailable: boolean; imageRendererAvailable: boolean;
} }
export const NotificationSettings: FC<Props> = ({ currentFormValues, imageRendererAvailable, register }) => { export const NotificationSettings = ({ currentFormValues, imageRendererAvailable, register }: Props) => {
return ( return (
<CollapsableSection label="Notification settings" isOpen={false}> <CollapsableSection label="Notification settings" isOpen={false}>
<Field> <Field>
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { FormAPI, Input, InputControl, Select, TextArea } from '@grafana/ui'; import { FormAPI, Input, InputControl, Select, TextArea } from '@grafana/ui';
@@ -9,7 +9,7 @@ interface Props extends Pick<FormAPI<any>, 'register' | 'control'> {
invalid?: boolean; invalid?: boolean;
} }
export const OptionElement: FC<Props> = ({ control, option, register, invalid }) => { export const OptionElement = ({ control, option, register, invalid }: Props) => {
const modelValue = option.secure ? `secureSettings.${option.propertyName}` : `settings.${option.propertyName}`; const modelValue = option.secure ? `secureSettings.${option.propertyName}` : `settings.${option.propertyName}`;
switch (option.element) { switch (option.element) {
case 'input': case 'input':
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Tab, TabProps } from '@grafana/ui/src/components/Tabs/Tab'; import { Tab, TabProps } from '@grafana/ui/src/components/Tabs/Tab';
import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
@@ -11,7 +11,7 @@ interface Props extends Omit<TabProps, 'counter' | 'ref'> {
} }
// it will load rule count from backend // it will load rule count from backend
export const PanelAlertTab: FC<Props> = ({ panel, dashboard, ...otherProps }) => { export const PanelAlertTab = ({ panel, dashboard, ...otherProps }: Props) => {
const { rules, loading } = usePanelCombinedRules({ panel, dashboard }); const { rules, loading } = usePanelCombinedRules({ panel, dashboard });
return <Tab {...otherProps} counter={loading ? null : rules.length} />; return <Tab {...otherProps} counter={loading ? null : rules.length} />;
}; };
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
@@ -17,7 +17,7 @@ interface Props {
panel: PanelModel; panel: PanelModel;
} }
export const PanelAlertTabContent: FC<Props> = ({ dashboard, panel }) => { export const PanelAlertTabContent = ({ dashboard, panel }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const { errors, loading, rules } = usePanelCombinedRules({ const { errors, loading, rules } = usePanelCombinedRules({
dashboard, dashboard,
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, useMemo } from 'react'; import React, { useMemo } from 'react';
import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Field, Select, useStyles2 } from '@grafana/ui'; import { Field, Select, useStyles2 } from '@grafana/ui';
@@ -17,7 +17,7 @@ function getAlertManagerLabel(alertManager: AlertManagerDataSource) {
return alertManager.name === GRAFANA_RULES_SOURCE_NAME ? 'Grafana' : alertManager.name.slice(0, 37); return alertManager.name === GRAFANA_RULES_SOURCE_NAME ? 'Grafana' : alertManager.name.slice(0, 37);
} }
export const AlertManagerPicker: FC<Props> = ({ onChange, current, dataSources, disabled = false }) => { export const AlertManagerPicker = ({ onChange, current, dataSources, disabled = false }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const options: Array<SelectableValue<string>> = useMemo(() => { const options: Array<SelectableValue<string>> = useMemo(() => {
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2, textUtil } from '@grafana/data'; import { GrafanaTheme2, textUtil } from '@grafana/data';
import { Tooltip, useStyles2 } from '@grafana/ui'; import { Tooltip, useStyles2 } from '@grafana/ui';
@@ -18,7 +18,7 @@ interface Props {
valueLink?: string; valueLink?: string;
} }
export const AnnotationDetailsField: FC<Props> = ({ annotationKey, value, valueLink }) => { export const AnnotationDetailsField = ({ annotationKey, value, valueLink }: Props) => {
const label = annotationLabels[annotationKey as Annotation] ? ( const label = annotationLabels[annotationKey as Annotation] ? (
<Tooltip content={annotationKey} placement="top" theme="info"> <Tooltip content={annotationKey} placement="top" theme="info">
<span>{annotationLabels[annotationKey as Annotation]}</span> <span>{annotationLabels[annotationKey as Annotation]}</span>
@@ -34,7 +34,7 @@ export const AnnotationDetailsField: FC<Props> = ({ annotationKey, value, valueL
); );
}; };
const AnnotationValue: FC<Props> = ({ annotationKey, value, valueLink }) => { const AnnotationValue = ({ annotationKey, value, valueLink }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const needsWell = wellableAnnotationKeys.includes(annotationKey); const needsWell = wellableAnnotationKeys.includes(annotationKey);
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, HTMLAttributes } from 'react'; import React, { HTMLAttributes } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { IconSize, useStyles2, Button } from '@grafana/ui'; import { IconSize, useStyles2, Button } from '@grafana/ui';
@@ -14,7 +14,7 @@ interface Props extends HTMLAttributes<HTMLButtonElement> {
text?: string; text?: string;
} }
export const CollapseToggle: FC<Props> = ({ export const CollapseToggle = ({
isCollapsed, isCollapsed,
onToggle, onToggle,
idControlled, idControlled,
@@ -22,7 +22,7 @@ export const CollapseToggle: FC<Props> = ({
text, text,
size = 'xl', size = 'xl',
...restOfProps ...restOfProps
}) => { }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { ButtonHTMLAttributes, FC } from 'react'; import React, { ButtonHTMLAttributes } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Button, ButtonVariant, IconName, LinkButton, useStyles2 } from '@grafana/ui'; import { Button, ButtonVariant, IconName, LinkButton, useStyles2 } from '@grafana/ui';
@@ -18,7 +18,7 @@ export interface EmptyAreaWithCTAProps {
showButton?: boolean; showButton?: boolean;
} }
export const EmptyAreaWithCTA: FC<EmptyAreaWithCTAProps> = ({ export const EmptyAreaWithCTA = ({
buttonIcon, buttonIcon,
buttonLabel, buttonLabel,
buttonSize = 'lg', buttonSize = 'lg',
@@ -27,7 +27,7 @@ export const EmptyAreaWithCTA: FC<EmptyAreaWithCTAProps> = ({
text, text,
href, href,
showButton = true, showButton = true,
}) => { }: EmptyAreaWithCTAProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const commonProps = { const commonProps = {
@@ -1,7 +1,7 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import { Placement } from '@popperjs/core'; import { Placement } from '@popperjs/core';
import classnames from 'classnames'; import classnames from 'classnames';
import React, { FC, ReactElement, ReactNode, useRef } from 'react'; import React, { ReactElement, ReactNode, useRef } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
@@ -19,7 +19,7 @@ export interface HoverCardProps {
arrow?: boolean; arrow?: boolean;
} }
export const HoverCard: FC<HoverCardProps> = ({ export const HoverCard = ({
children, children,
header, header,
content, content,
@@ -29,7 +29,7 @@ export const HoverCard: FC<HoverCardProps> = ({
wrapperClassName, wrapperClassName,
disabled = false, disabled = false,
...rest ...rest
}) => { }: HoverCardProps) => {
const popoverRef = useRef<HTMLElement>(null); const popoverRef = useRef<HTMLElement>(null);
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
@@ -1,11 +1,11 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, ReactNode } from 'react'; import React, { ReactNode } from 'react';
import { GrafanaTheme2, IconName } from '@grafana/data'; import { GrafanaTheme2, IconName } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
import { Icon, useStyles2 } from '@grafana/ui'; import { Icon, useStyles2 } from '@grafana/ui';
interface LabelProps { interface Props {
icon?: IconName; icon?: IconName;
label?: ReactNode; label?: ReactNode;
value: ReactNode; value: ReactNode;
@@ -13,7 +13,7 @@ interface LabelProps {
} }
// TODO allow customization with color prop // TODO allow customization with color prop
const Label: FC<LabelProps> = ({ label, value, icon }) => { const Label = ({ label, value, icon }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (
@@ -1,16 +1,16 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import classNames from 'classnames'; import classNames from 'classnames';
import React, { FC, HTMLAttributes } from 'react'; import React, { HTMLAttributes } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
import { Icon, IconName, useStyles2 } from '@grafana/ui'; import { Icon, IconName, useStyles2 } from '@grafana/ui';
interface MetaTextProps extends HTMLAttributes<HTMLDivElement> { interface Props extends HTMLAttributes<HTMLDivElement> {
icon?: IconName; icon?: IconName;
} }
const MetaText: FC<MetaTextProps> = ({ children, icon, ...rest }) => { const MetaText = ({ children, icon, ...rest }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const interactive = typeof rest.onClick === 'function'; const interactive = typeof rest.onClick === 'function';
@@ -1,13 +1,13 @@
import React, { FC } from 'react'; import React from 'react';
import { Icon } from '@grafana/ui'; import { Icon } from '@grafana/ui';
interface RuleLocationProps { interface Props {
namespace: string; namespace: string;
group?: string; group?: string;
} }
const RuleLocation: FC<RuleLocationProps> = ({ namespace, group }) => { const RuleLocation = ({ namespace, group }: Props) => {
if (!group) { if (!group) {
return <>{namespace}</>; return <>{namespace}</>;
} }
@@ -1,12 +1,12 @@
import { cx, css } from '@emotion/css'; import { cx, css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '@grafana/ui'; import { useStyles2 } from '@grafana/ui';
type Props = React.HTMLAttributes<HTMLDivElement>; type Props = React.HTMLAttributes<HTMLDivElement>;
export const Well: FC<Props> = ({ children, className }) => { export const Well = ({ children, className }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return <div className={cx(styles.wrapper, className)}>{children}</div>; return <div className={cx(styles.wrapper, className)}>{children}</div>;
}; };
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { LinkButton, useStyles2 } from '@grafana/ui'; import { LinkButton, useStyles2 } from '@grafana/ui';
@@ -18,7 +18,7 @@ interface AmNotificationsAlertDetailsProps {
alert: AlertmanagerAlert; alert: AlertmanagerAlert;
} }
export const AlertDetails: FC<AmNotificationsAlertDetailsProps> = ({ alert, alertManagerSourceName }) => { export const AlertDetails = ({ alert, alertManagerSourceName }: AmNotificationsAlertDetailsProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const instancePermissions = getInstancesPermissions(alertManagerSourceName); const instancePermissions = getInstancesPermissions(alertManagerSourceName);
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Badge, clearButtonStyles, useStyles2 } from '@grafana/ui'; import { Badge, clearButtonStyles, useStyles2 } from '@grafana/ui';
@@ -11,12 +11,7 @@ interface AlertConditionProps {
onSetCondition?: () => void; onSetCondition?: () => void;
} }
export const AlertConditionIndicator: FC<AlertConditionProps> = ({ export const AlertConditionIndicator = ({ enabled = false, error, warning, onSetCondition }: AlertConditionProps) => {
enabled = false,
error,
warning,
onSetCondition,
}) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
if (enabled && error) { if (enabled && error) {
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { useFieldArray, useFormContext } from 'react-hook-form'; import { useFieldArray, useFormContext } from 'react-hook-form';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
@@ -11,7 +11,7 @@ interface Props {
intervalIndex: number; intervalIndex: number;
} }
export const MuteTimingTimeRange: FC<Props> = ({ intervalIndex }) => { export const MuteTimingTimeRange = ({ intervalIndex }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const { register, formState } = useFormContext<MuteTimingFields>(); const { register, formState } = useFormContext<MuteTimingFields>();
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
@@ -32,7 +32,7 @@ interface Props {
hideActions?: boolean; hideActions?: boolean;
} }
export const MuteTimingsTable: FC<Props> = ({ alertManagerSourceName, muteTimingNames, hideActions }) => { export const MuteTimingsTable = ({ alertManagerSourceName, muteTimingNames, hideActions }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const dispatch = useDispatch(); const dispatch = useDispatch();
const permissions = getNotificationsPermissions(alertManagerSourceName); const permissions = getNotificationsPermissions(alertManagerSourceName);
@@ -1,5 +1,5 @@
import pluralize from 'pluralize'; import pluralize from 'pluralize';
import React, { FC, Fragment } from 'react'; import React, { Fragment } from 'react';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
import { Badge } from '@grafana/ui'; import { Badge } from '@grafana/ui';
@@ -10,7 +10,7 @@ interface Props {
unprocessed?: number; unprocessed?: number;
} }
export const AlertGroupsSummary: FC<Props> = ({ active = 0, suppressed = 0, unprocessed = 0 }) => { export const AlertGroupsSummary = ({ active = 0, suppressed = 0, unprocessed = 0 }: Props) => {
const statsComponents: React.ReactNode[] = []; const statsComponents: React.ReactNode[] = [];
const total = active + suppressed + unprocessed; const total = active + suppressed + unprocessed;
@@ -1,5 +1,5 @@
import { cx } from '@emotion/css'; import { cx } from '@emotion/css';
import React, { FC, ReactNode, useState } from 'react'; import React, { ReactNode, useState } from 'react';
import { Collapse, Field, Form, Input, InputControl, Link, MultiSelect, Select, useStyles2 } from '@grafana/ui'; import { Collapse, Field, Form, Input, InputControl, Link, MultiSelect, Select, useStyles2 } from '@grafana/ui';
import { RouteWithID } from 'app/plugins/datasource/alertmanager/types'; import { RouteWithID } from 'app/plugins/datasource/alertmanager/types';
@@ -28,13 +28,13 @@ export interface AmRootRouteFormProps {
route: RouteWithID; route: RouteWithID;
} }
export const AmRootRouteForm: FC<AmRootRouteFormProps> = ({ export const AmRootRouteForm = ({
actionButtons, actionButtons,
alertManagerSourceName, alertManagerSourceName,
onSubmit, onSubmit,
receivers, receivers,
route, route,
}) => { }: AmRootRouteFormProps) => {
const styles = useStyles2(getFormStyles); const styles = useStyles2(getFormStyles);
const [isTimingOptionsExpanded, setIsTimingOptionsExpanded] = useState(false); const [isTimingOptionsExpanded, setIsTimingOptionsExpanded] = useState(false);
const [groupByOptions, setGroupByOptions] = useState(stringsToSelectableValues(route.group_by)); const [groupByOptions, setGroupByOptions] = useState(stringsToSelectableValues(route.group_by));
@@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import React, { FC, ReactNode, useState } from 'react'; import React, { ReactNode, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
@@ -45,7 +45,7 @@ export interface AmRoutesExpandedFormProps {
actionButtons: ReactNode; actionButtons: ReactNode;
} }
export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ actionButtons, receivers, route, onSubmit }) => { export const AmRoutesExpandedForm = ({ actionButtons, receivers, route, onSubmit }: AmRoutesExpandedFormProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const formStyles = useStyles2(getFormStyles); const formStyles = useStyles2(getFormStyles);
const [groupByOptions, setGroupByOptions] = useState(stringsToSelectableValues(route?.group_by)); const [groupByOptions, setGroupByOptions] = useState(stringsToSelectableValues(route?.group_by));
@@ -1,6 +1,6 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import { debounce, pick } from 'lodash'; import { debounce, pick } from 'lodash';
import React, { FC, useCallback, useEffect, useRef } from 'react'; import React, { useCallback, useEffect, useRef } from 'react';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
@@ -16,11 +16,11 @@ interface NotificationPoliciesFilterProps {
onChangeReceiver: (receiver: string | undefined) => void; onChangeReceiver: (receiver: string | undefined) => void;
} }
const NotificationPoliciesFilter: FC<NotificationPoliciesFilterProps> = ({ const NotificationPoliciesFilter = ({
receivers, receivers,
onChangeReceiver, onChangeReceiver,
onChangeMatchers, onChangeMatchers,
}) => { }: NotificationPoliciesFilterProps) => {
const [searchParams, setSearchParams] = useURLSearchParams(); const [searchParams, setSearchParams] = useURLSearchParams();
const searchInputRef = useRef<HTMLInputElement | null>(null); const searchInputRef = useRef<HTMLInputElement | null>(null);
const { queryString, contactPoint } = getNotificationPoliciesFilters(searchParams); const { queryString, contactPoint } = getNotificationPoliciesFilters(searchParams);
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { useAsync } from 'react-use'; import { useAsync } from 'react-use';
@@ -17,7 +17,7 @@ interface Props {
className?: string; className?: string;
} }
export const NewRuleFromPanelButton: FC<Props> = ({ dashboard, panel, className }) => { export const NewRuleFromPanelButton = ({ dashboard, panel, className }: Props) => {
const templating = useSelector((state) => { const templating = useSelector((state) => {
return state.templating; return state.templating;
}); });
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Alert } from '@grafana/ui'; import { Alert } from '@grafana/ui';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -14,7 +14,7 @@ interface Props {
alertManagerSourceName: string; alertManagerSourceName: string;
} }
export const DuplicateTemplateView: FC<Props> = ({ config, templateName, alertManagerSourceName }) => { export const DuplicateTemplateView = ({ config, templateName, alertManagerSourceName }: Props) => {
const template = config.template_files?.[templateName]; const template = config.template_files?.[templateName];
if (!template) { if (!template) {
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Alert } from '@grafana/ui'; import { Alert } from '@grafana/ui';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -14,7 +14,7 @@ interface Props {
alertManagerSourceName: string; alertManagerSourceName: string;
} }
export const EditReceiverView: FC<Props> = ({ config, receiverName, alertManagerSourceName }) => { export const EditReceiverView = ({ config, receiverName, alertManagerSourceName }: Props) => {
const receiver = config.alertmanager_config.receivers?.find(({ name }) => name === receiverName); const receiver = config.alertmanager_config.receivers?.find(({ name }) => name === receiverName);
if (!receiver) { if (!receiver) {
return ( return (
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Alert } from '@grafana/ui'; import { Alert } from '@grafana/ui';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -11,7 +11,7 @@ interface Props {
alertManagerSourceName: string; alertManagerSourceName: string;
} }
export const EditTemplateView: FC<Props> = ({ config, templateName, alertManagerSourceName }) => { export const EditTemplateView = ({ config, templateName, alertManagerSourceName }: Props) => {
const template = config.template_files?.[templateName]; const template = config.template_files?.[templateName];
const provenance = config.template_file_provenances?.[templateName]; const provenance = config.template_file_provenances?.[templateName];
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { useForm, FormProvider } from 'react-hook-form'; import { useForm, FormProvider } from 'react-hook-form';
import { Alert, Button, HorizontalGroup, LinkButton } from '@grafana/ui'; import { Alert, Button, HorizontalGroup, LinkButton } from '@grafana/ui';
@@ -27,7 +27,7 @@ const defaultValues: FormValues = {
smtp_require_tls: true, smtp_require_tls: true,
} as const; } as const;
export const GlobalConfigForm: FC<Props> = ({ config, alertManagerSourceName }) => { export const GlobalConfigForm = ({ config, alertManagerSourceName }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
useCleanup((state) => (state.unifiedAlerting.saveAMConfig = initialAsyncRequestState)); useCleanup((state) => (state.unifiedAlerting.saveAMConfig = initialAsyncRequestState));
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -12,7 +12,7 @@ interface Props {
alertManagerSourceName: string; alertManagerSourceName: string;
} }
export const NewReceiverView: FC<Props> = ({ alertManagerSourceName, config }) => { export const NewReceiverView = ({ alertManagerSourceName, config }: Props) => {
if (alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME) { if (alertManagerSourceName === GRAFANA_RULES_SOURCE_NAME) {
return <GrafanaReceiverForm alertManagerSourceName={alertManagerSourceName} config={config} />; return <GrafanaReceiverForm alertManagerSourceName={alertManagerSourceName} config={config} />;
} else { } else {
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types'; import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -9,6 +9,6 @@ interface Props {
alertManagerSourceName: string; alertManagerSourceName: string;
} }
export const NewTemplateView: FC<Props> = ({ config, alertManagerSourceName }) => { export const NewTemplateView = ({ config, alertManagerSourceName }: Props) => {
return <TemplateForm config={config} alertManagerSourceName={alertManagerSourceName} />; return <TemplateForm config={config} alertManagerSourceName={alertManagerSourceName} />;
}; };
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
import { Alert, LinkButton } from '@grafana/ui'; import { Alert, LinkButton } from '@grafana/ui';
@@ -17,7 +17,7 @@ interface Props {
alertManagerName: string; alertManagerName: string;
} }
export const ReceiversAndTemplatesView: FC<Props> = ({ config, alertManagerName }) => { export const ReceiversAndTemplatesView = ({ config, alertManagerName }: Props) => {
const isCloud = alertManagerName !== GRAFANA_RULES_SOURCE_NAME; const isCloud = alertManagerName !== GRAFANA_RULES_SOURCE_NAME;
const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerName); const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerName);
@@ -1,5 +1,5 @@
import pluralize from 'pluralize'; import pluralize from 'pluralize';
import React, { FC, useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import { dateTime, dateTimeFormat } from '@grafana/data'; import { dateTime, dateTimeFormat } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
@@ -238,7 +238,7 @@ interface Props {
alertManagerName: string; alertManagerName: string;
} }
export const ReceiversTable: FC<Props> = ({ config, alertManagerName }) => { export const ReceiversTable = ({ config, alertManagerName }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerName); const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerName);
const permissions = getNotificationsPermissions(alertManagerName); const permissions = getNotificationsPermissions(alertManagerName);
@@ -4,7 +4,7 @@
* It includes auto-complete for template data and syntax highlighting * It includes auto-complete for template data and syntax highlighting
*/ */
import { editor, IDisposable } from 'monaco-editor'; import { editor, IDisposable } from 'monaco-editor';
import React, { FC, useEffect, useRef } from 'react'; import React, { useEffect, useRef } from 'react';
import { CodeEditor } from '@grafana/ui'; import { CodeEditor } from '@grafana/ui';
import { CodeEditorProps } from '@grafana/ui/src/components/Monaco/types'; import { CodeEditorProps } from '@grafana/ui/src/components/Monaco/types';
@@ -17,7 +17,7 @@ type TemplateEditorProps = Omit<CodeEditorProps, 'language' | 'theme'> & {
autoHeight?: boolean; autoHeight?: boolean;
}; };
const TemplateEditor: FC<TemplateEditorProps> = (props) => { const TemplateEditor = (props: TemplateEditorProps) => {
const shouldAutoHeight = Boolean(props.autoHeight); const shouldAutoHeight = Boolean(props.autoHeight);
const disposeSuggestions = useRef<IDisposable | null>(null); const disposeSuggestions = useRef<IDisposable | null>(null);
@@ -1,6 +1,6 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import { Location } from 'history'; import { Location } from 'history';
import React, { FC } from 'react'; import React from 'react';
import { useForm, Validate } from 'react-hook-form'; import { useForm, Validate } from 'react-hook-form';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import AutoSizer from 'react-virtualized-auto-sizer'; import AutoSizer from 'react-virtualized-auto-sizer';
@@ -41,7 +41,7 @@ interface Props {
} }
export const isDuplicating = (location: Location) => location.pathname.endsWith('/duplicate'); export const isDuplicating = (location: Location) => location.pathname.endsWith('/duplicate');
export const TemplateForm: FC<Props> = ({ existing, alertManagerSourceName, config, provenance }) => { export const TemplateForm = ({ existing, alertManagerSourceName, config, provenance }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -1,4 +1,4 @@
import React, { FC, Fragment, useMemo, useState } from 'react'; import React, { Fragment, useMemo, useState } from 'react';
import { ConfirmModal, useStyles2 } from '@grafana/ui'; import { ConfirmModal, useStyles2 } from '@grafana/ui';
import { contextSrv } from 'app/core/services/context_srv'; import { contextSrv } from 'app/core/services/context_srv';
@@ -23,7 +23,7 @@ interface Props {
alertManagerName: string; alertManagerName: string;
} }
export const TemplatesTable: FC<Props> = ({ config, alertManagerName }) => { export const TemplatesTable = ({ config, alertManagerName }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [expandedTemplates, setExpandedTemplates] = useState<Record<string, boolean>>({}); const [expandedTemplates, setExpandedTemplates] = useState<Record<string, boolean>>({});
const tableStyles = useStyles2(getAlertTableStyles); const tableStyles = useStyles2(getAlertTableStyles);
@@ -1,15 +1,15 @@
import React, { FC } from 'react'; import React from 'react';
import { useFormContext } from 'react-hook-form'; import { useFormContext } from 'react-hook-form';
import { Checkbox, Field } from '@grafana/ui'; import { Checkbox, Field } from '@grafana/ui';
import { CommonSettingsComponentProps } from '../../../types/receiver-form'; import { CommonSettingsComponentProps } from '../../../types/receiver-form';
export const CloudCommonChannelSettings: FC<CommonSettingsComponentProps> = ({ export const CloudCommonChannelSettings = ({
pathPrefix, pathPrefix,
className, className,
readOnly = false, readOnly = false,
}) => { }: CommonSettingsComponentProps) => {
const { register } = useFormContext(); const { register } = useFormContext();
return ( return (
<div className={className}> <div className={className}>
@@ -1,4 +1,4 @@
import React, { FC, useMemo } from 'react'; import React, { useMemo } from 'react';
import { Alert } from '@grafana/ui'; import { Alert } from '@grafana/ui';
import { AlertManagerCortexConfig, Receiver } from 'app/plugins/datasource/alertmanager/types'; import { AlertManagerCortexConfig, Receiver } from 'app/plugins/datasource/alertmanager/types';
@@ -32,7 +32,7 @@ const defaultChannelValues: CloudChannelValues = Object.freeze({
type: 'email', type: 'email',
}); });
export const CloudReceiverForm: FC<Props> = ({ existing, alertManagerSourceName, config }) => { export const CloudReceiverForm = ({ existing, alertManagerSourceName, config }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerSourceName); const isVanillaAM = isVanillaPrometheusAlertManagerDataSource(alertManagerSourceName);
@@ -1,15 +1,15 @@
import React, { FC } from 'react'; import React from 'react';
import { useFormContext } from 'react-hook-form'; import { useFormContext } from 'react-hook-form';
import { Checkbox, Field } from '@grafana/ui'; import { Checkbox, Field } from '@grafana/ui';
import { CommonSettingsComponentProps } from '../../../types/receiver-form'; import { CommonSettingsComponentProps } from '../../../types/receiver-form';
export const GrafanaCommonChannelSettings: FC<CommonSettingsComponentProps> = ({ export const GrafanaCommonChannelSettings = ({
pathPrefix, pathPrefix,
className, className,
readOnly = false, readOnly = false,
}) => { }: CommonSettingsComponentProps) => {
const { register } = useFormContext(); const { register } = useFormContext();
return ( return (
<div className={className}> <div className={className}>
@@ -1,4 +1,4 @@
import React, { FC, useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { LoadingPlaceholder } from '@grafana/ui'; import { LoadingPlaceholder } from '@grafana/ui';
import { import {
@@ -44,7 +44,7 @@ const defaultChannelValues: GrafanaChannelValues = Object.freeze({
type: 'email', type: 'email',
}); });
export const GrafanaReceiverForm: FC<Props> = ({ existing, alertManagerSourceName, config }) => { export const GrafanaReceiverForm = ({ existing, alertManagerSourceName, config }: Props) => {
const grafanaNotifiers = useUnifiedAlertingSelector((state) => state.grafanaNotifiers); const grafanaNotifiers = useUnifiedAlertingSelector((state) => state.grafanaNotifiers);
const [testChannelValues, setTestChannelValues] = useState<GrafanaChannelValues>(); const [testChannelValues, setTestChannelValues] = useState<GrafanaChannelValues>();
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Button, Input, useStyles2 } from '@grafana/ui'; import { Button, Input, useStyles2 } from '@grafana/ui';
@@ -12,7 +12,7 @@ interface Props {
onChange: (value: Record<string, string>) => void; onChange: (value: Record<string, string>) => void;
} }
export const KeyValueMapInput: FC<Props> = ({ value, onChange, readOnly = false }) => { export const KeyValueMapInput = ({ value, onChange, readOnly = false }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const [pairs, setPairs] = useState(recordToPairs(value)); const [pairs, setPairs] = useState(recordToPairs(value));
useEffect(() => setPairs(recordToPairs(value)), [value]); useEffect(() => setPairs(recordToPairs(value)), [value]);
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { Button, Input, useStyles2 } from '@grafana/ui'; import { Button, Input, useStyles2 } from '@grafana/ui';
@@ -12,7 +12,7 @@ interface Props {
onChange: (value: string[]) => void; onChange: (value: string[]) => void;
} }
export const StringArrayInput: FC<Props> = ({ value, onChange, readOnly = false }) => { export const StringArrayInput = ({ value, onChange, readOnly = false }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const deleteItem = (index: number) => { const deleteItem = (index: number) => {
@@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { FieldError, DeepMap, useFormContext } from 'react-hook-form'; import { FieldError, DeepMap, useFormContext } from 'react-hook-form';
import { Button, useStyles2 } from '@grafana/ui'; import { Button, useStyles2 } from '@grafana/ui';
@@ -19,7 +19,7 @@ interface Props {
readOnly?: boolean; readOnly?: boolean;
} }
export const SubformArrayField: FC<Props> = ({ option, pathPrefix, errors, defaultValues, readOnly = false }) => { export const SubformArrayField = ({ option, pathPrefix, errors, defaultValues, readOnly = false }: Props) => {
const styles = useStyles2(getReceiverFormFieldStyles); const styles = useStyles2(getReceiverFormFieldStyles);
const path = `${pathPrefix}${option.propertyName}`; const path = `${pathPrefix}${option.propertyName}`;
const formAPI = useFormContext(); const formAPI = useFormContext();
@@ -1,4 +1,4 @@
import React, { FC, useState } from 'react'; import React, { useState } from 'react';
import { FieldError, DeepMap, useFormContext } from 'react-hook-form'; import { FieldError, DeepMap, useFormContext } from 'react-hook-form';
import { Button, useStyles2 } from '@grafana/ui'; import { Button, useStyles2 } from '@grafana/ui';
@@ -17,7 +17,7 @@ interface Props {
readOnly?: boolean; readOnly?: boolean;
} }
export const SubformField: FC<Props> = ({ option, pathPrefix, errors, defaultValue, readOnly = false }) => { export const SubformField = ({ option, pathPrefix, errors, defaultValue, readOnly = false }: Props) => {
const styles = useStyles2(getReceiverFormFieldStyles); const styles = useStyles2(getReceiverFormFieldStyles);
const name = `${pathPrefix}${option.propertyName}`; const name = `${pathPrefix}${option.propertyName}`;
const { watch } = useFormContext(); const { watch } = useFormContext();
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { DeepMap, FieldError, FormProvider, useForm, useFormContext, UseFormWatch } from 'react-hook-form'; import { DeepMap, FieldError, FormProvider, useForm, useFormContext, UseFormWatch } from 'react-hook-form';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@@ -73,7 +73,7 @@ type Props = {
prefill?: Partial<RuleFormValues>; // Existing implies we modify existing rule. Prefill only provides default form values prefill?: Partial<RuleFormValues>; // Existing implies we modify existing rule. Prefill only provides default form values
}; };
export const AlertRuleForm: FC<Props> = ({ existing, prefill }) => { export const AlertRuleForm = ({ existing, prefill }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const dispatch = useDispatch(); const dispatch = useDispatch();
const notifyApp = useAppNotification(); const notifyApp = useAppNotification();
@@ -1,4 +1,4 @@
import React, { FC, useMemo } from 'react'; import React, { useMemo } from 'react';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
@@ -16,7 +16,7 @@ interface Props {
'aria-label'?: string; 'aria-label'?: string;
} }
export const AnnotationKeyInput: FC<Props> = ({ value, existingKeys, 'aria-label': ariaLabel, ...rest }) => { export const AnnotationKeyInput = ({ value, existingKeys, 'aria-label': ariaLabel, ...rest }: Props) => {
const annotationOptions = useMemo( const annotationOptions = useMemo(
(): SelectableValue[] => (): SelectableValue[] =>
Object.values(Annotation) Object.values(Annotation)
@@ -1,6 +1,6 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import { noop } from 'lodash'; import { noop } from 'lodash';
import React, { FC, useCallback, useMemo } from 'react'; import React, { useCallback, useMemo } from 'react';
import { useAsync } from 'react-use'; import { useAsync } from 'react-use';
import { CoreApp, DataQuery, DataSourcePluginContextProvider, GrafanaTheme2, LoadingState } from '@grafana/data'; import { CoreApp, DataQuery, DataSourcePluginContextProvider, GrafanaTheme2, LoadingState } from '@grafana/data';
@@ -19,12 +19,12 @@ export interface ExpressionEditorProps {
showPreviewAlertsButton: boolean; showPreviewAlertsButton: boolean;
} }
export const ExpressionEditor: FC<ExpressionEditorProps> = ({ export const ExpressionEditor = ({
value, value,
onChange, onChange,
dataSourceName, dataSourceName,
showPreviewAlertsButton = true, showPreviewAlertsButton = true,
}) => { }: ExpressionEditorProps) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
const { mapToValue, mapToQuery } = useQueryMappers(dataSourceName); const { mapToValue, mapToQuery } = useQueryMappers(dataSourceName);
@@ -1,4 +1,4 @@
import React, { FC, useMemo } from 'react'; import React, { useMemo } from 'react';
import { PanelData } from '@grafana/data'; import { PanelData } from '@grafana/data';
import { Stack } from '@grafana/experimental'; import { Stack } from '@grafana/experimental';
@@ -21,7 +21,7 @@ interface Props {
onUpdateQueryExpression: (query: ExpressionQuery) => void; onUpdateQueryExpression: (query: ExpressionQuery) => void;
} }
export const ExpressionsEditor: FC<Props> = ({ export const ExpressionsEditor = ({
condition, condition,
onSetCondition, onSetCondition,
queries, queries,
@@ -30,7 +30,7 @@ export const ExpressionsEditor: FC<Props> = ({
onRemoveExpression, onRemoveExpression,
onUpdateExpressionType, onUpdateExpressionType,
onUpdateQueryExpression, onUpdateQueryExpression,
}) => { }: Props) => {
const expressionQueries = useMemo(() => { const expressionQueries = useMemo(() => {
return queries.reduce((acc: ExpressionQuery[], query) => { return queries.reduce((acc: ExpressionQuery[], query) => {
return isExpressionQuery(query.model) ? acc.concat(query.model) : acc; return isExpressionQuery(query.model) ? acc.concat(query.model) : acc;
@@ -1,4 +1,4 @@
import React, { FC, useMemo } from 'react'; import React, { useMemo } from 'react';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { Select } from '@grafana/ui'; import { Select } from '@grafana/ui';
@@ -17,7 +17,7 @@ const options: SelectableValue[] = [
{ value: GrafanaAlertStateDecision.Error, label: 'Error' }, { value: GrafanaAlertStateDecision.Error, label: 'Error' },
]; ];
export const GrafanaAlertStatePicker: FC<Props> = ({ includeNoData, includeError, ...props }) => { export const GrafanaAlertStatePicker = ({ includeNoData, includeError, ...props }: Props) => {
const opts = useMemo(() => { const opts = useMemo(() => {
if (!includeNoData) { if (!includeNoData) {
return options.filter((opt) => opt.value !== GrafanaAlertStateDecision.NoData); return options.filter((opt) => opt.value !== GrafanaAlertStateDecision.NoData);
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC, useEffect, useMemo } from 'react'; import React, { useEffect, useMemo } from 'react';
import { useFormContext } from 'react-hook-form'; import { useFormContext } from 'react-hook-form';
import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { GrafanaTheme2, SelectableValue } from '@grafana/data';
@@ -16,7 +16,7 @@ interface Props {
rulesSourceName: string; rulesSourceName: string;
} }
export const GroupAndNamespaceFields: FC<Props> = ({ rulesSourceName }) => { export const GroupAndNamespaceFields = ({ rulesSourceName }: Props) => {
const { const {
control, control,
watch, watch,
@@ -1,5 +1,5 @@
import { css } from '@emotion/css'; import { css } from '@emotion/css';
import React, { FC } from 'react'; import React from 'react';
import { GrafanaTheme2, PanelData } from '@grafana/data'; import { GrafanaTheme2, PanelData } from '@grafana/data';
import { useStyles2 } from '@grafana/ui'; import { useStyles2 } from '@grafana/ui';
@@ -18,7 +18,7 @@ interface Props {
onSetCondition: (refId: string) => void; onSetCondition: (refId: string) => void;
} }
export const QueryEditor: FC<Props> = ({ export const QueryEditor = ({
queries, queries,
expressions, expressions,
panelData, panelData,
@@ -27,7 +27,7 @@ export const QueryEditor: FC<Props> = ({
onDuplicateQuery, onDuplicateQuery,
condition, condition,
onSetCondition, onSetCondition,
}) => { }: Props) => {
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
return ( return (

Some files were not shown because too many files have changed in this diff Show More