[react@18] Fix useCallback breaking type changes (#182344)

## Summary

Prep work for React@18 bump
https://github.com/elastic/kibana/issues/138222

In React@18 `useCallback` types has changed that introduced breaking
changes:
https://github.com/DefinitelyTyped/DefinitelyTyped/issues/46691

Fixed using:

https://github.com/eps1lon/types-react-codemod?tab=readme-ov-file#usecallback-implicit-any

**Tried to do my best with fixing the types, but if you disagree or have
a better idea how it should be solved feel free to suggest changes or
commit directly to the branch 🙏**

---------

Co-authored-by: Sergi Massaneda <sergi.massaneda@elastic.co>
Co-authored-by: Sébastien Loix <sabee77@gmail.com>
Co-authored-by: Nick Peihl <nick.peihl@elastic.co>
Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
Co-authored-by: Felix Stürmer <felix.stuermer@elastic.co>
Co-authored-by: nickofthyme <nicholas.partridge@elastic.co>
Co-authored-by: Davis McPhee <davis.mcphee@elastic.co>
Co-authored-by: Vitalii Dmyterko <92328789+vitaliidm@users.noreply.github.com>
Co-authored-by: Maxim Palenov <maxim.palenov@elastic.co>
Co-authored-by: Christos Nasikas <christos.nasikas@elastic.co>
Co-authored-by: Anton Dosov <anton.dosov@elastic.co>
This commit is contained in:
Patryk Kopyciński 2024-08-28 16:33:35 +02:00 committed by GitHub
parent 97b54795f4
commit 2d1d592a3b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
432 changed files with 1250 additions and 875 deletions

View file

@ -8,7 +8,15 @@
import { i18n } from '@kbn/i18n';
import useUpdateEffect from 'react-use/lib/useUpdateEffect';
import React, { useState, useCallback, Dispatch, FocusEvent, useContext, useMemo } from 'react';
import React, {
useState,
useCallback,
Dispatch,
FocusEvent,
useContext,
useMemo,
ChangeEventHandler,
} from 'react';
import { css } from '@emotion/react';
import {
@ -126,9 +134,9 @@ export function ColorRangeItem({
[colorRange.start, colorRanges, dispatch, index, popoverInFocus, dataBounds, palettes, isLast]
);
const onValueChange = useCallback(
const onValueChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
({ target: { value: targetValue } }) => {
setLocalValue(targetValue);
setLocalValue(+targetValue);
dispatch({
type: 'updateValue',
payload: { index, value: targetValue, accessor, dataBounds, palettes },
@ -138,7 +146,7 @@ export function ColorRangeItem({
);
const onUpdateColor = useCallback(
(color) => {
(color: string) => {
dispatch({ type: 'updateColor', payload: { index, color, dataBounds, palettes } });
},
[dispatch, index, dataBounds, palettes]

View file

@ -14,6 +14,7 @@ export {
type DraggingIdentifier,
type DragDropAction,
type DropOverlayWrapperProps,
type DroppableProps,
Draggable,
Droppable,
useDragDropContext,

View file

@ -102,7 +102,7 @@ const GroupPanelComponent = <T,>({
);
const onToggle = useCallback(
(isOpen) => {
(isOpen: boolean) => {
if (onToggleGroup) {
onToggleGroup(isOpen, groupBucket);
}

View file

@ -56,7 +56,7 @@ export type DynamicGroupingProps<T> = Pick<
/** Interface for configuring grouping package where T is the consumer `GroupingAggregation`
* @interface GroupingArgs<T>
*/
interface GroupingArgs<T> {
export interface GroupingArgs<T> {
componentProps: StaticGroupingProps<T>;
defaultGroupingOptions: GroupOption[];
fields: FieldSpec[];

View file

@ -70,7 +70,7 @@ export const CodeEditor = ({ onChange, type, isReadOnly, name, ...props }: CodeE
editorModel.setValue(trimmedValue);
}, []);
const editorDidMount = useCallback(
const editorDidMount = useCallback<NonNullable<KibanaReactCodeEditorProps['editorDidMount']>>(
(editor) => {
setEditorCalculatedHeight(editor);

View file

@ -13,6 +13,7 @@ import { getFieldInputValue } from '@kbn/management-settings-utilities';
import { useUpdate } from '@kbn/management-settings-utilities';
import { debounce } from 'lodash';
import { OnInputChangeFn } from '@kbn/management-settings-types';
import { useServices } from '../services';
import { InputProps } from '../types';
import { TEST_SUBJ_PREFIX_FIELD } from '.';
@ -39,7 +40,7 @@ export const ArrayInput = ({
const onUpdate = useUpdate({ onInputChange, field });
const updateValue = useCallback(
async (newValue: string, onUpdateFn) => {
async (newValue: string, onUpdateFn: OnInputChangeFn<'array'>) => {
const parsedValue = newValue
.replace(REGEX, ',')
.split(',')

View file

@ -12,6 +12,7 @@ import { EuiFieldNumber, EuiFieldNumberProps } from '@elastic/eui';
import { getFieldInputValue, useUpdate } from '@kbn/management-settings-utilities';
import { debounce } from 'lodash';
import { OnInputChangeFn } from '@kbn/management-settings-types';
import { InputProps } from '../types';
import { TEST_SUBJ_PREFIX_FIELD } from '.';
import { useServices } from '../services';
@ -36,7 +37,7 @@ export const NumberInput = ({
const onUpdate = useUpdate({ onInputChange, field });
const updateValue = useCallback(
async (newValue: number, onUpdateFn) => {
async (newValue: number, onUpdateFn: OnInputChangeFn<'number'>) => {
const validationResponse = await validateChange(field.id, newValue);
if (validationResponse.successfulValidation && !validationResponse.valid) {
onUpdateFn({

View file

@ -64,7 +64,7 @@ export const AutocompleteFieldListsComponent: React.FC<AutocompleteFieldListsPro
largeLists: [],
});
const { loading, result, start } = useFindListsBySize();
const getLabel = useCallback(({ name }) => name, []);
const getLabel = useCallback(({ name }: ListSchema) => name, []);
const optionsMemo = useMemo(
() => filterFieldToList(listData, selectedField),

View file

@ -44,7 +44,7 @@ export const OperatorComponent: React.FC<OperatorState> = ({
selectedField,
'aria-label': ariaLabel,
}): JSX.Element => {
const getLabel = useCallback(({ message }): string => message, []);
const getLabel = useCallback(({ message }: OperatorOption): string => message, []);
const optionsMemo = useMemo(
(): OperatorOption[] =>
operatorOptions != null && operatorOptions.length > 0

View file

@ -9,7 +9,7 @@
import React, { useCallback } from 'react';
import type { FC } from 'react';
import type { IconType, SearchFilterConfig } from '@elastic/eui';
import type { EuiSearchBarProps, IconType, SearchFilterConfig } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiButton, EuiSearchBar } from '@elastic/eui';
import type { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
import type { GetExceptionItemProps } from '../types';
@ -73,7 +73,7 @@ const SearchBarComponent: FC<SearchBarProps> = ({
onSearch,
onAddExceptionClick,
}) => {
const handleOnSearch = useCallback(
const handleOnSearch = useCallback<NonNullable<EuiSearchBarProps['onChange']>>(
({ queryText }): void => {
onSearch({ search: queryText });
},

View file

@ -7,7 +7,7 @@
*/
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { EuiFormRow, EuiHorizontalRule, EuiRange } from '@elastic/eui';
import { EuiFormRow, EuiHorizontalRule, EuiRange, EuiRangeProps } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { debounce } from 'lodash';
import { RowHeightSettings, RowHeightSettingsProps } from './row_height_settings';
@ -63,9 +63,9 @@ export const UnifiedDataTableAdditionalDisplaySettings: React.FC<
[onChangeSampleSize]
);
const onChangeActiveSampleSize = useCallback(
const onChangeActiveSampleSize = useCallback<NonNullable<EuiRangeProps['onChange']>>(
(event) => {
if (!event.target.value) {
if (!('value' in event.target) || !event.target.value) {
setActiveSampleSize('');
return;
}

View file

@ -28,6 +28,17 @@ const tooltipContent = {
}),
};
export interface ColorPickerProps {
overwriteColor?: string | null;
defaultColor?: string | null;
isClearable?: boolean;
setConfig: (config: { color?: string }) => void;
label?: string;
disableHelpTooltip?: boolean;
disabledMessage?: string;
showAlpha?: boolean;
}
export const ColorPicker = ({
overwriteColor,
defaultColor,
@ -37,16 +48,7 @@ export const ColorPicker = ({
disableHelpTooltip,
disabledMessage,
showAlpha,
}: {
overwriteColor?: string | null;
defaultColor?: string | null;
isClearable?: boolean;
setConfig: (config: { color?: string }) => void;
label?: string;
disableHelpTooltip?: boolean;
disabledMessage?: string;
showAlpha?: boolean;
}) => {
}: ColorPickerProps) => {
const [colorText, setColorText] = useState(overwriteColor || defaultColor);
const [validatedColor, setValidatedColor] = useState(overwriteColor || defaultColor);
const [currentColorAlpha, setCurrentColorAlpha] = useState(getColorAlpha(colorText));

View file

@ -33,6 +33,18 @@ export const defaultFilter: Query = {
language: 'kuery',
};
export interface FilterQueryInputProps {
inputFilter: Query | undefined;
onChange: (query: Query) => void;
dataView: DataViewBase;
helpMessage?: string | null;
label?: string;
initiallyOpen?: boolean;
['data-test-subj']?: string;
queryInputServices: QueryInputServices;
appName: string;
}
export function FilterQueryInput({
inputFilter,
onChange,
@ -43,17 +55,7 @@ export function FilterQueryInput({
['data-test-subj']: dataTestSubj,
queryInputServices,
appName,
}: {
inputFilter: Query | undefined;
onChange: (query: Query) => void;
dataView: DataViewBase;
helpMessage?: string | null;
label?: string;
initiallyOpen?: boolean;
['data-test-subj']?: string;
queryInputServices: QueryInputServices;
appName: string;
}) {
}: FilterQueryInputProps) {
const [filterPopoverOpen, setFilterPopoverOpen] = useState(Boolean(initiallyOpen));
const onClosePopup: EuiPopoverProps['closePopover'] = useCallback(() => {

View file

@ -40,6 +40,7 @@ export type {
IconSet,
AccessorConfig,
QueryInputServices,
ColorPickerProps,
} from './components';
export type { FormatFactory, LineStyle } from './types';

View file

@ -17,7 +17,7 @@ export const useIfMounted = () => {
[]
);
const ifMounted = useCallback((func) => {
const ifMounted = useCallback((func?: () => void) => {
if (isMounted.current && func) {
func();
}

View file

@ -194,7 +194,7 @@ export const GaugeComponent: FC<GaugeRenderProps> = ({
const getColor = useCallback(
(
value,
value: number,
paletteConfig: PaletteOutput<CustomPaletteState>,
bands: number[],
percentageMode?: boolean

View file

@ -18,6 +18,8 @@ import {
Wordcloud,
RenderChangeListener,
LEGACY_LIGHT_THEME,
ElementClickListener,
WordCloudElementEvent,
} from '@elastic/charts';
import { EmptyPlaceholder } from '@kbn/charts-plugin/public';
import {
@ -190,13 +192,13 @@ export const TagCloudChart = ({
[]
);
const handleWordClick = useCallback(
const handleWordClick = useCallback<ElementClickListener>(
(elements) => {
if (!bucket) {
return;
}
const termsBucketId = getColumnByAccessor(bucket, visData.columns)!.id;
const clickedValue = elements[0][0].text;
const clickedValue = (elements[0] as WordCloudElementEvent)[0].text;
const columnIndex = visData.columns.findIndex((col) => col.id === termsBucketId);
if (columnIndex < 0) {

View file

@ -11,7 +11,7 @@ import { animationFrameScheduler } from 'rxjs';
import { useCallback, useEffect, RefObject } from 'react';
import { filter, debounceTime } from 'rxjs';
import type { Chart } from '@elastic/charts';
import type { Chart, PointerUpdateListener } from '@elastic/charts';
import { parseSyncOptions } from './active_cursor_utils';
@ -24,9 +24,9 @@ export const useActiveCursor = (
activeCursor: ActiveCursor,
chartRef: RefObject<Chart>,
syncOptions: ActiveCursorSyncOption
) => {
): PointerUpdateListener => {
const { accessors, isDateHistogram } = parseSyncOptions(syncOptions);
const handleCursorUpdate = useCallback(
const handleCursorUpdate = useCallback<PointerUpdateListener>(
(cursor) => {
activeCursor.activeCursor$?.next({
cursor,

View file

@ -157,7 +157,7 @@ export const OptionsListPopoverSuggestions = ({
}, [loadMoreSuggestions, totalCardinality]);
const renderOption = useCallback(
(option, searchStringValue) => {
(option: EuiSelectableOption, searchStringValue: string) => {
if (!allowExpensiveQueries || searchTechnique === 'exact') return option.label;
return (

View file

@ -196,7 +196,7 @@ const IndexPatternEditorFlyoutContentComponent = ({
const getRollupIndices = (rollupCaps: RollupIndicesCapsResponse) => Object.keys(rollupCaps);
const onTypeChange = useCallback(
(newType) => {
(newType: INDEX_PATTERN_TYPE) => {
form.setFieldValue('title', '');
form.setFieldValue('name', '');
form.setFieldValue('timestampField', '');

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import React, { Fragment, useCallback, useMemo, useState, FC, PropsWithChildren } from 'react';
import React, { Fragment, useCallback, useMemo, useState, FC } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiSpacer, EuiText, useEuiPaddingSize } from '@elastic/eui';
import { css } from '@emotion/react';
@ -241,7 +241,7 @@ export function ContextAppContent({
);
}
const WrapperWithPadding: FC<PropsWithChildren<unknown>> = ({ children }) => {
const WrapperWithPadding: FC = ({ children }) => {
const padding = useEuiPaddingSize('s');
return (

View file

@ -250,7 +250,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps)
// As unifiedFieldListSidebarContainerRef ref can be empty in the beginning,
// we need to fetch the data once API becomes available and after documents are fetched
const initializeUnifiedFieldListSidebarContainerApi = useCallback(
(api) => {
(api: UnifiedFieldListSidebarContainerApi) => {
if (!api) {
return;
}

View file

@ -11,7 +11,7 @@ import { EuiFormRow, EuiSelect } from '@elastic/eui';
import { FieldHook, getFieldValidityAndErrorMessage } from '../../hook_form_lib';
interface Props {
export interface Props {
field: FieldHook;
euiFieldProps: {
options: Array<

View file

@ -94,7 +94,7 @@ export const DashboardLinkDestinationPicker = ({
);
const renderOption = useCallback(
(option, searchValue, contentClassName) => {
(option: DashboardComboBoxOption, searchValue: string, contentClassName: string) => {
const { label, key: dashboardId } = option;
return (
<EuiFlexGroup gutterSize="s" alignItems="center" className={contentClassName}>

View file

@ -10,6 +10,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import useMountedState from 'react-use/lib/useMountedState';
import {
DropResult,
EuiButton,
EuiButtonEmpty,
EuiButtonGroup,
@ -101,7 +102,7 @@ const LinksEditor = ({
}, [initialLinks]);
const onDragEnd = useCallback(
({ source, destination }) => {
({ source, destination }: DropResult) => {
if (source && destination) {
const newList = euiDragDropReorder(orderedLinks, source.index, destination.index).map(
(link, i) => {

View file

@ -5,12 +5,13 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { ComponentProps, useCallback, useEffect, useRef, useState } from 'react';
import type { Observable } from 'rxjs';
import type { AggregateQuery, Query } from '@kbn/es-query';
import { isEqual } from 'lodash';
import { isEqual, isObject } from 'lodash';
import type { LensEmbeddableOutput, Suggestion } from '@kbn/lens-plugin/public';
import type { Datatable } from '@kbn/expressions-plugin/common';
import { EditLensConfigPanelComponent } from '@kbn/lens-plugin/public/plugin';
import { deriveLensSuggestionFromLensAttributes } from '../utils/external_vis_context';
import {
@ -49,13 +50,16 @@ export function ChartConfigPanel({
const previousAdapters = useRef<Record<string, Datatable> | undefined>(undefined);
const previousQuery = useRef<Query | AggregateQuery | undefined>(undefined);
const updatePanelState = useCallback(
const updatePanelState = useCallback<
ComponentProps<EditLensConfigPanelComponent>['updatePanelState']
>(
(datasourceState, visualizationState, visualizationId) => {
const updatedSuggestion: Suggestion = {
...currentSuggestionContext?.suggestion,
visualizationId: visualizationId ?? currentSuggestionContext?.suggestion?.visualizationId,
...(datasourceState && { datasourceState }),
...(visualizationState && { visualizationState }),
...currentSuggestionContext.suggestion!,
visualizationId:
visualizationId ?? currentSuggestionContext.suggestion?.visualizationId ?? '',
...(isObject(datasourceState) && { datasourceState }),
...(isObject(visualizationState) && { visualizationState }),
};
onSuggestionContextEdit({
...currentSuggestionContext,
@ -65,7 +69,9 @@ export function ChartConfigPanel({
[currentSuggestionContext, onSuggestionContextEdit]
);
const updateSuggestion = useCallback(
const updateSuggestion = useCallback<
NonNullable<ComponentProps<EditLensConfigPanelComponent>['updateSuggestion']>
>(
(attributes) => {
const updatedSuggestion = deriveLensSuggestionFromLensAttributes({
externalVisContext: {

View file

@ -60,9 +60,11 @@ export const ToolbarSelector: React.FC<ToolbarSelectorProps> = ({
[]
);
const onSelectionChange = useCallback(
const onSelectionChange = useCallback<
NonNullable<EuiSelectableProps<SelectableEntry>['onChange']>
>(
(newOptions) => {
const chosenOption = newOptions.find(({ checked }: SelectableEntry) => checked === 'on');
const chosenOption = newOptions.find(({ checked }) => checked === 'on');
onChange?.(
chosenOption?.value && chosenOption?.value !== EMPTY_OPTION ? chosenOption : undefined
@ -139,7 +141,7 @@ export const ToolbarSelector: React.FC<ToolbarSelectorProps> = ({
anchorPosition="downLeft"
>
<EuiPopoverTitle paddingSize="s">{popoverTitle}</EuiPopoverTitle>
<EuiSelectable
<EuiSelectable<SelectableEntry>
id={`${dataTestSubj}Selectable`}
singleSelection
aria-label={popoverTitle}

View file

@ -7,10 +7,9 @@
*/
import { DataView, DataViewField, DataViewType } from '@kbn/data-views-plugin/common';
import { RequestAdapter } from '@kbn/inspector-plugin/common';
import { Suggestion } from '@kbn/lens-plugin/public';
import { renderHook } from '@testing-library/react-hooks';
import { act } from 'react-test-renderer';
import { UnifiedHistogramFetchStatus } from '../../types';
import { UnifiedHistogramFetchStatus, UnifiedHistogramSuggestionContext } from '../../types';
import { dataViewMock } from '../../__mocks__/data_view';
import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
import { lensAdaptersMock } from '../../__mocks__/lens_adapters';
@ -451,10 +450,12 @@ describe('useStateProps', () => {
expect(stateService.setBreakdownField).toHaveBeenLastCalledWith('field');
act(() => {
onSuggestionContextChange({ title: 'Stacked Bar' } as Suggestion);
onSuggestionContextChange({
suggestion: { title: 'Stacked Bar' },
} as UnifiedHistogramSuggestionContext);
});
expect(stateService.setCurrentSuggestionContext).toHaveBeenLastCalledWith({
title: 'Stacked Bar',
suggestion: { title: 'Stacked Bar' },
});
});

View file

@ -10,7 +10,11 @@ import { DataView, DataViewField, DataViewType } from '@kbn/data-views-plugin/co
import { AggregateQuery, isOfAggregateQueryType, Query } from '@kbn/es-query';
import type { RequestAdapter } from '@kbn/inspector-plugin/public';
import { useCallback, useEffect, useMemo } from 'react';
import { UnifiedHistogramChartLoadEvent, UnifiedHistogramFetchStatus } from '../../types';
import {
UnifiedHistogramChartLoadEvent,
UnifiedHistogramFetchStatus,
UnifiedHistogramSuggestionContext,
} from '../../types';
import type { UnifiedHistogramStateService } from '../services/state_service';
import {
breakdownFieldSelector,
@ -150,7 +154,7 @@ export const useStateProps = ({
);
const onSuggestionContextChange = useCallback(
(suggestionContext) => {
(suggestionContext: UnifiedHistogramSuggestionContext | undefined) => {
stateService?.setCurrentSuggestionContext(suggestionContext);
},
[stateService]

View file

@ -16,6 +16,7 @@ import {
EuiPanel,
EuiButtonGroup,
toSentenceCase,
Direction,
} from '@elastic/eui';
import type { DataViewListItem } from '@kbn/data-views-plugin/public';
import { i18n } from '@kbn/i18n';
@ -107,8 +108,8 @@ export function DataViewsList({
);
const onChangeSortDirection = useCallback(
(value) => {
sortingService.setDirection(value);
(value: string) => {
sortingService.setDirection(value as Direction);
setSortedDataViewsList((dataViews) => sortingService.sortData(dataViews));
},
[sortingService]

View file

@ -10,10 +10,11 @@ import React, { useCallback, useContext } from 'react';
import { DataView, DataViewField } from '@kbn/data-views-plugin/common';
import type { Filter } from '@kbn/es-query';
import { EuiToolTip, EuiFormRow } from '@elastic/eui';
import { FilterMetaParams } from '@kbn/es-query/src/filters/build_filters';
import type { Operator } from '../../filter_bar/filter_editor';
import { getFieldValidityAndErrorMessage } from '../../filter_bar/filter_editor/lib';
import { FiltersBuilderContextType } from '../context';
import { ParamsEditorInput } from './params_editor_input';
import { ParamsEditorInput, ParamsEditorInputProps } from './params_editor_input';
interface ParamsEditorProps {
dataView: DataView;
@ -37,15 +38,15 @@ export function ParamsEditor({
filtersForSuggestions,
}: ParamsEditorProps) {
const { disabled, suggestionsAbstraction } = useContext(FiltersBuilderContextType);
const onParamsChange = useCallback(
const onParamsChange = useCallback<ParamsEditorInputProps['onParamsChange']>(
(selectedParams) => {
onHandleParamsChange(selectedParams);
onHandleParamsChange(selectedParams as FilterMetaParams);
},
[onHandleParamsChange]
);
const onParamsUpdate = useCallback(
(value) => {
const onParamsUpdate = useCallback<ParamsEditorInputProps['onParamsUpdate']>(
(value: any) => {
onHandleParamsUpdate(value);
},
[onHandleParamsUpdate]

View file

@ -34,7 +34,7 @@ export const strings = {
}),
};
interface ParamsEditorInputProps {
export interface ParamsEditorInputProps {
dataView: DataView;
params: unknown;
onParamsChange: (params: unknown) => void;

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import React, { useState, useCallback } from 'react';
import React, { useState, useCallback, ChangeEventHandler } from 'react';
import { EuiButton, EuiForm, EuiFormRow, EuiFieldText, EuiSwitch } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { isEqual } from 'lodash';
@ -117,7 +117,7 @@ export function SaveQueryForm({
shouldIncludeTimefilter,
]);
const onInputChange = useCallback((event) => {
const onInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>((event) => {
setFormErrors([]);
setTitle(event.target.value);
}, []);

View file

@ -24,6 +24,7 @@ import {
EuiHorizontalRule,
EuiProgress,
PrettyDuration,
EuiSelectableProps,
} from '@elastic/eui';
import { EuiContextMenuClass } from '@elastic/eui/src/components/context_menu/context_menu';
import { i18n } from '@kbn/i18n';
@ -282,9 +283,17 @@ export const SavedQueryManagementList = ({
}
}, [onLoad, selectedSavedQuery, onClose]);
const handleSelect = useCallback((savedQueryToSelect) => {
setSelectedSavedQuery(savedQueryToSelect);
}, []);
const handleSelect = useCallback<NonNullable<EuiSelectableProps<SelectableProps>['onChange']>>(
(choices) => {
const choice = choices.find(({ checked }) => checked);
if (choice) {
setSelectedSavedQuery(
currentPageQueries.find((savedQuery) => savedQuery.id === choice.value)
);
}
},
[currentPageQueries]
);
const handleDelete = useCallback((savedQueryToDelete: SavedQuery) => {
setShowDeletionConfirmationModal(true);
@ -439,14 +448,7 @@ export const SavedQueryManagementList = ({
{noSavedQueriesDescriptionText}
</span>
}
onChange={(choices) => {
const choice = choices.find(({ checked }) => checked);
if (choice) {
handleSelect(
currentPageQueries.find((savedQuery) => savedQuery.id === choice.value)
);
}
}}
onChange={handleSelect}
renderOption={renderOption}
css={{
'.euiSelectableList__list': {

View file

@ -11,7 +11,7 @@ import { EuiForm, EuiAccordion, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import useUnmount from 'react-use/lib/useUnmount';
import { IAggConfig, AggGroupNames } from '@kbn/data-plugin/public';
import { IAggConfig, AggGroupNames, IAggType } from '@kbn/data-plugin/public';
import type { DataView } from '@kbn/data-views-plugin/public';
import type { Schema } from '@kbn/visualizations-plugin/public';
@ -124,7 +124,7 @@ function DefaultEditorAggParams({
!!error || isInvalidParamsTouched(agg.type, aggType, paramsState);
const onAggSelect = useCallback(
(value) => {
(value: IAggType) => {
if (agg.type !== value) {
onAggTypeChange(agg.id, value);
// reset touched and valid of params

View file

@ -104,14 +104,14 @@ function DefaultEditorAggSelect({
},
[setValue]
);
const onSearchChange = useCallback((searchValue) => setIsDirty(Boolean(searchValue)), []);
const onSearchChange = useCallback((searchValue: string) => setIsDirty(Boolean(searchValue)), []);
const setTouched = useCallback(
() => onChangeAggType({ type: AGG_TYPE_ACTION_KEYS.TOUCHED, payload: true }),
[onChangeAggType]
);
const setValidity = useCallback(
(valid) => onChangeAggType({ type: AGG_TYPE_ACTION_KEYS.VALID, payload: valid }),
(valid: boolean) => onChangeAggType({ type: AGG_TYPE_ACTION_KEYS.VALID, payload: valid }),
[onChangeAggType]
);

View file

@ -67,7 +67,7 @@ const defaultConfig = {
};
function FromToList({ showValidation, onBlur, ...rest }: FromToListProps) {
const renderInputRow = useCallback(
const renderInputRow = useCallback<InputListConfig['renderInputRow']>(
(item: FromToModel, index, onChangeValue) => (
<>
<EuiFlexItem>

View file

@ -63,7 +63,7 @@ const defaultConfig = {
};
function MaskList({ showValidation, onBlur, ...rest }: MaskListProps) {
const renderInputRow = useCallback(
const renderInputRow = useCallback<InputListConfig['renderInputRow']>(
({ mask }: MaskModel, index, onChangeValue) => (
<EuiFlexItem>
<EuiFieldText

View file

@ -120,7 +120,7 @@ function FieldParamEditor({
}
});
const onSearchChange = useCallback((searchValue) => setIsDirty(Boolean(searchValue)), []);
const onSearchChange = useCallback((searchValue: string) => setIsDirty(Boolean(searchValue)), []);
return (
<EuiFormRow

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import React, { useMemo, useCallback } from 'react';
import React, { useMemo, useCallback, ChangeEventHandler } from 'react';
import { EuiFormRow, EuiSelect } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@ -46,7 +46,10 @@ function MetricAggParamEditor({
[metricAggs, agg.type.name]
);
const options = useAvailableOptions(aggFilter, filteredMetrics, DEFAULT_OPTIONS);
const onChange = useCallback((ev) => setValue(ev.target.value), [setValue]);
const onChange = useCallback<ChangeEventHandler<HTMLSelectElement>>(
(e) => setValue(e.target.value),
[setValue]
);
return (
<EuiFormRow

View file

@ -39,7 +39,7 @@ function RowsOrColumnsControl({ editorStateParams, setStateParamValue }: AggCont
},
];
const onChange = useCallback(
(optionId) => setStateParamValue(PARAMS.NAME, optionId === PARAMS.ROWS),
(optionId: string) => setStateParamValue(PARAMS.NAME, optionId === PARAMS.ROWS),
[setStateParamValue]
);

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import React, { useEffect, useCallback } from 'react';
import React, { useEffect, useCallback, ChangeEventHandler } from 'react';
import { EuiFieldText, EuiFormRow } from '@elastic/eui';
import { AggParamEditorProps } from '../agg_param_props';
@ -26,7 +26,10 @@ function StringParamEditor({
setValidity(isValid);
}, [isValid, setValidity]);
const onChange = useCallback((ev) => setValue(ev.target.value), [setValue]);
const onChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
(e) => setValue(e.target.value),
[setValue]
);
return (
<EuiFormRow

View file

@ -9,7 +9,8 @@
import { useCallback } from 'react';
import type { SerializableRecord } from '@kbn/utility-types';
import { IAggConfig, AggParamType } from '@kbn/data-plugin/public';
import { IAggConfig, AggParamType, AggConfigSerialized } from '@kbn/data-plugin/public';
import { DefaultEditorCommonProps } from '../../agg_common_props';
type SetValue = (value?: IAggConfig) => void;
@ -18,9 +19,9 @@ function useSubAggParamsHandlers(
aggParam: AggParamType,
subAgg: IAggConfig,
setValue: SetValue
) {
const setAggParamValue = useCallback(
(aggId, paramName, val) => {
): Pick<DefaultEditorCommonProps, 'onAggTypeChange' | 'setAggParamValue'> {
const setAggParamValue = useCallback<DefaultEditorCommonProps['setAggParamValue']>(
(_, paramName, val) => {
const parsedParams = subAgg.serialize();
const params = {
...parsedParams,
@ -35,13 +36,13 @@ function useSubAggParamsHandlers(
[agg, aggParam, setValue, subAgg]
);
const onAggTypeChange = useCallback(
(aggId, aggType) => {
const onAggTypeChange = useCallback<DefaultEditorCommonProps['onAggTypeChange']>(
(_, aggType) => {
const parsedAgg = subAgg.serialize();
const parsedAggParams = parsedAgg.params as SerializableRecord;
// we should share between aggs only field and base params: json, label, time shift.
const params = {
const params: AggConfigSerialized = {
...parsedAgg,
params: {
field: parsedAggParams.field,
@ -49,6 +50,7 @@ function useSubAggParamsHandlers(
customLabel: parsedAggParams.customLabel,
timeShift: parsedAggParams.timeShift,
},
// @ts-ignore - Need to verify type
type: aggType,
};

View file

@ -39,8 +39,8 @@ function ColorRanges({
}, [colorsRange]);
const validateRange = useCallback(
({ from, to }, index) => {
if (!colorsRange[index]) {
({ from, to }: RangeValues, index: number) => {
if (from === undefined || to === undefined || !colorsRange[index]) {
return [false, false];
}

View file

@ -9,11 +9,9 @@
export { BasicOptions } from './basic_options';
export { SwitchOption } from './switch';
export { SelectOption } from './select';
export type { SetColorRangeValue } from './color_ranges';
export { ColorRanges } from './color_ranges';
export type { SetColorSchemaOptionsValue } from './color_schema';
export { ColorSchemaOptions } from './color_schema';
export { NumberInputOption } from './number_input';
export { ColorRanges, type SetColorRangeValue } from './color_ranges';
export { ColorSchemaOptions, type SetColorSchemaOptionsValue } from './color_schema';
export { NumberInputOption, type NumberInputOptionProps } from './number_input';
export { RangeOption } from './range';
export { RequiredNumberInputOption } from './required_number_input';
export { TextInputOption } from './text_input';

View file

@ -71,7 +71,7 @@ export const LegendSizeSettings = ({
}, [isVerticalLegend, legendSize, onLegendSizeChange]);
const onLegendSizeOptionChange = useCallback(
(option) => onLegendSizeChange(option === DEFAULT_LEGEND_SIZE ? undefined : option),
(size: LegendSize) => onLegendSizeChange(size === DEFAULT_LEGEND_SIZE ? undefined : size),
[onLegendSizeChange]
);

View file

@ -62,4 +62,4 @@ function NumberInputOption<ParamName extends string>({
);
}
export { NumberInputOption };
export { NumberInputOption, type NumberInputOptionProps };

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import React, { useCallback, useState } from 'react';
import React, { SetStateAction, useCallback, useState } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
@ -42,7 +42,7 @@ function DefaultEditorControls({
const { enableAutoApply } = vis.type.editorConfig;
const [autoApplyEnabled, setAutoApplyEnabled] = useState(false);
const toggleAutoApply = useCallback(
(nextAutoApplyEnabled) => setAutoApplyEnabled(nextAutoApplyEnabled),
(nextAutoApplyEnabled: SetStateAction<boolean>) => setAutoApplyEnabled(nextAutoApplyEnabled),
[]
);
const onClickDiscard = useCallback(() => dispatch(discardChanges(vis)), [dispatch, vis]);

View file

@ -27,6 +27,7 @@ export {
ColorRanges,
BasicOptions,
type SetColorRangeValue,
type NumberInputOptionProps,
type SetColorSchemaOptionsValue,
} from './components/options';
export type { RangeValues } from './components/controls/ranges';

View file

@ -69,7 +69,10 @@ const HeatmapOptions = (props: HeatmapOptionsProps) => {
}
}, [stateParams]);
const handleLegendSizeChange = useCallback((size) => setValue('legendSize', size), [setValue]);
const handleLegendSizeChange = useCallback(
(size?: LegendSize) => setValue('legendSize', size),
[setValue]
);
return (
<>

View file

@ -47,7 +47,10 @@ function LabelsPanel({ valueAxis, setValue, isNewLibrary }: LabelsPanelProps) {
[setValueAxisLabels]
);
const setColor = useCallback((value) => setValueAxisLabels('color', value), [setValueAxisLabels]);
const setColor = useCallback(
(value: string) => setValueAxisLabels('color', value),
[setValueAxisLabels]
);
return (
<EuiPanel paddingSize="s">

View file

@ -117,14 +117,17 @@ const PieOptions = (props: PieOptionsProps) => {
}, [props.palettes]);
const handleEmptySizeRatioChange = useCallback(
(sizeId) => {
(sizeId: string) => {
const emptySizeRatio = emptySizeRatioOptions.find(({ id }) => id === sizeId)?.value;
setValue('emptySizeRatio', emptySizeRatio);
},
[setValue]
);
const handleLegendSizeChange = useCallback((size) => setValue('legendSize', size), [setValue]);
const handleLegendSizeChange = useCallback(
(size?: LegendSize) => setValue('legendSize', size),
[setValue]
);
const handleLegendDisplayChange = useCallback(
(name: keyof PartitionVisParams, show: boolean) => {

View file

@ -74,7 +74,7 @@ export const AnnotationsEditor = (props: AnnotationsEditorProps) => {
);
const handleDelete = useCallback(
(annotation) => () =>
(annotation: Annotation) => () =>
collectionActions.handleDelete(getCollectionActionsProps(props), annotation),
[props]
);

View file

@ -19,12 +19,12 @@ interface InspectorDataGridProps extends VegaRuntimeData {
export const InspectorDataGrid = ({ columns, data, dataGridAriaLabel }: InspectorDataGridProps) => {
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: DEFAULT_PAGE_SIZE });
const onChangeItemsPerPage = useCallback(
(pageSize) => setPagination((p) => ({ ...p, pageSize, pageIndex: 0 })),
(pageSize: number) => setPagination((p) => ({ ...p, pageSize, pageIndex: 0 })),
[setPagination]
);
const onChangePage = useCallback(
(pageIndex) => setPagination((p) => ({ ...p, pageIndex })),
(pageIndex: number) => setPagination((p) => ({ ...p, pageIndex })),
[setPagination]
);

View file

@ -47,7 +47,7 @@ function ChartOptions({
);
const setValueAxis = useCallback(
(paramName, value) => {
(paramName: 'valueAxis', value: string) => {
changeValueAxis(index, paramName, value);
},
[changeValueAxis, index]

View file

@ -10,7 +10,7 @@ import React, { useEffect, useCallback } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { NumberInputOption } from '@kbn/vis-default-editor-plugin/public';
import { NumberInputOption, NumberInputOptionProps } from '@kbn/vis-default-editor-plugin/public';
import { Scale, ScaleType } from '../../../../types';
import { SetScale } from './value_axis_options';
@ -54,7 +54,7 @@ function YExtents({ scale, setScale, setMultipleValidity }: YExtentsProps) {
const isValid = !errors.length;
const setExtents = useCallback(
const setExtents = useCallback<NumberInputOptionProps<'min' | 'max'>['setValue']>(
(paramName, value) => {
setScale(paramName, value === '' ? null : value);
},

View file

@ -46,7 +46,10 @@ export function PointSeriesOptions(props: ValidationVisOptionsProps<VisParams>)
const [hadAutoLegendSize] = useState(() => legendSize === LegendSize.AUTO);
const handleLegendSizeChange = useCallback((size) => setValue('legendSize', size), [setValue]);
const handleLegendSizeChange = useCallback(
(size?: LegendSize) => setValue('legendSize', size),
[setValue]
);
return (
<>

View file

@ -16,7 +16,7 @@ interface CounterParams {
}
export class SelfChangingEditor extends React.Component<VisEditorOptionsProps<CounterParams>> {
onCounterChange = (ev: any) => {
onCounterChange = (ev: React.ChangeEvent<HTMLInputElement>) => {
this.props.setValue('counter', parseInt(ev.target.value, 10));
};

View file

@ -470,7 +470,7 @@ export const App = (props: {
const currentSO = useRef<string>(initialAttributes);
const [currentValid, saveValidSO] = useState(initialAttributes);
const switchChartPreset = useCallback(
(newIndex) => {
(newIndex: number) => {
const newChart = charts[newIndex];
const newAttributes = JSON.stringify(newChart.attributes, null, 2);
currentSO.current = newAttributes;
@ -694,7 +694,7 @@ export const App = (props: {
<EuiSelect
options={charts.map(({ id }, i) => ({ value: i, text: id }))}
value={undefined}
onChange={(e) => switchChartPreset(Number(e.target.value))}
onChange={(e) => switchChartPreset(+e.target.value)}
aria-label="Load from a preset"
prepend={'Load preset'}
/>

View file

@ -6,7 +6,7 @@
*/
import React, { useCallback, useMemo, useState } from 'react';
import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
import { EuiComboBox, EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui';
import * as i18n from './translations';
@ -49,7 +49,9 @@ export const ModelSelector: React.FC<Props> = React.memo(
);
// Callback for when user types to create a new model
const onCreateOption = useCallback(
const onCreateOption = useCallback<
NonNullable<EuiComboBoxProps<string | number | string[] | undefined>['onCreateOption']>
>(
(searchValue, flattenedOptions = []) => {
if (!searchValue || !searchValue.trim().toLowerCase()) {
return;
@ -58,8 +60,7 @@ export const ModelSelector: React.FC<Props> = React.memo(
const normalizedSearchValue = searchValue.trim().toLowerCase();
const optionExists =
flattenedOptions.findIndex(
(option: EuiComboBoxOptionOption) =>
option.label.trim().toLowerCase() === normalizedSearchValue
(option) => option.label.trim().toLowerCase() === normalizedSearchValue
) !== -1;
const newOption = {

View file

@ -51,7 +51,7 @@ export const InferenceFlyout: React.FC<GenericInferenceFlyoutProps> = ({
}, [inferenceEndpointError]);
const onChangingInferenceEndpoint = useCallback(
(value) => {
(value: any) => {
setInferenceEndpointId(value);
onInferenceEndpointChange(value);
},

View file

@ -104,7 +104,7 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
groupFilter !== undefined
);
const onChange = useCallback((tableSettings) => {
const onChange = useCallback((tableSettings: any) => {
if (tableSettings.page) {
const { index, size } = tableSettings.page;
setPageIndex(index);

View file

@ -247,7 +247,7 @@ export const LogRateAnalysisResultsGroupsTable: FC<LogRateAnalysisResultsTablePr
groupColumns.push(...columns);
const onChange = useCallback((tableSettings) => {
const onChange = useCallback((tableSettings: any) => {
if (tableSettings.page) {
const { index, size } = tableSettings.page;
setPageIndex(index);

View file

@ -9,6 +9,7 @@ import moment from 'moment';
import {
FIELD_TYPES,
Form,
FormSubmitHandler,
getUseField,
useForm,
useFormData,
@ -136,7 +137,7 @@ export const CreateMaintenanceWindowForm = React.memo<CreateMaintenanceWindowFor
};
}, [isScopedQueryEnabled, scopedQueryFeatureFlag, query, filters]);
const submitMaintenanceWindow = useCallback(
const submitMaintenanceWindow = useCallback<FormSubmitHandler<FormProps>>(
async (formData, isValid) => {
if (!isValid || scopedQueryErrors.length !== 0) {
return;

View file

@ -29,7 +29,7 @@ import {
MaintenanceWindow,
} from '../../../../common';
import { StatusFilter } from './status_filter';
import { TableActionsPopover } from './table_actions_popover';
import { TableActionsPopover, TableActionsPopoverProps } from './table_actions_popover';
import { useFinishMaintenanceWindow } from '../../../hooks/use_finish_maintenance_window';
import { useArchiveMaintenanceWindow } from '../../../hooks/use_archive_maintenance_window';
import { useFinishAndArchiveMaintenanceWindow } from '../../../hooks/use_finish_and_archive_maintenance_window';
@ -115,13 +115,13 @@ export const MaintenanceWindowsList = React.memo<MaintenanceWindowsListProps>(
};
const { euiTheme } = useEuiTheme();
const { navigateToEditMaintenanceWindows } = useEditMaintenanceWindowsNavigation();
const onEdit = useCallback(
const onEdit = useCallback<TableActionsPopoverProps['onEdit']>(
(id) => navigateToEditMaintenanceWindows(id),
[navigateToEditMaintenanceWindows]
);
const { mutate: finishMaintenanceWindow, isLoading: isLoadingFinish } =
useFinishMaintenanceWindow();
const onCancel = useCallback(
const onCancel = useCallback<TableActionsPopoverProps['onCancel']>(
(id) => finishMaintenanceWindow(id, { onSuccess: () => refreshData() }),
[finishMaintenanceWindow, refreshData]
);

View file

@ -18,7 +18,7 @@ import {
import * as i18n from '../translations';
import { MaintenanceWindowStatus } from '../../../../common';
interface TableActionsPopoverProps {
export interface TableActionsPopoverProps {
id: string;
status: MaintenanceWindowStatus;
onEdit: (id: string) => void;

View file

@ -6,7 +6,7 @@
*/
import React, { useState, useEffect, useCallback } from 'react';
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSelect } from '@elastic/eui';
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSelect, EuiSelectProps } from '@elastic/eui';
import { DatatableColumn, ExpressionAstExpression } from '@kbn/expressions-plugin/common';
import { templateFromReactComponent } from '../../../public/lib/template_from_react_component';
import { ArgumentStrings } from '../../../i18n';
@ -15,7 +15,7 @@ import { ResolvedArgProps, ResolvedColumns } from '../../../public/expression_ty
const { VisDimension: strings } = ArgumentStrings;
type VisDimensionArgInputProps = {
onValueChange: (value: ExpressionAstExpression) => void;
onValueChange: (value: ExpressionAstExpression | string) => void;
argValue: ExpressionAstExpression;
typeInstance: {
options?: {
@ -30,14 +30,14 @@ const VisDimensionArgInput: React.FC<VisDimensionArgInputProps> = ({
onValueChange,
resolved: { columns },
}) => {
const [value, setValue] = useState(argValue);
const [value, setValue] = useState<ExpressionAstExpression | string>(argValue);
const confirm = typeInstance?.options?.confirm;
useEffect(() => {
setValue(argValue);
}, [argValue]);
const onChange = useCallback(
const onChange = useCallback<NonNullable<EuiSelectProps['onChange']>>(
(ev) => {
const onChangeFn = confirm ? setValue : onValueChange;
const astObj: ExpressionAstExpression = {

View file

@ -59,14 +59,18 @@ const ArgTemplateFormComponent: React.FunctionComponent<ArgTemplateFormProps> =
mountedArgumentRef.current = undefined;
});
const onMount = useCallback((ref) => {
const onMount = useCallback(
(ref: UpdatePropsRef<ArgTemplateFormProps['argumentProps']> | null) => {
if (!mountedArgumentRef.current && ref) {
mountedArgumentRef.current = ref;
}
}, []);
},
[]
);
const renderTemplate = useCallback(
(domNode) => template && template(domNode, argumentProps, updatedHandlers, onMount),
(domNode: HTMLElement) =>
template && template(domNode, argumentProps, updatedHandlers, onMount),
[argumentProps, onMount, template, updatedHandlers]
);

View file

@ -48,7 +48,7 @@ export const VarValueField: FC<Props> = ({ type, value, onChange }) => {
];
const onNumberChange = useCallback(
(e) => {
(e: React.ChangeEvent<HTMLInputElement>) => {
const floatVal = parseFloat(e.target.value);
const varValue = isNaN(floatVal) ? '' : floatVal;
onChange(varValue);

View file

@ -74,7 +74,7 @@ export const Workpad: FC<ContainerProps> = (props) => {
);
const getAnimation = useCallback(
(pageNumber) => {
(pageNumber: number) => {
if (!transition || !transition.name) {
return null;
}
@ -94,7 +94,7 @@ export const Workpad: FC<ContainerProps> = (props) => {
const onTransitionEnd = useCallback(() => setTransition(null), [setTransition]);
const setFullscreenWithEffect = useCallback(
(fullscreen) => {
(fullscreen: boolean) => {
setFullscreen(fullscreen);
if (fullscreen === true) {
trackCanvasUiMetric(

View file

@ -21,8 +21,11 @@ const strings = {
export const WorkpadColorPicker = (props: Props) => {
const dispatch = useDispatch();
const onAddColor = useCallback((payload) => dispatch(addColor(payload)), [dispatch]);
const onRemoveColor = useCallback((payload) => dispatch(removeColor(payload)), [dispatch]);
const onAddColor = useCallback((payload: string) => dispatch(addColor(payload)), [dispatch]);
const onRemoveColor = useCallback(
(payload: string) => dispatch(removeColor(payload)),
[dispatch]
);
const colors = useSelector(getWorkpadColors);
return (

View file

@ -61,12 +61,12 @@ const DatasourceWrapperComponent: React.FunctionComponent<DatasourceWrapperProps
const { spec, datasourceProps, handlers } = props;
const prevSpec = usePrevious(spec);
const onMount = useCallback((ref) => {
const onMount = useCallback((ref: UpdatePropsRef<DatasourceRenderProps> | null) => {
datasourceRef.current = ref ?? undefined;
}, []);
const callRenderFn = useCallback(
(domNode) => {
(domNode: HTMLDivElement) => {
const { template } = spec;
if (!template) {
return null;

View file

@ -198,7 +198,7 @@ const EditAssigneesSelectableComponent: React.FC<Props> = ({
);
const onSearchChange = useCallback(
(value) => {
(value: string) => {
setSearchValue(value);
onContentChange(value);
},

View file

@ -120,10 +120,6 @@ const EditTagsSelectableComponent: React.FC<Props> = ({
[options, searchValue, state.items]
);
const onSearchChange = useCallback((value) => {
setSearchValue(value);
}, []);
return (
<EuiSelectable
options={optionsWithAddNewTagOption}
@ -132,7 +128,7 @@ const EditTagsSelectableComponent: React.FC<Props> = ({
placeholder: i18n.SEARCH_PLACEHOLDER,
isLoading,
isClearable: !isLoading,
onChange: onSearchChange,
onChange: setSearchValue,
value: searchValue,
'data-test-subj': 'cases-actions-tags-edit-selectable-search-input',
}}

View file

@ -26,7 +26,7 @@ import {
import { AttachmentType } from '../../../common/types/domain';
import { useCreateAttachments } from '../../containers/use_create_attachments';
import type { CaseUI } from '../../containers/types';
import type { EuiMarkdownEditorRef } from '../markdown_editor';
import type { MarkdownEditorRef } from '../markdown_editor';
import { MarkdownEditorForm } from '../markdown_editor';
import { getMarkdownEditorStorageKey } from '../markdown_editor/utils';
import { removeItemFromSessionStorage } from '../utils';
@ -45,7 +45,7 @@ const initialCommentValue: AddCommentFormSchema = {
export interface AddCommentRefObject {
addQuote: (quote: string) => void;
setComment: (newComment: string) => void;
editor: EuiMarkdownEditorRef | null;
editor: MarkdownEditorRef | null;
}
/* eslint-disable react/no-unused-prop-types */
@ -65,7 +65,7 @@ export const AddComment = React.memo(
{ id, caseId, onCommentPosted, onCommentSaving, showLoading = true, statusActionButton },
ref
) => {
const editorRef = useRef<EuiMarkdownEditorRef>(null);
const editorRef = useRef<MarkdownEditorRef>(null);
const [focusOnContext, setFocusOnContext] = useState(false);
const { permissions, owner } = useCasesContext();
const { isLoading, mutate: createAttachments } = useCreateAttachments();
@ -85,7 +85,7 @@ export const AddComment = React.memo(
const { setFieldValue, reset, submit } = form;
const [{ comment }] = useFormData<{ comment: string }>({ form, watch: [fieldName] });
const addQuote = useCallback(
const addQuote = useCallback<AddCommentRefObject['addQuote']>(
(quote) => {
const addCarrots = quote.replace(new RegExp('\r?\n', 'g'), '\n> ');
const val = `> ${addCarrots} \n\n`;
@ -95,7 +95,7 @@ export const AddComment = React.memo(
[comment, setFieldValue]
);
const setComment = useCallback(
const setComment = useCallback<AddCommentRefObject['setComment']>(
(newComment) => {
setFieldValue(fieldName, newComment);
},

View file

@ -27,7 +27,7 @@ export const NavButtons: FunctionComponent<Props> = ({ actionsErrors }) => {
const { getCreateCaseUrl, navigateToCreateCase } = useCreateCaseNavigation();
const { euiTheme } = useEuiTheme();
const navigateToCreateCaseClick = useCallback(
(e) => {
(e: React.SyntheticEvent) => {
e.preventDefault();
navigateToCreateCase();
},

View file

@ -22,7 +22,7 @@ const TableSearchComponent: React.FC<TableSearchComponentProps> = ({
const [search, setSearch] = useState(filterOptionsSearch);
const onSearch = useCallback(
(newSearch) => {
(newSearch: string) => {
const trimSearch = newSearch.trim();
setSearch(trimSearch);
onFilterOptionsChange({ search: trimSearch });

View file

@ -59,7 +59,7 @@ export const CasesTable: FunctionComponent<CasesTableProps> = ({
const { getCreateCaseUrl, navigateToCreateCase } = useCreateCaseNavigation();
const { euiTheme } = useEuiTheme();
const navigateToCreateCaseClick = useCallback(
(ev) => {
(ev: React.SyntheticEvent) => {
ev.preventDefault();
if (goToCreateCase != null) {
goToCreateCase();

View file

@ -28,6 +28,7 @@ import { NoPrivilegesPage } from '../no_privileges';
import * as i18n from './translations';
import { useReadonlyHeader } from './use_readonly_header';
import type { CaseViewProps } from '../case_view/types';
import type { CreateCaseFormProps } from '../create/form';
const CaseViewLazy: React.FC<CaseViewProps> = lazy(() => import('../case_view'));
@ -45,7 +46,7 @@ const CasesRoutesComponent: React.FC<CasesRoutesProps> = ({
const { navigateToCaseView } = useCaseViewNavigation();
useReadonlyHeader();
const onCreateCaseSuccess = useCallback(
const onCreateCaseSuccess: CreateCaseFormProps['onSuccess'] = useCallback(
async ({ id }) => navigateToCaseView({ detailName: id }),
[navigateToCaseView]
);

View file

@ -73,7 +73,7 @@ export const CaseViewPage = React.memo<CaseViewPageProps>(
}, [isLoading, refreshRef, refreshCaseViewPage]);
const onSubmitTitle = useCallback(
(newTitle) =>
(newTitle: string) =>
onUpdateField({
key: 'title',
value: newTitle,

View file

@ -25,6 +25,7 @@ import { useGetSupportedActionConnectors } from '../../../containers/configure/u
import type { CaseSeverity, CaseStatuses } from '../../../../common/types/domain';
import type { CaseUICustomField, UseFetchAlertData } from '../../../../common/ui/types';
import type { CaseUI } from '../../../../common';
import type { EditConnectorProps } from '../../edit_connector';
import { EditConnector } from '../../edit_connector';
import type { CasesNavigation } from '../../links';
import { StatusActionButton } from '../../status/button';
@ -115,12 +116,12 @@ export const CaseViewActivity = ({
);
const onSubmitTags = useCallback(
(newTags) => onUpdateField({ key: 'tags', value: newTags }),
(newTags: string[]) => onUpdateField({ key: 'tags', value: newTags }),
[onUpdateField]
);
const onSubmitCategory = useCallback(
(newCategory) => onUpdateField({ key: 'category', value: newCategory }),
(newCategory: string | null) => onUpdateField({ key: 'category', value: newCategory }),
[onUpdateField]
);
@ -142,7 +143,7 @@ export const CaseViewActivity = ({
const { isLoading: isLoadingAllAvailableConnectors, data: supportedActionConnectors } =
useGetSupportedActionConnectors();
const onSubmitConnector = useCallback(
const onSubmitConnector = useCallback<EditConnectorProps['onSubmit']>(
(connector) => {
onUpdateField({
key: 'connector',

View file

@ -57,7 +57,7 @@ export const CaseViewFiles = ({ caseData }: CaseViewFilesProps) => {
);
const onSearchChange = useCallback(
(newSearch) => {
(newSearch: string) => {
const trimSearch = newSearch.trim();
if (!isEqual(trimSearch, filteringOptions.searchTerm)) {
setFilteringOptions({

View file

@ -33,7 +33,7 @@ const CustomFieldsComponent: React.FC<Props> = ({
);
const onSubmitCustomField = useCallback(
(customFieldToAdd) => {
(customFieldToAdd: CaseUICustomField) => {
onSubmit(customFieldToAdd);
},
[onSubmit]

View file

@ -28,7 +28,7 @@ import { RemovableItem } from '../../removable_item/removable_item';
export interface EditCategoryProps {
isLoading: boolean;
onSubmit: (category?: string | null) => void;
onSubmit: (category: string | null) => void;
category?: string | null;
}

View file

@ -21,7 +21,7 @@ import { getMarkdownEditorStorageKey } from '../markdown_editor/utils';
import * as i18n from '../user_actions/translations';
import { useCasesContext } from '../cases_context/use_cases_context';
import { useLensDraftComment } from '../markdown_editor/plugins/lens/use_lens_draft_comment';
import type { EditableMarkdownRefObject, EuiMarkdownEditorRef } from '../markdown_editor';
import type { EditableMarkdownRefObject, MarkdownEditorRef } from '../markdown_editor';
import { EditableMarkdown, ScrollableMarkdown } from '../markdown_editor';
import type { CaseUI } from '../../containers/types';
import type { OnUpdateFields } from '../case_view/types';
@ -30,7 +30,7 @@ import { schema } from './schema';
const DESCRIPTION_ID = 'description';
export interface DescriptionMarkdownRefObject extends EditableMarkdownRefObject {
editor: EuiMarkdownEditorRef | null;
editor: MarkdownEditorRef | null;
}
export interface DescriptionProps {
caseData: CaseUI;

View file

@ -31,6 +31,7 @@ import { useCasesContext } from '../cases_context/use_cases_context';
import * as i18n from './translations';
import { useRefreshCaseViewPage } from '../case_view/use_on_refresh_case_view_page';
import { deleteFileAttachments } from '../../containers/api';
import type { ServerError } from '../../types';
interface AddFileProps {
caseId: string;
@ -47,7 +48,7 @@ const AddFileComponent: React.FC<AddFileProps> = ({ caseId }) => {
const showModal = () => setIsModalVisible(true);
const onError = useCallback(
(error) => {
(error: Error | ServerError) => {
showErrorToast(error, {
title: i18n.FAILED_UPLOAD,
});

View file

@ -62,7 +62,7 @@ export const FilterPopoverComponent = ({
const setIsPopoverOpenCb = useCallback(() => setIsPopoverOpen(!isPopoverOpen), [isPopoverOpen]);
const toggleSelectedGroupCb = useCallback(
(option) => onSelectedOptionsChanged(toggleSelectedGroup(option, selectedOptions)),
(option: string) => onSelectedOptionsChanged(toggleSelectedGroup(option, selectedOptions)),
[selectedOptions, onSelectedOptionsChanged]
);

View file

@ -56,7 +56,7 @@ const HeaderPageComponent: React.FC<HeaderPageProps> = ({
const xsFontSize = useEuiFontSize('xs').fontSize;
const navigateToAllCasesClick = useCallback(
(e) => {
(e: React.SyntheticEvent) => {
if (e) {
e.preventDefault();
}

View file

@ -44,7 +44,7 @@ const CaseDetailsLinkComponent: React.FC<CaseDetailsLinkProps> = ({
}) => {
const { getCaseViewUrl, navigateToCaseView } = useCaseViewNavigation();
const navigateToCaseViewClick = useCallback(
(ev) => {
(ev: React.SyntheticEvent) => {
ev.preventDefault();
navigateToCaseView({ detailName });
},
@ -83,7 +83,7 @@ const ConfigureCaseButtonComponent: React.FC<ConfigureCaseButtonProps> = ({
const { getConfigureCasesUrl, navigateToConfigureCases } = useConfigureCasesNavigation();
const navigateToConfigureCasesClick = useCallback(
(e) => {
(e: React.SyntheticEvent) => {
e.preventDefault();
navigateToConfigureCases();
},

View file

@ -50,7 +50,7 @@ const EditableMarkDownRenderer = forwardRef<
const { submit, setFieldValue, isValid: isFormValid } = form;
const setComment = useCallback(
(newComment) => {
(newComment: string) => {
setFieldValue(fieldName, newComment);
},
[setFieldValue, fieldName]

View file

@ -11,6 +11,7 @@ import { first } from 'rxjs';
import { useKibana } from '../../../../common/lib/kibana';
import { DRAFT_COMMENT_STORAGE_ID } from './constants';
import { VISUALIZATION } from './translations';
import type { MarkdownEditorRef } from '../../editor';
interface DraftComment {
commentId: string;
@ -51,9 +52,11 @@ export const useLensDraftComment = () => {
fetchDraftComment();
}, [currentAppId$, embeddable, storage]);
const openLensModal = useCallback(({ editorRef }) => {
const openLensModal = useCallback(({ editorRef }: { editorRef: MarkdownEditorRef }) => {
if (editorRef && editorRef.textarea && editorRef.toolbar) {
const lensPluginButton = editorRef.toolbar?.querySelector(`[aria-label="${VISUALIZATION}"]`);
const lensPluginButton = editorRef.toolbar?.querySelector<HTMLButtonElement>(
`[aria-label="${VISUALIZATION}"]`
);
if (lensPluginButton) {
lensPluginButton.click();
}

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import type { EuiSelectOption } from '@elastic/eui';
import type { EuiSelectOption, EuiSelectProps } from '@elastic/eui';
import { EuiSelect } from '@elastic/eui';
import React, { useCallback } from 'react';
@ -50,7 +50,7 @@ export const RecentCasesFilters = React.memo<{
};
});
const onChange = useCallback(
const onChange = useCallback<NonNullable<EuiSelectProps['onChange']>>(
(e) => {
setFilterBy(e.target.value as FilterMode);
},

View file

@ -48,7 +48,7 @@ const RecentCasesComponent = React.memo(({ maxCasesToShow }: RecentCasesProps) =
useState<RecentCasesFilterMode>('recentlyCreated');
const navigateToAllCasesClick = useCallback(
(e) => {
(e: React.SyntheticEvent) => {
e.preventDefault();
navigateToAllCases();
},

View file

@ -23,7 +23,7 @@ const NoCasesComponent = ({ recentCasesFilterBy }: NoCasesComp) => {
const { getCreateCaseUrl, navigateToCreateCase } = useCreateCaseNavigation();
const navigateToCreateCaseClick = useCallback(
(e) => {
(e: React.SyntheticEvent) => {
e.preventDefault();
navigateToCreateCase();
},

View file

@ -24,7 +24,7 @@ export const useCreateCaseModal = ({ onCaseCreated }: UseCreateCaseModalProps) =
const closeModal = useCallback(() => setIsModalOpen(false), []);
const openModal = useCallback(() => setIsModalOpen(true), []);
const onSuccess = useCallback(
async (theCase) => {
async (theCase: CaseUI) => {
onCaseCreated(theCase);
closeModal();
},

View file

@ -36,7 +36,7 @@ const CallOutComponent = ({
const { permissions } = useCasesContext();
const handleCallOut = useCallback(
(e) => handleButtonClick(e, id, type),
(e: React.MouseEvent) => handleButtonClick(e, id, type),
[handleButtonClick, id, type]
);

View file

@ -36,7 +36,7 @@ const CaseCallOutComponent = ({
}: CaseCallOutProps) => {
const { navigateToConfigureCases } = useConfigureCasesNavigation();
const handleCallOut = useCallback(
(e) => {
(e: React.SyntheticEvent) => {
e.preventDefault();
// if theres connectors open dropdown editor
// if no connectors, redirect to create case page

View file

@ -29,7 +29,7 @@ interface MultipleAlertsProps extends SingleAlertProps {
const RuleLink: React.FC<SingleAlertProps> = memo(
({ onRuleDetailsClick, getRuleDetailsHref, ruleId, ruleName, loadingAlertData, actionId }) => {
const onLinkClick = useCallback(
(ev) => {
(ev: React.MouseEvent) => {
ev.preventDefault();
if (onRuleDetailsClick) onRuleDetailsClick(ruleId, ev);
},

View file

@ -31,7 +31,7 @@ const HostIsolationCommentEventComponent: React.FC<Props> = ({
const endpointDetailsHref = href ? href(endpoints[0].endpointId) : '';
const onLinkClick = useCallback(
(ev) => {
(ev: React.MouseEvent) => {
ev.preventDefault();
if (onClick) onClick(endpoints[0].endpointId, ev);
},

View file

@ -139,7 +139,7 @@ export const ControlGeneralViewResponse = ({
}, [closePopover, onDuplicate, response]);
const onChangeMatches = useCallback(
(options) => {
(options: any) => {
response.match = options.map((option: EuiComboBoxOptionOption) => option.value);
onResponseChange(response, index);
@ -148,7 +148,7 @@ export const ControlGeneralViewResponse = ({
);
const onChangeExcludes = useCallback(
(options) => {
(options: any) => {
response.exclude = options.map((option: EuiComboBoxOptionOption) => option.value);
if (response.exclude?.length === 0) {

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