Skip to content

Commit

Permalink
[8.8] [SecuritySolution] Fix minimize amd maximize panel actions (#15…
Browse files Browse the repository at this point in the history
…6518) (#156570)

# Backport

This will backport the following commits from `main` to `8.8`:
- [[SecuritySolution] Fix minimize amd maximize panel actions
(#156518)](#156518)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Angela
Chuang","email":"[email protected]"},"sourceCommit":{"committedDate":"2023-05-03T15:13:42Z","message":"[SecuritySolution]
Fix minimize amd maximize panel actions (#156518)\n\n##
Summary\r\n\r\nIssues: #155857
|\r\nhttps://github.com//issues/156253\r\n\r\nThis PR
fixed minimize amd maximize panel actions in Security
Dashboard\r\nview.\r\n\r\n\r\nhttps://user-images.githubusercontent.com/6295984/235910244-1cca8dda-cd4c-40b7-977a-69fa00021f81.mov\r\n\r\n\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Pablo Machado
<[email protected]>","sha":"c278f4e89469ada4d6a506752cd7182c03af69df","branchLabelMapping":{"^v8.9.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","Team:Threat
Hunting","Team: SecuritySolution","Team:Threat
Hunting:Explore","v8.8.0","v8.9.0"],"number":156518,"url":"https://github.com/elastic/kibana/pull/156518","mergeCommit":{"message":"[SecuritySolution]
Fix minimize amd maximize panel actions (#156518)\n\n##
Summary\r\n\r\nIssues: #155857
|\r\nhttps://github.com//issues/156253\r\n\r\nThis PR
fixed minimize amd maximize panel actions in Security
Dashboard\r\nview.\r\n\r\n\r\nhttps://user-images.githubusercontent.com/6295984/235910244-1cca8dda-cd4c-40b7-977a-69fa00021f81.mov\r\n\r\n\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Pablo Machado
<[email protected]>","sha":"c278f4e89469ada4d6a506752cd7182c03af69df"}},"sourceBranch":"main","suggestedTargetBranches":["8.8"],"targetPullRequestStates":[{"branch":"8.8","label":"v8.8.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.9.0","labelRegex":"^v8.9.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/156518","number":156518,"mergeCommit":{"message":"[SecuritySolution]
Fix minimize amd maximize panel actions (#156518)\n\n##
Summary\r\n\r\nIssues: #155857
|\r\nhttps://github.com//issues/156253\r\n\r\nThis PR
fixed minimize amd maximize panel actions in Security
Dashboard\r\nview.\r\n\r\n\r\nhttps://user-images.githubusercontent.com/6295984/235910244-1cca8dda-cd4c-40b7-977a-69fa00021f81.mov\r\n\r\n\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Pablo Machado
<[email protected]>","sha":"c278f4e89469ada4d6a506752cd7182c03af69df"}}]}]
BACKPORT-->

Co-authored-by: Angela Chuang <[email protected]>
  • Loading branch information
kibanamachine and angorayc authored May 3, 2023
1 parent 92ced17 commit f4620b2
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
import { render } from '@testing-library/react';
import React from 'react';
import { DashboardViewPromptState } from '../hooks/use_dashboard_view_prompt_state';
import { StatusPropmpt } from './status_prompt';
import { StatusPrompt } from './status_prompt';

describe('StatusPropmpt', () => {
describe('StatusPrompt', () => {
it('hides by default', () => {
const { queryByTestId } = render(<StatusPropmpt currentState={null} />);
const { queryByTestId } = render(<StatusPrompt currentState={null} />);
expect(queryByTestId(`dashboardViewEmptyDefault`)).not.toBeInTheDocument();
});

it('shows when No Read Permission', () => {
const { queryByTestId } = render(
<StatusPropmpt currentState={DashboardViewPromptState.NoReadPermission} />
<StatusPrompt currentState={DashboardViewPromptState.NoReadPermission} />
);

expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { EuiPageTemplate } from '@elastic/eui';
import type { DashboardViewPromptState } from '../hooks/use_dashboard_view_prompt_state';
import { useDashboardViewPromptState } from '../hooks/use_dashboard_view_prompt_state';

const StatusPropmptComponent = ({
const StatusPromptComponent = ({
currentState,
}: {
currentState: DashboardViewPromptState | null;
Expand All @@ -21,5 +21,5 @@ const StatusPropmptComponent = ({
</EuiPageTemplate>
) : null;
};
StatusPropmptComponent.displayName = 'StatusPropmptComponent';
export const StatusPropmpt = React.memo(StatusPropmptComponent);
StatusPromptComponent.displayName = 'StatusPromptComponent';
export const StatusPrompt = React.memo(StatusPromptComponent);
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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 { render } from '@testing-library/react';
import React from 'react';
import { Router } from 'react-router-dom';
import { DashboardView } from '.';
import { useCapabilities } from '../../../common/lib/kibana';
import { TestProviders } from '../../../common/mock';

jest.mock('react-router-dom', () => {
const actual = jest.requireActual('react-router-dom');
return {
...actual,
useParams: jest.fn().mockReturnValue({ detailName: 'mockSavedObjectId' }),
};
});

jest.mock('../../../common/lib/kibana', () => {
const actual = jest.requireActual('../../../common/lib/kibana');
return {
...actual,
useCapabilities: jest.fn().mockReturnValue({ show: true, showWriteControls: true }),
};
});

jest.mock('../../../common/components/dashboards/dashboard_renderer', () => ({
DashboardRenderer: jest
.fn()
.mockImplementation((props) => (
<div data-test-subj={`dashboard-view-${props.savedObjectId}`} />
)),
}));

type Action = 'PUSH' | 'POP' | 'REPLACE';
const pop: Action = 'POP';
const location = {
pathname: '/network',
search: '',
state: '',
hash: '',
};
const mockHistory = {
length: 2,
location,
action: pop,
push: jest.fn(),
replace: jest.fn(),
go: jest.fn(),
goBack: jest.fn(),
goForward: jest.fn(),
block: jest.fn(),
createHref: jest.fn(),
listen: jest.fn(),
};

describe('DashboardView', () => {
beforeEach(() => {
(useCapabilities as unknown as jest.Mock).mockReturnValue({
show: true,
showWriteControls: true,
});
});
test('render when no error state', () => {
const { queryByTestId } = render(
<Router history={mockHistory}>
<DashboardView />
</Router>,
{ wrapper: TestProviders }
);

expect(queryByTestId(`dashboard-view-mockSavedObjectId`)).toBeInTheDocument();
});

test('render a prompt when error state exists', () => {
(useCapabilities as unknown as jest.Mock).mockReturnValue({
show: false,
showWriteControls: true,
});
const { queryByTestId } = render(
<Router history={mockHistory}>
<DashboardView />
</Router>,
{ wrapper: TestProviders }
);

expect(queryByTestId(`dashboard-view-mockSavedObjectId`)).not.toBeInTheDocument();
expect(queryByTestId(`dashboard-view-error-prompt-wrapper`)).toBeInTheDocument();
});

test('render dashboard view with height', () => {
const { queryByTestId } = render(
<Router history={mockHistory}>
<DashboardView />
</Router>,
{ wrapper: TestProviders }
);

expect(queryByTestId(`dashboard-view-wrapper`)).toHaveStyle({
'min-height': `calc(100vh - 140px)`,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import type { DashboardCapabilities } from '@kbn/dashboard-plugin/common/types';
import { useParams } from 'react-router-dom';

import { pick } from 'lodash/fp';
import { EuiLoadingSpinner } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui';
import { SecurityPageName } from '../../../../common/constants';
import { SpyRoute } from '../../../common/utils/route/spy_routes';
import { useCapabilities } from '../../../common/lib/kibana';
import { DashboardViewPromptState } from '../../hooks/use_dashboard_view_prompt_state';
import { DashboardRenderer } from '../../../common/components/dashboards/dashboard_renderer';
import { StatusPropmpt } from '../../components/status_prompt';
import { StatusPrompt } from '../../components/status_prompt';
import { SiemSearchBar } from '../../../common/components/search_bar';
import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper';
import { FiltersGlobal } from '../../../common/components/filters_global';
Expand All @@ -33,6 +33,8 @@ import { EditDashboardButton } from '../../components/edit_dashboard_button';

type DashboardDetails = Record<string, string>;

const dashboardViewFlexGroupStyle = { minHeight: `calc(100vh - 140px)` };

const DashboardViewComponent: React.FC = () => {
const { fromStr, toStr, from, to } = useDeepEqualSelector((state) =>
pick(['fromStr', 'toStr', 'from', 'to'], inputsSelectors.globalTimeRangeSelector(state))
Expand Down Expand Up @@ -76,34 +78,47 @@ const DashboardViewComponent: React.FC = () => {
</FiltersGlobal>
)}
<SecuritySolutionPageWrapper>
<HeaderPage border title={dashboardDetails?.title ?? <EuiLoadingSpinner size="m" />}>
{showWriteControls && dashboardExists && (
<EditDashboardButton
filters={filters}
query={query}
savedObjectId={savedObjectId}
timeRange={timeRange}
/>
<EuiFlexGroup
direction="column"
style={dashboardViewFlexGroupStyle}
gutterSize="none"
data-test-subj="dashboard-view-wrapper"
>
<EuiFlexItem grow={false}>
<HeaderPage border title={dashboardDetails?.title ?? <EuiLoadingSpinner size="m" />}>
{showWriteControls && dashboardExists && (
<EditDashboardButton
filters={filters}
query={query}
savedObjectId={savedObjectId}
timeRange={timeRange}
/>
)}
</HeaderPage>
</EuiFlexItem>
{!errorState && (
<EuiFlexItem grow>
<DashboardRenderer
query={query}
filters={filters}
canReadDashboard={canReadDashboard}
id={`dashboard-view-${savedObjectId}`}
onDashboardContainerLoaded={onDashboardContainerLoaded}
savedObjectId={savedObjectId}
timeRange={timeRange}
/>
</EuiFlexItem>
)}
</HeaderPage>

{!errorState && (
<DashboardRenderer
query={query}
filters={filters}
canReadDashboard={canReadDashboard}
id={`dashboard-view-${savedObjectId}`}
onDashboardContainerLoaded={onDashboardContainerLoaded}
savedObjectId={savedObjectId}
timeRange={timeRange}
{errorState && (
<EuiFlexItem data-test-subj="dashboard-view-error-prompt-wrapper" grow>
<StatusPrompt currentState={errorState} />
</EuiFlexItem>
)}
<SpyRoute
pageName={SecurityPageName.dashboards}
state={{ dashboardName: dashboardDetails?.title }}
/>
)}

<StatusPropmpt currentState={errorState} />
<SpyRoute
pageName={SecurityPageName.dashboards}
state={{ dashboardName: dashboardDetails?.title }}
/>
</EuiFlexGroup>
</SecuritySolutionPageWrapper>
</>
);
Expand Down

0 comments on commit f4620b2

Please sign in to comment.