mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
[Security Solution][Timeline] Refactor from styled-components to emotion (#222438)
## Summary This PR was originally addressing some dark-mode issues in the timeline. Those issues has been already fixed upstream but there are still valuable contributions in this PR that should be considered anyways: 1. unit test has been refactor to use `react-testing-library` instead of `enzyme` 2. the styling for the timeline has been moved from `styled-components` to `emotion` 3. the color tokens have been updated according to #199715 > [!important] > > #199715 also suggests to move away from the `success` tokens. However, in the drag-and-drop use-case the EUI team has confirmed that for now we should prefer the `success` tokens until proper drag-and-drop tokens will be produced ## Screenshots > [!important] > > Light mode was not visually impacted by these changes, therefore no screenshots have been provided ### Empty query builder - The background of the query builder matches the general background now - The dashed border is a little bit lighter than before **Before** <img width="1205" alt="dark-1-before" src="https://github.com/user-attachments/assets/2008ddd3-f801-4646-8407-045de4dc3ebd" /> **After** <img width="1206" alt="dark-1-after" src="https://github.com/user-attachments/assets/a93e4b7e-6666-4805-91d1-ab9b4c3f5b82" /> ### Drag-and-drop query builder - The border color is a bit washed up compared to the original one - The background green is darker and less teal **Before** <img width="1203" alt="dark-2-before" src="https://github.com/user-attachments/assets/b3d85b9e-3821-44c5-adaa-99719ca3aef6" /> **After** <img width="1074" alt="Screenshot 2025-06-04 at 18 45 16" src="https://github.com/user-attachments/assets/41b4cbca-4654-4571-a59c-4976ca0930a5" /> ## Code overview - `[...]/timelines/components/timeline/data_providers/index.tsx` - Replace `styled-components` with `emotion` - `styled-components` have an issue where the theme is always set to `LIGHT` in this component - after a bit of debugging the issue seems to come from eui, but the investigation was interrupted because - `styled-components` are deprecated anyways - `[...]/timelines/components/timeline/data_providers/index.test.tsx` - Refactor unit test from using `enzyme` to `react-testing-library` ## Credits Huge thanks to @kapral18 for working on this with me. ### Checklist <details> <summary>Expand</summary> Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The `release_note:breaking` label should be applied in these situations. - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) ### Identify risks Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss. Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging. - [ ] [See some risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) - [ ] ... </details> --------- Co-authored-by: Karen Grigoryan <karen.grigoryan@elastic.co>
This commit is contained in:
parent
d195260b95
commit
4b7f8d9399
3 changed files with 43 additions and 51 deletions
|
@ -431,7 +431,6 @@ module.exports = {
|
|||
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]cell_rendering[\/\\]default_cell_renderer.tsx/,
|
||||
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]data_providers[\/\\]add_data_provider_popover.tsx/,
|
||||
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]data_providers[\/\\]empty.tsx/,
|
||||
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]data_providers[\/\\]index.tsx/,
|
||||
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]data_providers[\/\\]provider_badge.tsx/,
|
||||
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]data_providers[\/\\]provider_item_actions.tsx/,
|
||||
/x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]timelines[\/\\]components[\/\\]timeline[\/\\]data_providers[\/\\]providers.tsx/,
|
||||
|
|
|
@ -6,91 +6,85 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
// Necessary until components being tested are migrated of styled-components https://github.com/elastic/kibana/issues/219037
|
||||
import 'jest-styled-components';
|
||||
import { screen, render, waitFor } from '@testing-library/react';
|
||||
|
||||
import { TestProviders } from '../../../../common/mock/test_providers';
|
||||
import { useMountAppended } from '../../../../common/utils/use_mount_appended';
|
||||
|
||||
import { DataProviders } from '.';
|
||||
import { TimelineId } from '../../../../../common/types/timeline';
|
||||
|
||||
describe('DataProviders', () => {
|
||||
const mount = useMountAppended();
|
||||
|
||||
describe('rendering', () => {
|
||||
const dropMessage = ['Drop', 'query', 'build', 'here'];
|
||||
|
||||
test('renders correctly against snapshot', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<DataProviders data-test-subj="dataProviders-container" timelineId="foo" />
|
||||
</TestProviders>
|
||||
);
|
||||
expect(wrapper.find(`[data-test-subj="dataProviders-container"]`)).toBeTruthy();
|
||||
expect(wrapper.find(`[date-test-subj="drop-target-data-providers"]`)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('it should render a placeholder when there are zero data providers', () => {
|
||||
const wrapper = mount(
|
||||
test('renders correctly against snapshot', async () => {
|
||||
const { container } = render(
|
||||
<TestProviders>
|
||||
<DataProviders timelineId="foo" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
dropMessage.forEach((word) => expect(wrapper.text()).toContain(word));
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
container.querySelector('.drop-target-data-providers-container')
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByTestId('dataProviders')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test('it renders the data providers', () => {
|
||||
const wrapper = mount(
|
||||
test('it should render a placeholder when there are zero data providers', async () => {
|
||||
const dropMessage = ['Drop', 'query', 'build', 'here'];
|
||||
|
||||
const { container } = render(
|
||||
<TestProviders>
|
||||
<DataProviders timelineId="foo" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="empty"]').last().text()).toEqual(
|
||||
await waitFor(() => {
|
||||
dropMessage.forEach((word) => expect(container.textContent).toContain(word));
|
||||
});
|
||||
});
|
||||
|
||||
test('it renders the data providers', async () => {
|
||||
render(
|
||||
<TestProviders>
|
||||
<DataProviders timelineId="foo" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect((await screen.findByTestId('empty')).textContent).toEqual(
|
||||
'Drop anythinghighlightedhere to build anORquery+ Add field'
|
||||
);
|
||||
});
|
||||
|
||||
describe('resizable drop target', () => {
|
||||
test('it may be resized vertically via a resize handle', () => {
|
||||
const wrapper = mount(
|
||||
test('it may be resized vertically via a resize handle', async () => {
|
||||
render(
|
||||
<TestProviders>
|
||||
<DataProviders timelineId={TimelineId.test} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="dataProviders"]').first()).toHaveStyleRule(
|
||||
'resize',
|
||||
'vertical'
|
||||
);
|
||||
expect(await screen.findByTestId('dataProviders')).toHaveStyleRule('resize', 'vertical');
|
||||
});
|
||||
|
||||
test('it never grows taller than one third (33%) of the view height', () => {
|
||||
const wrapper = mount(
|
||||
test('it never grows taller than one third (33%) of the view height', async () => {
|
||||
render(
|
||||
<TestProviders>
|
||||
<DataProviders timelineId={TimelineId.test} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="dataProviders"]').first()).toHaveStyleRule(
|
||||
'max-height',
|
||||
'33vh'
|
||||
);
|
||||
expect(await screen.findByTestId('dataProviders')).toHaveStyleRule('max-height', '33vh');
|
||||
});
|
||||
|
||||
test('it automatically displays scroll bars when the width or height of the data providers exceeds the drop target', () => {
|
||||
const wrapper = mount(
|
||||
test('it automatically displays scroll bars when the width or height of the data providers exceeds the drop target', async () => {
|
||||
render(
|
||||
<TestProviders>
|
||||
<DataProviders timelineId={TimelineId.test} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="dataProviders"]').first()).toHaveStyleRule(
|
||||
'overflow',
|
||||
'auto'
|
||||
);
|
||||
expect(await screen.findByTestId('dataProviders')).toHaveStyleRule('overflow', 'auto');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,10 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { rgba } from 'polished';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import styled from '@emotion/styled';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { IS_DRAGGING_CLASS_NAME } from '@kbn/securitysolution-t-grid';
|
||||
import { EuiToolTip, EuiSuperSelect, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
|
@ -39,15 +38,15 @@ const DropTargetDataProvidersContainer = styled.div`
|
|||
position: relative;
|
||||
|
||||
.${IS_DRAGGING_CLASS_NAME} & .drop-target-data-providers {
|
||||
background: ${({ theme }) => rgba(theme.eui.euiColorSuccess, 0.1)};
|
||||
border: 0.2rem dashed ${({ theme }) => theme.eui.euiColorSuccess};
|
||||
background: ${({ theme }) => theme.euiTheme.colors.backgroundBaseSuccess};
|
||||
border: 0.2rem dashed ${({ theme }) => theme.euiTheme.colors.borderStrongSuccess};
|
||||
|
||||
& .timeline-drop-area-empty__text {
|
||||
color: ${({ theme }) => theme.eui.euiColorSuccess};
|
||||
color: ${({ theme }) => theme.euiTheme.colors.textSuccess};
|
||||
}
|
||||
|
||||
& .euiFormHelpText {
|
||||
color: ${({ theme }) => theme.eui.euiColorSuccess};
|
||||
color: ${({ theme }) => theme.euiTheme.colors.textSuccess};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
@ -57,15 +56,15 @@ const DropTargetDataProviders = styled.div`
|
|||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
position: relative;
|
||||
border: 0.2rem dashed ${({ theme }) => theme.eui.euiColorMediumShade};
|
||||
border: 0.2rem dashed ${({ theme }) => theme.euiTheme.colors.borderBaseFormsControl};
|
||||
border-radius: 5px;
|
||||
padding: ${({ theme }) => theme.eui.euiSizeS} 0;
|
||||
padding: ${({ theme }) => theme.euiTheme.size.s} 0;
|
||||
margin: 0px 0 0px 0;
|
||||
max-height: 33vh;
|
||||
min-height: 100px;
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
background-color: ${({ theme }) => theme.eui.euiFormBackgroundColor};
|
||||
background-color: ${({ theme }) => theme.euiTheme.components.forms.background};
|
||||
`;
|
||||
|
||||
DropTargetDataProviders.displayName = 'DropTargetDataProviders';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue