From e1c44d7a8ab64953351878147bcc8cd7623ec845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Bedi?= Date: Wed, 21 Oct 2020 09:06:41 +0200 Subject: [PATCH] Chore: react hooks eslint fixes in grafana-ui (#28026) * Fix some rule violation in grafan-ui * Update eslint-plugin-react-hooks to latest * Remove duplicate dependency * Fix more files * Props destruction --- package.json | 6 ++-- packages/grafana-toolkit/package.json | 2 +- .../components/BigValue/BigValue.story.tsx | 6 ++-- .../src/components/Chart/TooltipContainer.tsx | 18 +++++------ .../components/ContextMenu/ContextMenu.tsx | 2 +- .../components/DataLinks/DataLinkInput.tsx | 2 +- .../DataSourceHttpSettings.tsx | 2 +- .../src/components/FileUpload/FileUpload.tsx | 17 +++++----- .../grafana-ui/src/components/Forms/Form.tsx | 2 +- .../RadioButtonGroup/RadioButtonGroup.tsx | 2 +- .../src/components/Logs/LogRowContext.tsx | 15 +++++---- .../FieldNameByRegexMatcherEditor.tsx | 6 ++-- .../MatchersUI/FieldNameMatcherEditor.tsx | 6 ++-- .../MatchersUI/FieldTypeMatcherEditor.tsx | 6 ++-- .../src/components/OptionsUI/number.tsx | 2 +- .../src/components/OptionsUI/string.tsx | 2 +- .../src/components/Select/SelectBase.tsx | 2 +- .../src/components/Table/FilterList.tsx | 2 +- .../grafana-ui/src/components/Table/Table.tsx | 31 ++++++++++--------- .../TimeRangePicker/TimePickerCalendar.tsx | 10 ++---- .../TimeRangePicker/TimePickerContent.tsx | 14 ++++----- .../TimeRangePicker/TimeRangeForm.tsx | 6 ++-- .../components/TimePicker/TimeZonePicker.tsx | 29 +++++++++-------- .../TimeZonePicker/TimeZoneDescription.tsx | 16 ++++++---- .../components/PanelEditor/PanelEditor.tsx | 1 - yarn.lock | 8 ++--- 26 files changed, 108 insertions(+), 107 deletions(-) diff --git a/package.json b/package.json index 78b6aa12776..a2beafa0350 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "eslint-config-prettier": "6.11.0", "eslint-plugin-jsdoc": "28.6.1", "eslint-plugin-prettier": "3.1.4", - "eslint-plugin-react-hooks": "4.0.5", + "eslint-plugin-react-hooks": "4.1.2", "expect.js": "0.3.1", "expose-loader": "0.7.5", "file-loader": "5.0.2", @@ -212,17 +212,16 @@ "@types/antlr4": "^4.7.1", "@types/braintree__sanitize-url": "4.0.0", "@types/common-tags": "^1.8.0", + "@types/hoist-non-react-statics": "3.3.1", "@types/jsurl": "^1.2.28", "@types/md5": "^2.1.33", "@types/react-loadable": "5.5.2", - "@types/hoist-non-react-statics": "3.3.1", "@types/react-virtualized-auto-sizer": "1.0.0", "@types/sockjs-client": "^1.1.1", "@types/uuid": "8.3.0", "@welldone-software/why-did-you-render": "4.0.6", "abortcontroller-polyfill": "1.4.0", "angular": "1.6.9", - "hoist-non-react-statics": "3.3.2", "angular-bindonce": "0.3.1", "angular-native-dragdrop": "1.2.2", "angular-route": "1.6.6", @@ -243,6 +242,7 @@ "eventemitter3": "4.0.0", "fast-text-encoding": "^1.0.0", "file-saver": "2.0.2", + "hoist-non-react-statics": "3.3.2", "immutable": "3.8.2", "is-hotkey": "0.1.6", "jquery": "3.5.1", diff --git a/packages/grafana-toolkit/package.json b/packages/grafana-toolkit/package.json index eeae3af4e6b..1ddda60a629 100644 --- a/packages/grafana-toolkit/package.json +++ b/packages/grafana-toolkit/package.json @@ -62,7 +62,7 @@ "eslint-config-prettier": "6.11.0", "eslint-plugin-jsdoc": "28.6.1", "eslint-plugin-prettier": "3.1.4", - "eslint-plugin-react-hooks": "4.0.5", + "eslint-plugin-react-hooks": "4.1.2", "execa": "^1.0.0", "expect-puppeteer": "4.1.1", "file-loader": "5.0.2", diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx index a42c1f673e2..0864250ed3c 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValue.story.tsx @@ -34,8 +34,9 @@ export default { }, }; -export const basic = () => { +export const Basic = () => { const { value, title, colorMode, graphMode, height, width, color, textMode, justifyMode } = getKnobs(); + const theme = useTheme(); const sparkline = { xMin: 0, xMax: 5, @@ -51,8 +52,7 @@ export const basic = () => { return ( { }); export const TooltipContainer: React.FC = ({ - position, - offset, + position: { x: positionX, y: positionY }, + offset: { x: offsetX, y: offsetY }, children, className, ...otherProps @@ -38,8 +38,8 @@ export const TooltipContainer: React.FC = ({ const tooltipRef = useRef(null); const { width, height } = useWindowSize(); const [placement, setPlacement] = useState({ - x: position.x + offset.x, - y: position.y + offset.y, + x: positionX + offsetX, + y: positionY + offsetY, }); // Make sure tooltip does not overflow window @@ -48,8 +48,8 @@ export const TooltipContainer: React.FC = ({ yO = 0; if (tooltipRef && tooltipRef.current) { const measurement = tooltipRef.current.getBoundingClientRect(); - const xOverflow = width - (position.x + measurement.width); - const yOverflow = height - (position.y + measurement.height); + const xOverflow = width - (positionX + measurement.width); + const yOverflow = height - (positionY + measurement.height); if (xOverflow < 0) { xO = measurement.width; } @@ -60,10 +60,10 @@ export const TooltipContainer: React.FC = ({ } setPlacement({ - x: position.x + offset.x - xO, - y: position.y + offset.y - yO, + x: positionX + offsetX - xO, + y: positionY + offsetY - yO, }); - }, [tooltipRef, position]); + }, [tooltipRef, width, height, positionX, offsetX, positionY, offsetY]); const styles = getTooltipContainerStyles(theme); diff --git a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx index 4d0bdbe6d8d..e9181f7b9e6 100644 --- a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx +++ b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx @@ -169,7 +169,7 @@ export const ContextMenu: React.FC = React.memo(({ x, y, onClo top: collisions.bottom ? y - rect.height - OFFSET : y + OFFSET, }); } - }, [menuRef.current]); + }, [x, y]); useClickAway(menuRef, () => { if (onClose) { diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx index ca23d4bffa6..ba4d9ccbee3 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx @@ -82,7 +82,7 @@ export const DataLinkInput: React.FC = memo( stateRef.current = { showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange }; // SelectionReference is used to position the variables suggestion relatively to current DOM selection - const selectionRef = useMemo(() => new SelectionReference(), [setShowingSuggestions, linkUrl]); + const selectionRef = useMemo(() => new SelectionReference(), []); const onKeyDown = React.useCallback((event: KeyboardEvent, next: () => any) => { if (!stateRef.current.showingSuggestions) { diff --git a/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx index 113e178e74a..2d58f19b369 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx @@ -68,7 +68,7 @@ export const DataSourceHttpSettings: React.FC = props => { ...change, }); }, - [dataSourceConfig] + [dataSourceConfig, onChange] ); switch (dataSourceConfig.access) { diff --git a/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx b/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx index 69729a5967c..ee7b8f032a0 100644 --- a/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx +++ b/packages/grafana-ui/src/components/FileUpload/FileUpload.tsx @@ -40,13 +40,16 @@ export const FileUpload: FC = ({ const style = getStyles(theme, size); const [fileName, setFileName] = useState(''); - const onChange = useCallback((event: FormEvent) => { - const file = event.currentTarget?.files?.[0]; - if (file) { - setFileName(file.name ?? ''); - } - onFileUpload(event); - }, []); + const onChange = useCallback( + (event: FormEvent) => { + const file = event.currentTarget?.files?.[0]; + if (file) { + setFileName(file.name ?? ''); + } + onFileUpload(event); + }, + [onFileUpload] + ); return ( <> diff --git a/packages/grafana-ui/src/components/Forms/Form.tsx b/packages/grafana-ui/src/components/Forms/Form.tsx index 387aefa2df7..6307f9cd57d 100644 --- a/packages/grafana-ui/src/components/Forms/Form.tsx +++ b/packages/grafana-ui/src/components/Forms/Form.tsx @@ -33,7 +33,7 @@ export function Form({ if (validateOnMount) { triggerValidation(validateFieldsOnMount); } - }, []); + }, [triggerValidation, validateFieldsOnMount, validateOnMount]); return (
({ fullWidth = false, }: RadioButtonGroupProps) { const handleOnChange = useCallback( - (option: SelectableValue) => { + (option: SelectableValue) => { return () => { if (onChange) { onChange(option.value); diff --git a/packages/grafana-ui/src/components/Logs/LogRowContext.tsx b/packages/grafana-ui/src/components/Logs/LogRowContext.tsx index 2ff8ca671fc..618ec1b9ea0 100644 --- a/packages/grafana-ui/src/components/Logs/LogRowContext.tsx +++ b/packages/grafana-ui/src/components/Logs/LogRowContext.tsx @@ -147,7 +147,7 @@ const LogRowContextGroup: React.FunctionComponent = ({ if (shouldScrollToBottom && listContainerRef.current) { setScrollTop(listContainerRef.current.offsetHeight); } - }); + }, [shouldScrollToBottom]); const headerProps = { row, @@ -197,18 +197,17 @@ export const LogRowContext: React.FunctionComponent = ({ onLoadMoreContext, hasMoreContextRows, }) => { - const handleEscKeyDown = (e: KeyboardEvent): void => { - if (e.keyCode === 27) { - onOutsideClick(); - } - }; - useEffect(() => { + const handleEscKeyDown = (e: KeyboardEvent): void => { + if (e.keyCode === 27) { + onOutsideClick(); + } + }; document.addEventListener('keydown', handleEscKeyDown, false); return () => { document.removeEventListener('keydown', handleEscKeyDown, false); }; - }, []); + }, [onOutsideClick]); return ( diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx index 6284723d994..ecd9f111c28 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx @@ -4,13 +4,13 @@ import { FieldMatcherID, fieldMatchers } from '@grafana/data'; import { Input } from '../Input/Input'; export const FieldNameByRegexMatcherEditor = memo>(props => { - const { options } = props; + const { options, onChange } = props; const onBlur = useCallback( (e: React.FocusEvent) => { - return props.onChange(e.target.value); + return onChange(e.target.value); }, - [props.onChange] + [onChange] ); return ; diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx index ab59eb0672d..1131777d1ad 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx @@ -4,7 +4,7 @@ import { FieldMatcherID, fieldMatchers, getFieldDisplayName, SelectableValue, Da import { Select } from '../Select/Select'; export const FieldNameMatcherEditor = memo>(props => { - const { data, options } = props; + const { data, options, onChange: onChangeFromProps } = props; const names = useFieldDisplayNames(data); const selectOptions = useSelectOptions(names); @@ -13,9 +13,9 @@ export const FieldNameMatcherEditor = memo>(props => { if (!selection.value || !names.has(selection.value)) { return; } - return props.onChange(selection.value); + return onChangeFromProps(selection.value); }, - [names, props.onChange] + [names, onChangeFromProps] ); const selectedOption = selectOptions.find(v => v.value === options); diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldTypeMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldTypeMatcherEditor.tsx index c48895fd077..cb2fc2798f8 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldTypeMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldTypeMatcherEditor.tsx @@ -4,15 +4,15 @@ import { FieldMatcherID, fieldMatchers, SelectableValue, FieldType, DataFrame } import { Select } from '../Select/Select'; export const FieldTypeMatcherEditor = memo>(props => { - const { data, options } = props; + const { data, options, onChange: onChangeFromProps } = props; const counts = useFieldCounts(data); const selectOptions = useSelectOptions(counts, options); const onChange = useCallback( (selection: SelectableValue) => { - return props.onChange(selection.value!); + return onChangeFromProps(selection.value!); }, - [counts, props.onChange] + [onChangeFromProps] ); const selectedOption = selectOptions.find(v => v.value === options); diff --git a/packages/grafana-ui/src/components/OptionsUI/number.tsx b/packages/grafana-ui/src/components/OptionsUI/number.tsx index 4bbbf28ff8f..a2741d7f1d5 100644 --- a/packages/grafana-ui/src/components/OptionsUI/number.tsx +++ b/packages/grafana-ui/src/components/OptionsUI/number.tsx @@ -36,7 +36,7 @@ export const NumberValueEditor: React.FC({ } onChange(value); }, - [isMulti, value, onChange] + [isMulti, onChange] ); let ReactSelectComponent: ReactSelect | Creatable = ReactSelect; const creatableProps: any = {}; diff --git a/packages/grafana-ui/src/components/Table/FilterList.tsx b/packages/grafana-ui/src/components/Table/FilterList.tsx index 2439bb8c9ae..15206f831fa 100644 --- a/packages/grafana-ui/src/components/Table/FilterList.tsx +++ b/packages/grafana-ui/src/components/Table/FilterList.tsx @@ -24,7 +24,7 @@ export const FilterList: FC = ({ options, values, onChange }) => { searchFilter, ]); const gutter = parseInt(theme.spacing.sm, 10); - const height = useMemo(() => Math.min(items.length * ITEM_HEIGHT, MIN_HEIGHT) + gutter, [items]); + const height = useMemo(() => Math.min(items.length * ITEM_HEIGHT, MIN_HEIGHT) + gutter, [gutter, items.length]); const onInputChange = useCallback( (event: React.FormEvent) => { diff --git a/packages/grafana-ui/src/components/Table/Table.tsx b/packages/grafana-ui/src/components/Table/Table.tsx index 4dcdf18d632..b2202adeedc 100644 --- a/packages/grafana-ui/src/components/Table/Table.tsx +++ b/packages/grafana-ui/src/components/Table/Table.tsx @@ -47,13 +47,12 @@ export interface Props { interface ReactTableInternalState extends UseResizeColumnsState<{}>, UseSortByState<{}>, UseFiltersState<{}> {} -function useTableStateReducer(props: Props) { +function useTableStateReducer({ onColumnResize, onSortByChange, data }: Props) { return useCallback( (newState: ReactTableInternalState, action: any) => { switch (action.type) { case 'columnDoneResizing': - if (props.onColumnResize) { - const { data } = props; + if (onColumnResize) { const info = (newState.columnResizing.headerIdWidths as any)[0]; const columnIdString = info[0]; const fieldIndex = parseInt(columnIdString, 10); @@ -65,11 +64,10 @@ function useTableStateReducer(props: Props) { } const fieldDisplayName = getFieldDisplayName(field, data); - props.onColumnResize(fieldDisplayName, width); + onColumnResize(fieldDisplayName, width); } case 'toggleSortBy': - if (props.onSortByChange) { - const { data } = props; + if (onSortByChange) { const sortByFields: TableSortByFieldState[] = []; for (const sortItem of newState.sortBy) { @@ -84,24 +82,24 @@ function useTableStateReducer(props: Props) { }); } - props.onSortByChange(sortByFields); + onSortByChange(sortByFields); } break; } return newState; }, - [props.onColumnResize, props.onSortByChange, props.data] + [data, onColumnResize, onSortByChange] ); } -function getInitialState(props: Props, columns: Column[]): Partial { +function getInitialState(initialSortBy: Props['initialSortBy'], columns: Column[]): Partial { const state: Partial = {}; - if (props.initialSortBy) { + if (initialSortBy) { state.sortBy = []; - for (const sortBy of props.initialSortBy) { + for (const sortBy of initialSortBy) { for (const col of columns) { if (col.Header === sortBy.displayName) { state.sortBy.push({ id: col.id as string, desc: sortBy.desc }); @@ -123,6 +121,7 @@ export const Table: FC = memo((props: Props) => { columnMinWidth = COLUMN_MIN_WIDTH, noHeader, resizable = true, + initialSortBy, } = props; const theme = useTheme(); const tableStyles = getTableStyles(theme); @@ -151,9 +150,9 @@ export const Table: FC = memo((props: Props) => { data: memoizedData, disableResizing: !resizable, stateReducer: stateReducer, - initialState: getInitialState(props, memoizedColumns), + initialState: getInitialState(initialSortBy, memoizedColumns), }), - [memoizedColumns, memoizedData, stateReducer, resizable] + [initialSortBy, memoizedColumns, memoizedData, resizable, stateReducer] ); const { getTableProps, headerGroups, rows, prepareRow, totalColumnsWidth } = useTable( @@ -164,6 +163,8 @@ export const Table: FC = memo((props: Props) => { useResizeColumns ); + const { fields } = data; + const RenderRow = React.useCallback( ({ index, style }) => { const row = rows[index]; @@ -173,7 +174,7 @@ export const Table: FC = memo((props: Props) => { {row.cells.map((cell: Cell, index: number) => ( = memo((props: Props) => { ); }, - [prepareRow, rows] + [fields, onCellFilterAdded, prepareRow, rows, tableStyles] ); const headerHeight = noHeader ? 0 : tableStyles.cellHeight; diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.tsx b/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.tsx index 6e801d27116..0462d6d1c72 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerCalendar.tsx @@ -1,4 +1,4 @@ -import React, { FormEvent, memo, useCallback, useEffect, useState } from 'react'; +import React, { FormEvent, memo, useCallback } from 'react'; import { css } from 'emotion'; import Calendar from 'react-calendar/dist/entry.nostyle'; import { dateTime, DateTime, dateTimeParse, GrafanaTheme, TimeZone } from '@grafana/data'; @@ -244,15 +244,11 @@ const Header = memo(({ onClose }) => { }); const Body = memo(({ onChange, from, to, timeZone }) => { - const [value, setValue] = useState(); + const value = inputToValue(from, to); const theme = useTheme(); const onCalendarChange = useOnCalendarChange(onChange, timeZone); const styles = getBodyStyles(theme); - useEffect(() => { - setValue(inputToValue(from, to)); - }, []); - return ( void, t onChange(from, to); }, - [onChange] + [onChange, timeZone] ); } diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerContent.tsx index 3cad5e7de27..4d2d7404584 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimePickerContent.tsx @@ -192,15 +192,15 @@ export const TimePickerContent: React.FC = props => { }; const NarrowScreenForm: React.FC = props => { - if (!props.visible) { - return null; - } - const theme = useTheme(); const styles = getNarrowScreenStyles(theme); const isAbsolute = isDateTime(props.value.raw.from) || isDateTime(props.value.raw.to); const [collapsed, setCollapsed] = useState(isAbsolute); + if (!props.visible) { + return null; + } + return ( <>
= props => { }; const FullScreenForm: React.FC = props => { + const theme = useTheme(); + const styles = getFullScreenStyles(theme); + if (!props.visible) { return null; } - const theme = useTheme(); - const styles = getFullScreenStyles(theme); - return ( <>
diff --git a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeForm.tsx b/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeForm.tsx index bf8d3a2f9cc..034b3bc1efe 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeForm.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimeRangePicker/TimeRangeForm.tsx @@ -32,7 +32,7 @@ interface InputState { const errorMessage = 'Please enter a past date or "now"'; export const TimeRangeForm: React.FC = props => { - const { value, isFullscreen = false, timeZone, roundup } = props; + const { value, isFullscreen = false, timeZone, onApply: onApplyFromProps } = props; const [from, setFrom] = useState(valueToState(value.raw.from, false, timeZone)); const [to, setTo] = useState(valueToState(value.raw.to, true, timeZone)); @@ -72,9 +72,9 @@ export const TimeRangeForm: React.FC = props => { const raw: RawTimeRange = { from: from.value, to: to.value }; const timeRange = rangeUtil.convertRawToRange(raw, timeZone); - props.onApply(timeRange); + onApplyFromProps(timeRange); }, - [from, to, roundup, timeZone] + [from.invalid, from.value, onApplyFromProps, timeZone, to.invalid, to.value] ); const onChange = useCallback( diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx b/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx index 1d31b4baa0b..dd3d87ec9fb 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimeZonePicker.tsx @@ -63,7 +63,7 @@ interface SelectableZoneGroup extends SelectableValue { const useTimeZones = (includeInternal: boolean): SelectableZoneGroup[] => { const now = Date.now(); - return getTimeZoneGroups(includeInternal).map((group: GroupedTimeZones) => { + const timeZoneGroups = getTimeZoneGroups(includeInternal).map((group: GroupedTimeZones) => { const options = group.zones.reduce((options: SelectableZone[], zone) => { const info = getTimeZoneInfo(zone, now); @@ -74,7 +74,7 @@ const useTimeZones = (includeInternal: boolean): SelectableZoneGroup[] => { options.push({ label: info.name, value: info.zone, - searchIndex: useSearchIndex(info, now), + searchIndex: getSearchIndex(info, now), }); return options; @@ -85,6 +85,7 @@ const useTimeZones = (includeInternal: boolean): SelectableZoneGroup[] => { options, }; }); + return timeZoneGroups; }; const useSelectedTimeZone = ( @@ -135,19 +136,17 @@ const useFilterBySearchIndex = () => { }, []); }; -const useSearchIndex = (info: TimeZoneInfo, timestamp: number): string => { - return useMemo(() => { - const parts: string[] = [ - toLower(info.name), - toLower(info.abbreviation), - toLower(formatUtcOffset(timestamp, info.zone)), - ]; +const getSearchIndex = (info: TimeZoneInfo, timestamp: number): string => { + const parts: string[] = [ + toLower(info.name), + toLower(info.abbreviation), + toLower(formatUtcOffset(timestamp, info.zone)), + ]; - for (const country of info.countries) { - parts.push(toLower(country.name)); - parts.push(toLower(country.code)); - } + for (const country of info.countries) { + parts.push(toLower(country.name)); + parts.push(toLower(country.code)); + } - return parts.join('|'); - }, [info.zone, info.abbreviation, info.offsetInMins]); + return parts.join('|'); }; diff --git a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneDescription.tsx b/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneDescription.tsx index e1cb26ccbe0..e02510fc92f 100644 --- a/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneDescription.tsx +++ b/packages/grafana-ui/src/components/TimePicker/TimeZonePicker/TimeZoneDescription.tsx @@ -8,21 +8,25 @@ interface Props { } export const TimeZoneDescription: React.FC> = ({ info }) => { - if (!info) { - return null; - } - const theme = useTheme(); const styles = getStyles(theme); const description = useDescription(info); + if (!info) { + return null; + } + return
{description}
; }; -const useDescription = (info: TimeZoneInfo): string => { +const useDescription = (info?: TimeZoneInfo): string => { return useMemo(() => { const parts: string[] = []; + if (!info) { + return ''; + } + if (info.countries.length > 0) { const country = info.countries[0]; parts.push(country.name); @@ -33,7 +37,7 @@ const useDescription = (info: TimeZoneInfo): string => { } return parts.join(', '); - }, [info.zone]); + }, [info]); }; const getStyles = stylesFactory((theme: GrafanaTheme) => { diff --git a/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx b/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx index 4b8312a8268..0a1b02d37a1 100644 --- a/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx @@ -102,7 +102,6 @@ export class PanelEditorUnconnected extends PureComponent { }; onFieldConfigChange = (config: FieldConfigSource) => { - console.log(config); const { panel } = this.props; panel.updateFieldConfig({ diff --git a/yarn.lock b/yarn.lock index 7c4e2fdb7c0..95ca2d4acad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12624,10 +12624,10 @@ eslint-plugin-prettier@3.1.4: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-react-hooks@4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.5.tgz#4879003aa38e5d05d0312175beb6e4a1f617bfcf" - integrity sha512-3YLSjoArsE2rUwL8li4Yxx1SUg3DQWp+78N3bcJQGWVZckcp+yeQGsap/MSq05+thJk57o+Ww4PtZukXGL02TQ== +eslint-plugin-react-hooks@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.2.tgz#2eb53731d11c95826ef7a7272303eabb5c9a271e" + integrity sha512-ykUeqkGyUGgwTtk78C0o8UG2fzwmgJ0qxBGPp2WqRKsTwcLuVf01kTDRAtOsd4u6whX2XOC8749n2vPydP82fg== eslint-scope@^4.0.3: version "4.0.3"