mirror of
https://github.com/grafana/grafana.git
synced 2024-11-22 08:56:43 -06:00
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
This commit is contained in:
parent
f158e4f526
commit
e1c44d7a8a
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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 (
|
||||
<BigValue
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
theme={useTheme()}
|
||||
theme={theme}
|
||||
width={width}
|
||||
height={height}
|
||||
colorMode={colorMode}
|
||||
|
@ -28,8 +28,8 @@ const getTooltipContainerStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
});
|
||||
|
||||
export const TooltipContainer: React.FC<TooltipContainerProps> = ({
|
||||
position,
|
||||
offset,
|
||||
position: { x: positionX, y: positionY },
|
||||
offset: { x: offsetX, y: offsetY },
|
||||
children,
|
||||
className,
|
||||
...otherProps
|
||||
@ -38,8 +38,8 @@ export const TooltipContainer: React.FC<TooltipContainerProps> = ({
|
||||
const tooltipRef = useRef<HTMLDivElement>(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<TooltipContainerProps> = ({
|
||||
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<TooltipContainerProps> = ({
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -169,7 +169,7 @@ export const ContextMenu: React.FC<ContextMenuProps> = React.memo(({ x, y, onClo
|
||||
top: collisions.bottom ? y - rect.height - OFFSET : y + OFFSET,
|
||||
});
|
||||
}
|
||||
}, [menuRef.current]);
|
||||
}, [x, y]);
|
||||
|
||||
useClickAway(menuRef, () => {
|
||||
if (onClose) {
|
||||
|
@ -82,7 +82,7 @@ export const DataLinkInput: React.FC<DataLinkInputProps> = 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) {
|
||||
|
@ -68,7 +68,7 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = props => {
|
||||
...change,
|
||||
});
|
||||
},
|
||||
[dataSourceConfig]
|
||||
[dataSourceConfig, onChange]
|
||||
);
|
||||
|
||||
switch (dataSourceConfig.access) {
|
||||
|
@ -40,13 +40,16 @@ export const FileUpload: FC<Props> = ({
|
||||
const style = getStyles(theme, size);
|
||||
const [fileName, setFileName] = useState('');
|
||||
|
||||
const onChange = useCallback((event: FormEvent<HTMLInputElement>) => {
|
||||
const file = event.currentTarget?.files?.[0];
|
||||
if (file) {
|
||||
setFileName(file.name ?? '');
|
||||
}
|
||||
onFileUpload(event);
|
||||
}, []);
|
||||
const onChange = useCallback(
|
||||
(event: FormEvent<HTMLInputElement>) => {
|
||||
const file = event.currentTarget?.files?.[0];
|
||||
if (file) {
|
||||
setFileName(file.name ?? '');
|
||||
}
|
||||
onFileUpload(event);
|
||||
},
|
||||
[onFileUpload]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -33,7 +33,7 @@ export function Form<T>({
|
||||
if (validateOnMount) {
|
||||
triggerValidation(validateFieldsOnMount);
|
||||
}
|
||||
}, []);
|
||||
}, [triggerValidation, validateFieldsOnMount, validateOnMount]);
|
||||
|
||||
return (
|
||||
<form
|
||||
|
@ -56,7 +56,7 @@ export function RadioButtonGroup<T>({
|
||||
fullWidth = false,
|
||||
}: RadioButtonGroupProps<T>) {
|
||||
const handleOnChange = useCallback(
|
||||
(option: SelectableValue<T>) => {
|
||||
(option: SelectableValue) => {
|
||||
return () => {
|
||||
if (onChange) {
|
||||
onChange(option.value);
|
||||
|
@ -147,7 +147,7 @@ const LogRowContextGroup: React.FunctionComponent<LogRowContextGroupProps> = ({
|
||||
if (shouldScrollToBottom && listContainerRef.current) {
|
||||
setScrollTop(listContainerRef.current.offsetHeight);
|
||||
}
|
||||
});
|
||||
}, [shouldScrollToBottom]);
|
||||
|
||||
const headerProps = {
|
||||
row,
|
||||
@ -197,18 +197,17 @@ export const LogRowContext: React.FunctionComponent<LogRowContextProps> = ({
|
||||
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 (
|
||||
<ClickOutsideWrapper onClick={onOutsideClick}>
|
||||
|
@ -4,13 +4,13 @@ import { FieldMatcherID, fieldMatchers } from '@grafana/data';
|
||||
import { Input } from '../Input/Input';
|
||||
|
||||
export const FieldNameByRegexMatcherEditor = memo<MatcherUIProps<string>>(props => {
|
||||
const { options } = props;
|
||||
const { options, onChange } = props;
|
||||
|
||||
const onBlur = useCallback(
|
||||
(e: React.FocusEvent<HTMLInputElement>) => {
|
||||
return props.onChange(e.target.value);
|
||||
return onChange(e.target.value);
|
||||
},
|
||||
[props.onChange]
|
||||
[onChange]
|
||||
);
|
||||
|
||||
return <Input placeholder="Enter regular expression" defaultValue={options} onBlur={onBlur} />;
|
||||
|
@ -4,7 +4,7 @@ import { FieldMatcherID, fieldMatchers, getFieldDisplayName, SelectableValue, Da
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
export const FieldNameMatcherEditor = memo<MatcherUIProps<string>>(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<MatcherUIProps<string>>(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);
|
||||
|
@ -4,15 +4,15 @@ import { FieldMatcherID, fieldMatchers, SelectableValue, FieldType, DataFrame }
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
export const FieldTypeMatcherEditor = memo<MatcherUIProps<string>>(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<string>) => {
|
||||
return props.onChange(selection.value!);
|
||||
return onChangeFromProps(selection.value!);
|
||||
},
|
||||
[counts, props.onChange]
|
||||
[onChangeFromProps]
|
||||
);
|
||||
|
||||
const selectedOption = selectOptions.find(v => v.value === options);
|
||||
|
@ -36,7 +36,7 @@ export const NumberValueEditor: React.FC<FieldConfigEditorProps<number, NumberFi
|
||||
);
|
||||
}
|
||||
},
|
||||
[onChange]
|
||||
[onChange, settings?.integer]
|
||||
);
|
||||
|
||||
const defaultValue = value === undefined || value === null || isNaN(value) ? '' : value.toString();
|
||||
|
@ -24,7 +24,7 @@ export const StringValueEditor: React.FC<FieldConfigEditorProps<string, StringFi
|
||||
onChange(evt.currentTarget.value.trim() === '' ? undefined : evt.currentTarget.value);
|
||||
}
|
||||
},
|
||||
[onChange]
|
||||
[item.settings?.useTextarea, onChange]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -144,7 +144,7 @@ export function SelectBase<T>({
|
||||
}
|
||||
onChange(value);
|
||||
},
|
||||
[isMulti, value, onChange]
|
||||
[isMulti, onChange]
|
||||
);
|
||||
let ReactSelectComponent: ReactSelect | Creatable = ReactSelect;
|
||||
const creatableProps: any = {};
|
||||
|
@ -24,7 +24,7 @@ export const FilterList: FC<Props> = ({ 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<HTMLInputElement>) => {
|
||||
|
@ -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<ReactTableInternalState> {
|
||||
function getInitialState(initialSortBy: Props['initialSortBy'], columns: Column[]): Partial<ReactTableInternalState> {
|
||||
const state: Partial<ReactTableInternalState> = {};
|
||||
|
||||
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<Props> = 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<Props> = 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<Props> = 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<Props> = memo((props: Props) => {
|
||||
{row.cells.map((cell: Cell, index: number) => (
|
||||
<TableCell
|
||||
key={index}
|
||||
field={data.fields[index]}
|
||||
field={fields[index]}
|
||||
tableStyles={tableStyles}
|
||||
cell={cell}
|
||||
onCellFilterAdded={onCellFilterAdded}
|
||||
@ -182,7 +183,7 @@ export const Table: FC<Props> = memo((props: Props) => {
|
||||
</div>
|
||||
);
|
||||
},
|
||||
[prepareRow, rows]
|
||||
[fields, onCellFilterAdded, prepareRow, rows, tableStyles]
|
||||
);
|
||||
|
||||
const headerHeight = noHeader ? 0 : tableStyles.cellHeight;
|
||||
|
@ -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<Props>(({ onClose }) => {
|
||||
});
|
||||
|
||||
const Body = memo<Props>(({ onChange, from, to, timeZone }) => {
|
||||
const [value, setValue] = useState<Date[]>();
|
||||
const value = inputToValue(from, to);
|
||||
const theme = useTheme();
|
||||
const onCalendarChange = useOnCalendarChange(onChange, timeZone);
|
||||
const styles = getBodyStyles(theme);
|
||||
|
||||
useEffect(() => {
|
||||
setValue(inputToValue(from, to));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Calendar
|
||||
selectRange={true}
|
||||
@ -309,7 +305,7 @@ function useOnCalendarChange(onChange: (from: DateTime, to: DateTime) => void, t
|
||||
|
||||
onChange(from, to);
|
||||
},
|
||||
[onChange]
|
||||
[onChange, timeZone]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -192,15 +192,15 @@ export const TimePickerContent: React.FC<Props> = props => {
|
||||
};
|
||||
|
||||
const NarrowScreenForm: React.FC<FormProps> = 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 (
|
||||
<>
|
||||
<div
|
||||
@ -238,13 +238,13 @@ const NarrowScreenForm: React.FC<FormProps> = props => {
|
||||
};
|
||||
|
||||
const FullScreenForm: React.FC<FormProps> = props => {
|
||||
const theme = useTheme();
|
||||
const styles = getFullScreenStyles(theme);
|
||||
|
||||
if (!props.visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const theme = useTheme();
|
||||
const styles = getFullScreenStyles(theme);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.container}>
|
||||
|
@ -32,7 +32,7 @@ interface InputState {
|
||||
const errorMessage = 'Please enter a past date or "now"';
|
||||
|
||||
export const TimeRangeForm: React.FC<Props> = props => {
|
||||
const { value, isFullscreen = false, timeZone, roundup } = props;
|
||||
const { value, isFullscreen = false, timeZone, onApply: onApplyFromProps } = props;
|
||||
|
||||
const [from, setFrom] = useState<InputState>(valueToState(value.raw.from, false, timeZone));
|
||||
const [to, setTo] = useState<InputState>(valueToState(value.raw.to, true, timeZone));
|
||||
@ -72,9 +72,9 @@ export const TimeRangeForm: React.FC<Props> = 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(
|
||||
|
@ -63,7 +63,7 @@ interface SelectableZoneGroup extends SelectableValue<string> {
|
||||
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('|');
|
||||
};
|
||||
|
@ -8,21 +8,25 @@ interface Props {
|
||||
}
|
||||
|
||||
export const TimeZoneDescription: React.FC<PropsWithChildren<Props>> = ({ info }) => {
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const theme = useTheme();
|
||||
const styles = getStyles(theme);
|
||||
const description = useDescription(info);
|
||||
|
||||
if (!info) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <div className={styles.description}>{description}</div>;
|
||||
};
|
||||
|
||||
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) => {
|
||||
|
@ -102,7 +102,6 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
||||
};
|
||||
|
||||
onFieldConfigChange = (config: FieldConfigSource) => {
|
||||
console.log(config);
|
||||
const { panel } = this.props;
|
||||
|
||||
panel.updateFieldConfig({
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user