[Exp view] Fix apply button equality check (#115744)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Shahzad 2021-10-29 19:49:30 +02:00 committed by GitHub
parent 40fd867b65
commit 9714aac93c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 111 additions and 17 deletions

View file

@ -54,13 +54,6 @@ describe('OperationTypeSelect', function () {
fireEvent.click(screen.getByTestId('operationTypeSelect'));
expect(setSeries).toHaveBeenCalledWith(0, {
operationType: 'median',
dataType: 'ux',
time: { from: 'now-15m', to: 'now' },
name: 'performance-distribution',
});
fireEvent.click(screen.getByText('95th Percentile'));
expect(setSeries).toHaveBeenCalledWith(0, {
operationType: '95th',

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import React, { useEffect } from 'react';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSuperSelect } from '@elastic/eui';
@ -30,12 +30,6 @@ export function OperationTypeSelect({
setSeries(seriesId, { ...series, operationType: value });
};
useEffect(() => {
setSeries(seriesId, { ...series, operationType: operationType || defaultOperationType });
// We only want to call this when defaultOperationType changes
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [defaultOperationType]);
return (
<OperationTypeComponent
onChange={onChange}

View file

@ -0,0 +1,88 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { screen, waitFor, fireEvent } from '@testing-library/dom';
import { render } from '../rtl_helpers';
import * as hooks from '../hooks/use_series_storage';
import { ViewActions } from './view_actions';
import { AllSeries } from '../hooks/use_series_storage';
describe('ViewActions', () => {
const applyChanges = jest.fn();
const mockSeriesStorage = (allSeries: AllSeries, urlAllSeries: AllSeries) => {
jest.clearAllMocks();
jest.spyOn(hooks, 'useSeriesStorage').mockReturnValue({
...jest.requireActual('../hooks/use_series_storage'),
allSeries,
applyChanges,
storage: { get: jest.fn().mockReturnValue(urlAllSeries) } as any,
});
};
const assertApplyIsEnabled = async () => {
render(<ViewActions />);
const applyBtn = screen.getByText(/Apply changes/i);
const btnComponent = screen.getByTestId('seriesChangesApplyButton');
expect(btnComponent.classList).not.toContain('euiButton-isDisabled');
fireEvent.click(applyBtn);
await waitFor(() => {
expect(applyChanges).toBeCalledTimes(1);
});
};
it('renders ViewActions', async () => {
mockSeriesStorage([], []);
render(<ViewActions />);
expect(screen.getByText(/Apply changes/i)).toBeInTheDocument();
});
it('apply button is disabled when no changes', async () => {
mockSeriesStorage([], []);
render(<ViewActions />);
const applyBtn = screen.getByText(/Apply changes/i);
const btnComponent = screen.getByTestId('seriesChangesApplyButton');
expect(btnComponent.classList).toContain('euiButton-isDisabled');
fireEvent.click(applyBtn);
await waitFor(() => {
expect(applyChanges).toBeCalledTimes(0);
});
});
it('should call apply changes when series length is different', async function () {
mockSeriesStorage([], [{ name: 'testSeries' } as any]);
await assertApplyIsEnabled();
});
it('should call apply changes when series content is different', async function () {
mockSeriesStorage([{ name: 'testSeriesChange' } as any], [{ name: 'testSeries' } as any]);
await assertApplyIsEnabled();
});
it('should call apply changes when series content is different as in undefined', async function () {
mockSeriesStorage(
[{ name: undefined } as any],
[{ name: 'testSeries', operationType: undefined } as any]
);
await assertApplyIsEnabled();
});
});

View file

@ -8,22 +8,41 @@
import React from 'react';
import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { isEqual } from 'lodash';
import { isEqual, pickBy } from 'lodash';
import { allSeriesKey, convertAllShortSeries, useSeriesStorage } from '../hooks/use_series_storage';
interface Props {
onApply?: () => void;
}
export function removeUndefinedProps<T extends object>(obj: T): Partial<T> {
return pickBy(obj, (value) => value !== undefined);
}
export function ViewActions({ onApply }: Props) {
const { allSeries, storage, applyChanges } = useSeriesStorage();
const noChanges = isEqual(allSeries, convertAllShortSeries(storage.get(allSeriesKey) ?? []));
const urlAllSeries = convertAllShortSeries(storage.get(allSeriesKey) ?? []);
let noChanges = allSeries.length === urlAllSeries.length;
if (noChanges) {
noChanges = !allSeries.some(
(series, index) =>
!isEqual(removeUndefinedProps(series), removeUndefinedProps(urlAllSeries[index]))
);
}
return (
<EuiFlexGroup justifyContent="flexEnd" alignItems="center">
<EuiFlexItem grow={false}>
<EuiButton onClick={() => applyChanges(onApply)} isDisabled={noChanges} fill size="s">
<EuiButton
onClick={() => applyChanges(onApply)}
isDisabled={noChanges}
fill
size="s"
data-test-subj={'seriesChangesApplyButton'}
>
{i18n.translate('xpack.observability.expView.seriesBuilder.apply', {
defaultMessage: 'Apply changes',
})}