mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
* Create edit node component * Accept EditNodeComponent * Switch to old header * test * Remove iconType * Remove isEditTitle * Move translations * Delete header_page_new component * Move editable title component to different folder * Update jest snapshot * Rename prop * Make EditableTitleComponent more generic * useCallback instead of inline functions in props * Hardcode titles * Move UI state inside EditableTitleComponent * Seperate title's tests * Create tests for EditableTitleComponent * useCallbacks on EditableTitle component * Create translation for aria-label in edit icon * Check if switched to edit mode after pressing submit * Test title when canceled Co-authored-by: patrykkopycinski <contact@patrykkopycinski.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: patrykkopycinski <contact@patrykkopycinski.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
89f24ad30e
commit
19f7c20df0
16 changed files with 546 additions and 632 deletions
26
x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/editable_title.test.tsx.snap
generated
Normal file
26
x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/editable_title.test.tsx.snap
generated
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`EditableTitle it renders 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
gutterSize="none"
|
||||
>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<Memo(TitleComponent)
|
||||
title="Test title"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
>
|
||||
<StyledEuiButtonIcon
|
||||
aria-label="You can edit Test title by clicking"
|
||||
data-test-subj="editable-title-edit-icon"
|
||||
iconType="pencil"
|
||||
onClick={[Function]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
|
@ -8,21 +8,16 @@ exports[`HeaderPage it renders 1`] = `
|
|||
alignItems="center"
|
||||
>
|
||||
<FlexItem>
|
||||
<EuiTitle
|
||||
size="l"
|
||||
>
|
||||
<h1
|
||||
data-test-subj="header-page-title"
|
||||
>
|
||||
Test title
|
||||
|
||||
<StyledEuiBetaBadge
|
||||
label="Beta"
|
||||
tooltipContent="Test tooltip"
|
||||
tooltipPosition="bottom"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<Memo(TitleComponent)
|
||||
badgeOptions={
|
||||
Object {
|
||||
"beta": true,
|
||||
"text": "Beta",
|
||||
"tooltip": "Test tooltip",
|
||||
}
|
||||
}
|
||||
title="Test title"
|
||||
/>
|
||||
<Subtitle
|
||||
data-test-subj="header-page-subtitle"
|
||||
items="Test subtitle"
|
||||
|
|
19
x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/title.test.tsx.snap
generated
Normal file
19
x-pack/legacy/plugins/siem/public/components/header_page/__snapshots__/title.test.tsx.snap
generated
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Title it renders 1`] = `
|
||||
<EuiTitle
|
||||
size="l"
|
||||
>
|
||||
<h1
|
||||
data-test-subj="header-page-title"
|
||||
>
|
||||
Test title
|
||||
|
||||
<StyledEuiBetaBadge
|
||||
label="Beta"
|
||||
tooltipContent="Test tooltip"
|
||||
tooltipPosition="bottom"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
`;
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { TestProviders } from '../../mock';
|
||||
import { EditableTitle } from './editable_title';
|
||||
import { useMountAppended } from '../../utils/use_mount_appended';
|
||||
|
||||
describe('EditableTitle', () => {
|
||||
const mount = useMountAppended();
|
||||
const submitTitle = jest.fn();
|
||||
|
||||
test('it renders', () => {
|
||||
const wrapper = shallow(
|
||||
<EditableTitle title="Test title" onSubmit={submitTitle} isLoading={false} />
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('it shows the edit title input field', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<EditableTitle title="Test title" onSubmit={submitTitle} isLoading={false} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-edit-icon"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="editable-title-input-field"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it shows the submit button', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<EditableTitle title="Test title" onSubmit={submitTitle} isLoading={false} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-edit-icon"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="editable-title-submit-btn"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it shows the cancel button', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<EditableTitle title="Test title" onSubmit={submitTitle} isLoading={false} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-edit-icon"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="editable-title-cancel-btn"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it DOES NOT shows the edit icon when in edit mode', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<EditableTitle title="Test title" onSubmit={submitTitle} isLoading={false} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-edit-icon"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="editable-title-edit-icon"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('it switch to non edit mode when canceled', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<EditableTitle title="Test title" onSubmit={submitTitle} isLoading={false} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-edit-icon"]').simulate('click');
|
||||
wrapper.update();
|
||||
wrapper.find('button[data-test-subj="editable-title-cancel-btn"]').simulate('click');
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="editable-title-edit-icon"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it should change the title', () => {
|
||||
const newTitle = 'new test title';
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<EditableTitle title="Test title" onSubmit={submitTitle} isLoading={false} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-edit-icon"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
wrapper
|
||||
.find('input[data-test-subj="editable-title-input-field"]')
|
||||
.simulate('change', { target: { value: newTitle } });
|
||||
|
||||
wrapper.update();
|
||||
|
||||
expect(
|
||||
wrapper.find('input[data-test-subj="editable-title-input-field"]').prop('value')
|
||||
).toEqual(newTitle);
|
||||
});
|
||||
|
||||
test('it should NOT change the title when cancel', () => {
|
||||
const title = 'Test title';
|
||||
const newTitle = 'new test title';
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<EditableTitle title={title} onSubmit={submitTitle} isLoading={false} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-edit-icon"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
wrapper
|
||||
.find('input[data-test-subj="editable-title-input-field"]')
|
||||
.simulate('change', { target: { value: newTitle } });
|
||||
wrapper.update();
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-cancel-btn"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('h1[data-test-subj="header-page-title"]').text()).toEqual(title);
|
||||
});
|
||||
|
||||
test('it submits the title', () => {
|
||||
const newTitle = 'new test title';
|
||||
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<EditableTitle title="Test title" onSubmit={submitTitle} isLoading={false} />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-edit-icon"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
wrapper
|
||||
.find('input[data-test-subj="editable-title-input-field"]')
|
||||
.simulate('change', { target: { value: newTitle } });
|
||||
|
||||
wrapper.find('button[data-test-subj="editable-title-submit-btn"]').simulate('click');
|
||||
wrapper.update();
|
||||
|
||||
expect(submitTitle).toHaveBeenCalled();
|
||||
expect(submitTitle.mock.calls[0][0]).toEqual(newTitle);
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="editable-title-edit-icon"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiFieldText,
|
||||
EuiButtonIcon,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import * as i18n from './translations';
|
||||
|
||||
import { Title } from './title';
|
||||
|
||||
const StyledEuiButtonIcon = styled(EuiButtonIcon)`
|
||||
${({ theme }) => css`
|
||||
margin-left: ${theme.eui.euiSize};
|
||||
`}
|
||||
`;
|
||||
|
||||
StyledEuiButtonIcon.displayName = 'StyledEuiButtonIcon';
|
||||
|
||||
interface Props {
|
||||
isLoading: boolean;
|
||||
title: string | React.ReactNode;
|
||||
onSubmit: (title: string) => void;
|
||||
}
|
||||
|
||||
const EditableTitleComponent: React.FC<Props> = ({ onSubmit, isLoading, title }) => {
|
||||
const [editMode, setEditMode] = useState(false);
|
||||
const [changedTitle, onTitleChange] = useState(title);
|
||||
|
||||
const onCancel = useCallback(() => setEditMode(false), []);
|
||||
const onClickEditIcon = useCallback(() => setEditMode(true), []);
|
||||
|
||||
const onClickSubmit = useCallback(
|
||||
(newTitle: string): void => {
|
||||
onSubmit(newTitle);
|
||||
setEditMode(false);
|
||||
},
|
||||
[changedTitle]
|
||||
);
|
||||
|
||||
return editMode ? (
|
||||
<EuiFlexGroup alignItems="center" gutterSize="m" justifyContent="spaceBetween">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFieldText
|
||||
onChange={e => onTitleChange(e.target.value)}
|
||||
value={`${changedTitle}`}
|
||||
data-test-subj="editable-title-input-field"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexGroup gutterSize="none" responsive={false} wrap={true}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
fill
|
||||
isDisabled={isLoading}
|
||||
isLoading={isLoading}
|
||||
onClick={() => onClickSubmit(changedTitle as string)}
|
||||
data-test-subj="editable-title-submit-btn"
|
||||
>
|
||||
{i18n.SUBMIT}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty onClick={onCancel} data-test-subj="editable-title-cancel-btn">
|
||||
{i18n.CANCEL}
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiFlexItem />
|
||||
</EuiFlexGroup>
|
||||
) : (
|
||||
<EuiFlexGroup alignItems="center" gutterSize="none">
|
||||
<EuiFlexItem grow={false}>
|
||||
<Title title={title} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<StyledEuiButtonIcon
|
||||
aria-label={i18n.EDIT_TITLE_ARIA(title as string)}
|
||||
iconType="pencil"
|
||||
onClick={onClickEditIcon}
|
||||
data-test-subj="editable-title-edit-icon"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export const EditableTitle = React.memo(EditableTitleComponent);
|
|
@ -31,21 +31,6 @@ describe('HeaderPage', () => {
|
|||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('it renders the title', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-title"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it renders the back link when provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
|
@ -191,34 +176,4 @@ describe('HeaderPage', () => {
|
|||
expect(siemHeaderPage).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
|
||||
expect(siemHeaderPage).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
|
||||
});
|
||||
|
||||
test('it renders as a draggable when arguments provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage draggableArguments={{ field: 'neat', value: 'cool' }} title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-draggable"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it DOES NOT render as a draggable when arguments not provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-draggable"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,20 +4,14 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiBetaBadge,
|
||||
EuiBadge,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiProgress,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiProgress } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
|
||||
import { DefaultDraggable } from '../draggables';
|
||||
import { LinkIcon, LinkIconProps } from '../link_icon';
|
||||
import { Subtitle, SubtitleProps } from '../subtitle';
|
||||
import { Title } from './title';
|
||||
import { DraggableArguments, BadgeOptions, TitleProp } from './types';
|
||||
|
||||
interface HeaderProps {
|
||||
border?: boolean;
|
||||
|
@ -63,28 +57,11 @@ const Badge = styled(EuiBadge)`
|
|||
`;
|
||||
Badge.displayName = 'Badge';
|
||||
|
||||
const StyledEuiBetaBadge = styled(EuiBetaBadge)`
|
||||
vertical-align: middle;
|
||||
`;
|
||||
|
||||
StyledEuiBetaBadge.displayName = 'StyledEuiBetaBadge';
|
||||
|
||||
interface BackOptions {
|
||||
href: LinkIconProps['href'];
|
||||
text: LinkIconProps['children'];
|
||||
}
|
||||
|
||||
interface BadgeOptions {
|
||||
beta?: boolean;
|
||||
text: string;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
interface DraggableArguments {
|
||||
field: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface HeaderPageProps extends HeaderProps {
|
||||
backOptions?: BackOptions;
|
||||
badgeOptions?: BadgeOptions;
|
||||
|
@ -92,7 +69,8 @@ export interface HeaderPageProps extends HeaderProps {
|
|||
draggableArguments?: DraggableArguments;
|
||||
subtitle?: SubtitleProps['items'];
|
||||
subtitle2?: SubtitleProps['items'];
|
||||
title: string | React.ReactNode;
|
||||
title: TitleProp;
|
||||
titleNode?: React.ReactElement;
|
||||
}
|
||||
|
||||
const HeaderPageComponent: React.FC<HeaderPageProps> = ({
|
||||
|
@ -105,6 +83,7 @@ const HeaderPageComponent: React.FC<HeaderPageProps> = ({
|
|||
subtitle,
|
||||
subtitle2,
|
||||
title,
|
||||
titleNode,
|
||||
...rest
|
||||
}) => (
|
||||
<Header border={border} {...rest}>
|
||||
|
@ -118,34 +97,13 @@ const HeaderPageComponent: React.FC<HeaderPageProps> = ({
|
|||
</LinkBack>
|
||||
)}
|
||||
|
||||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="header-page-title">
|
||||
{!draggableArguments ? (
|
||||
title
|
||||
) : (
|
||||
<DefaultDraggable
|
||||
data-test-subj="header-page-draggable"
|
||||
id={`header-page-draggable-${draggableArguments.field}-${draggableArguments.value}`}
|
||||
field={draggableArguments.field}
|
||||
value={`${draggableArguments.value}`}
|
||||
/>
|
||||
)}
|
||||
{badgeOptions && (
|
||||
<>
|
||||
{' '}
|
||||
{badgeOptions.beta ? (
|
||||
<StyledEuiBetaBadge
|
||||
label={badgeOptions.text}
|
||||
tooltipContent={badgeOptions.tooltip}
|
||||
tooltipPosition="bottom"
|
||||
/>
|
||||
) : (
|
||||
<Badge color="hollow">{badgeOptions.text}</Badge>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
{titleNode || (
|
||||
<Title
|
||||
draggableArguments={draggableArguments}
|
||||
title={title}
|
||||
badgeOptions={badgeOptions}
|
||||
/>
|
||||
)}
|
||||
|
||||
{subtitle && <Subtitle data-test-subj="header-page-subtitle" items={subtitle} />}
|
||||
{subtitle2 && <Subtitle data-test-subj="header-page-subtitle-2" items={subtitle2} />}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { TestProviders } from '../../mock';
|
||||
import { Title } from './title';
|
||||
import { useMountAppended } from '../../utils/use_mount_appended';
|
||||
|
||||
describe('Title', () => {
|
||||
const mount = useMountAppended();
|
||||
|
||||
test('it renders', () => {
|
||||
const wrapper = shallow(
|
||||
<Title
|
||||
badgeOptions={{ beta: true, text: 'Beta', tooltip: 'Test tooltip' }}
|
||||
title="Test title"
|
||||
/>
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('it renders the title', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<Title title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-title"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it renders as a draggable when arguments provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<Title draggableArguments={{ field: 'neat', value: 'cool' }} title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-draggable"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it DOES NOT render as a draggable when arguments not provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<Title title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-draggable"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiBetaBadge, EuiBadge, EuiTitle } from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { DraggableArguments, BadgeOptions, TitleProp } from './types';
|
||||
import { DefaultDraggable } from '../draggables';
|
||||
|
||||
const StyledEuiBetaBadge = styled(EuiBetaBadge)`
|
||||
vertical-align: middle;
|
||||
`;
|
||||
|
||||
StyledEuiBetaBadge.displayName = 'StyledEuiBetaBadge';
|
||||
|
||||
const Badge = styled(EuiBadge)`
|
||||
letter-spacing: 0;
|
||||
`;
|
||||
Badge.displayName = 'Badge';
|
||||
|
||||
interface Props {
|
||||
badgeOptions?: BadgeOptions;
|
||||
title: TitleProp;
|
||||
draggableArguments?: DraggableArguments;
|
||||
}
|
||||
|
||||
const TitleComponent: React.FC<Props> = ({ draggableArguments, title, badgeOptions }) => (
|
||||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="header-page-title">
|
||||
{!draggableArguments ? (
|
||||
title
|
||||
) : (
|
||||
<DefaultDraggable
|
||||
data-test-subj="header-page-draggable"
|
||||
id={`header-page-draggable-${draggableArguments.field}-${draggableArguments.value}`}
|
||||
field={draggableArguments.field}
|
||||
value={`${draggableArguments.value}`}
|
||||
/>
|
||||
)}
|
||||
{badgeOptions && (
|
||||
<>
|
||||
{' '}
|
||||
{badgeOptions.beta ? (
|
||||
<StyledEuiBetaBadge
|
||||
label={badgeOptions.text}
|
||||
tooltipContent={badgeOptions.tooltip}
|
||||
tooltipPosition="bottom"
|
||||
/>
|
||||
) : (
|
||||
<Badge color="hollow">{badgeOptions.text}</Badge>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
);
|
||||
|
||||
export const Title = React.memo(TitleComponent);
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const SUBMIT = i18n.translate('xpack.siem.header.editableTitle.submit', {
|
||||
defaultMessage: 'Submit',
|
||||
});
|
||||
|
||||
export const CANCEL = i18n.translate('xpack.siem.header.editableTitle.cancel', {
|
||||
defaultMessage: 'Cancel',
|
||||
});
|
||||
|
||||
export const EDIT_TITLE_ARIA = (title: string) =>
|
||||
i18n.translate('xpack.siem.header.editableTitle.editButtonAria', {
|
||||
values: { title },
|
||||
defaultMessage: 'You can edit {title} by clicking',
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export type TitleProp = string | React.ReactNode;
|
||||
|
||||
export interface DraggableArguments {
|
||||
field: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface BadgeOptions {
|
||||
beta?: boolean;
|
||||
text: string;
|
||||
tooltip?: string;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`HeaderPage it renders 1`] = `
|
||||
<Header
|
||||
border={true}
|
||||
>
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
justifyContent="spaceBetween"
|
||||
>
|
||||
<FlexItem
|
||||
grow={false}
|
||||
>
|
||||
<EuiTitle
|
||||
size="l"
|
||||
>
|
||||
<h1
|
||||
data-test-subj="header-page-title"
|
||||
>
|
||||
Test title
|
||||
|
||||
<StyledEuiBetaBadge
|
||||
label="Beta"
|
||||
tooltipContent="Test tooltip"
|
||||
tooltipPosition="bottom"
|
||||
/>
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<Subtitle
|
||||
data-test-subj="header-page-subtitle"
|
||||
items="Test subtitle"
|
||||
/>
|
||||
<Subtitle
|
||||
data-test-subj="header-page-subtitle-2"
|
||||
items="Test subtitle 2"
|
||||
/>
|
||||
</FlexItem>
|
||||
<FlexItem
|
||||
data-test-subj="header-page-supplements"
|
||||
>
|
||||
<p>
|
||||
Test supplement
|
||||
</p>
|
||||
</FlexItem>
|
||||
</EuiFlexGroup>
|
||||
</Header>
|
||||
`;
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { TestProviders } from '../../mock';
|
||||
import { HeaderPage } from './index';
|
||||
import { useMountAppended } from '../../utils/use_mount_appended';
|
||||
|
||||
describe('HeaderPage', () => {
|
||||
const mount = useMountAppended();
|
||||
|
||||
test('it renders', () => {
|
||||
const wrapper = shallow(
|
||||
<HeaderPage
|
||||
badgeOptions={{ beta: true, text: 'Beta', tooltip: 'Test tooltip' }}
|
||||
border
|
||||
subtitle="Test subtitle"
|
||||
subtitle2="Test subtitle 2"
|
||||
title="Test title"
|
||||
>
|
||||
<p>{'Test supplement'}</p>
|
||||
</HeaderPage>
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('it renders the title', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-title"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it renders the back link when provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage backOptions={{ href: '#', text: 'Test link' }} title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('.siemHeaderPage__linkBack')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it DOES NOT render the back link when not provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('.siemHeaderPage__linkBack')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('it renders the first subtitle when provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage subtitle="Test subtitle" title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-subtitle"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it DOES NOT render the first subtitle when not provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-section-subtitle"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('it renders the second subtitle when provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage subtitle2="Test subtitle 2" title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-subtitle-2"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it DOES NOT render the second subtitle when not provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-section-subtitle-2"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('it renders supplements when children provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title">
|
||||
<p>{'Test supplement'}</p>
|
||||
</HeaderPage>
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-supplements"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it DOES NOT render supplements when children not provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-supplements"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('it applies border styles when border is true', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage border title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
const siemHeaderPage = wrapper.find('.siemHeaderPage').first();
|
||||
|
||||
expect(siemHeaderPage).toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
|
||||
expect(siemHeaderPage).toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
|
||||
});
|
||||
|
||||
test('it DOES NOT apply border styles when border is false', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
const siemHeaderPage = wrapper.find('.siemHeaderPage').first();
|
||||
|
||||
expect(siemHeaderPage).not.toHaveStyleRule('border-bottom', euiDarkVars.euiBorderThin);
|
||||
expect(siemHeaderPage).not.toHaveStyleRule('padding-bottom', euiDarkVars.paddingSizes.l);
|
||||
});
|
||||
|
||||
test('it renders as a draggable when arguments provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage draggableArguments={{ field: 'neat', value: 'cool' }} title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-draggable"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('it DOES NOT render as a draggable when arguments not provided', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<HeaderPage title="Test title" />
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(
|
||||
wrapper
|
||||
.find('[data-test-subj="header-page-draggable"]')
|
||||
.first()
|
||||
.exists()
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiBadge,
|
||||
EuiBetaBadge,
|
||||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
EuiButtonIcon,
|
||||
EuiFieldText,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiProgress,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
|
||||
import { DefaultDraggable } from '../draggables';
|
||||
import { LinkIcon, LinkIconProps } from '../link_icon';
|
||||
import { Subtitle, SubtitleProps } from '../subtitle';
|
||||
import * as i18n from './translations';
|
||||
|
||||
interface HeaderProps {
|
||||
border?: boolean;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const Header = styled.header.attrs({
|
||||
className: 'siemHeaderPage',
|
||||
})<HeaderProps>`
|
||||
${({ border, theme }) => css`
|
||||
margin-bottom: ${theme.eui.euiSizeL};
|
||||
|
||||
${border &&
|
||||
css`
|
||||
border-bottom: ${theme.eui.euiBorderThin};
|
||||
padding-bottom: ${theme.eui.paddingSizes.l};
|
||||
.euiProgress {
|
||||
top: ${theme.eui.paddingSizes.l};
|
||||
}
|
||||
`}
|
||||
`}
|
||||
`;
|
||||
Header.displayName = 'Header';
|
||||
|
||||
const FlexItem = styled(EuiFlexItem)`
|
||||
display: block;
|
||||
`;
|
||||
FlexItem.displayName = 'FlexItem';
|
||||
|
||||
const LinkBack = styled.div.attrs({
|
||||
className: 'siemHeaderPage__linkBack',
|
||||
})`
|
||||
${({ theme }) => css`
|
||||
font-size: ${theme.eui.euiFontSizeXS};
|
||||
line-height: ${theme.eui.euiLineHeight};
|
||||
margin-bottom: ${theme.eui.euiSizeS};
|
||||
`}
|
||||
`;
|
||||
LinkBack.displayName = 'LinkBack';
|
||||
|
||||
const Badge = styled(EuiBadge)`
|
||||
letter-spacing: 0;
|
||||
`;
|
||||
Badge.displayName = 'Badge';
|
||||
|
||||
const StyledEuiBetaBadge = styled(EuiBetaBadge)`
|
||||
vertical-align: middle;
|
||||
`;
|
||||
|
||||
StyledEuiBetaBadge.displayName = 'StyledEuiBetaBadge';
|
||||
|
||||
const StyledEuiButtonIcon = styled(EuiButtonIcon)`
|
||||
${({ theme }) => css`
|
||||
margin-left: ${theme.eui.euiSize};
|
||||
`}
|
||||
`;
|
||||
|
||||
StyledEuiButtonIcon.displayName = 'StyledEuiButtonIcon';
|
||||
|
||||
interface BackOptions {
|
||||
href: LinkIconProps['href'];
|
||||
text: LinkIconProps['children'];
|
||||
}
|
||||
|
||||
interface BadgeOptions {
|
||||
beta?: boolean;
|
||||
text: string;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
interface DraggableArguments {
|
||||
field: string;
|
||||
value: string;
|
||||
}
|
||||
interface IconAction {
|
||||
'aria-label': string;
|
||||
iconType: string;
|
||||
onChange: (a: string) => void;
|
||||
onClick: (b: boolean) => void;
|
||||
onSubmit: () => void;
|
||||
}
|
||||
|
||||
export interface HeaderPageProps extends HeaderProps {
|
||||
backOptions?: BackOptions;
|
||||
badgeOptions?: BadgeOptions;
|
||||
children?: React.ReactNode;
|
||||
draggableArguments?: DraggableArguments;
|
||||
isEditTitle?: boolean;
|
||||
iconAction?: IconAction;
|
||||
subtitle2?: SubtitleProps['items'];
|
||||
subtitle?: SubtitleProps['items'];
|
||||
title: string | React.ReactNode;
|
||||
}
|
||||
|
||||
const HeaderPageComponent: React.FC<HeaderPageProps> = ({
|
||||
backOptions,
|
||||
badgeOptions,
|
||||
border,
|
||||
children,
|
||||
draggableArguments,
|
||||
isEditTitle,
|
||||
iconAction,
|
||||
isLoading,
|
||||
subtitle,
|
||||
subtitle2,
|
||||
title,
|
||||
...rest
|
||||
}) => (
|
||||
<Header border={border} {...rest}>
|
||||
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
|
||||
<FlexItem grow={false}>
|
||||
{backOptions && (
|
||||
<LinkBack>
|
||||
<LinkIcon href={backOptions.href} iconType="arrowLeft">
|
||||
{backOptions.text}
|
||||
</LinkIcon>
|
||||
</LinkBack>
|
||||
)}
|
||||
|
||||
{isEditTitle && iconAction ? (
|
||||
<EuiFlexGroup alignItems="center" gutterSize="m" justifyContent="spaceBetween">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiFieldText
|
||||
onChange={e => iconAction.onChange(e.target.value)}
|
||||
value={`${title}`}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexGroup gutterSize="none" responsive={false} wrap={true}>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
fill
|
||||
isDisabled={isLoading}
|
||||
isLoading={isLoading}
|
||||
onClick={iconAction.onSubmit}
|
||||
>
|
||||
{i18n.SUBMIT}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty onClick={() => iconAction.onClick(false)}>
|
||||
{i18n.CANCEL}
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiFlexItem />
|
||||
</EuiFlexGroup>
|
||||
) : (
|
||||
<EuiTitle size="l">
|
||||
<h1 data-test-subj="header-page-title">
|
||||
{!draggableArguments ? (
|
||||
title
|
||||
) : (
|
||||
<DefaultDraggable
|
||||
data-test-subj="header-page-draggable"
|
||||
id={`header-page-draggable-${draggableArguments.field}-${draggableArguments.value}`}
|
||||
field={draggableArguments.field}
|
||||
value={`${draggableArguments.value}`}
|
||||
/>
|
||||
)}
|
||||
{badgeOptions && (
|
||||
<>
|
||||
{' '}
|
||||
{badgeOptions.beta ? (
|
||||
<StyledEuiBetaBadge
|
||||
label={badgeOptions.text}
|
||||
tooltipContent={badgeOptions.tooltip}
|
||||
tooltipPosition="bottom"
|
||||
/>
|
||||
) : (
|
||||
<Badge color="hollow">{badgeOptions.text}</Badge>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{iconAction && (
|
||||
<StyledEuiButtonIcon
|
||||
aria-label={iconAction['aria-label']}
|
||||
iconType={iconAction.iconType}
|
||||
onClick={() => iconAction.onClick(true)}
|
||||
/>
|
||||
)}
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
)}
|
||||
|
||||
{subtitle && <Subtitle data-test-subj="header-page-subtitle" items={subtitle} />}
|
||||
{subtitle2 && <Subtitle data-test-subj="header-page-subtitle-2" items={subtitle2} />}
|
||||
{border && isLoading && <EuiProgress size="xs" color="accent" />}
|
||||
</FlexItem>
|
||||
|
||||
{children && <FlexItem data-test-subj="header-page-supplements">{children}</FlexItem>}
|
||||
</EuiFlexGroup>
|
||||
</Header>
|
||||
);
|
||||
|
||||
export const HeaderPage = React.memo(HeaderPageComponent);
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const SUBMIT = i18n.translate('xpack.siem.case.casePage.title.submit', {
|
||||
defaultMessage: 'Submit',
|
||||
});
|
||||
|
||||
export const CANCEL = i18n.translate('xpack.siem.case.casePage.title.cancel', {
|
||||
defaultMessage: 'Cancel',
|
||||
});
|
|
@ -24,7 +24,8 @@ import { DescriptionMarkdown } from '../description_md_editor';
|
|||
import { Case } from '../../../../containers/case/types';
|
||||
import { FormattedRelativePreferenceDate } from '../../../../components/formatted_date';
|
||||
import { getCaseUrl } from '../../../../components/link_to';
|
||||
import { HeaderPage } from '../../../../components/header_page_new';
|
||||
import { HeaderPage } from '../../../../components/header_page';
|
||||
import { EditableTitle } from '../../../../components/header_page/editable_title';
|
||||
import { Markdown } from '../../../../components/markdown';
|
||||
import { PropertyActions } from '../property_actions';
|
||||
import { TagList } from '../tag_list';
|
||||
|
@ -50,6 +51,7 @@ const MyDescriptionList = styled(EuiDescriptionList)`
|
|||
const MyWrapper = styled(WrapperPage)`
|
||||
padding-bottom: 0;
|
||||
`;
|
||||
|
||||
const BackgroundWrapper = styled.div`
|
||||
${({ theme }) => css`
|
||||
background-color: ${theme.eui.euiColorEmptyShade};
|
||||
|
@ -67,7 +69,6 @@ interface CasesProps {
|
|||
export const Cases = React.memo<CasesProps>(({ caseId, initialData, isLoading }) => {
|
||||
const [{ data }, dispatchUpdateCaseProperty] = useUpdateCase(caseId, initialData);
|
||||
const [isEditDescription, setIsEditDescription] = useState(false);
|
||||
const [isEditTitle, setIsEditTitle] = useState(false);
|
||||
const [isEditTags, setIsEditTags] = useState(false);
|
||||
const [isCaseOpen, setIsCaseOpen] = useState(data.state === 'open');
|
||||
const [description, setDescription] = useState(data.description);
|
||||
|
@ -83,7 +84,6 @@ export const Cases = React.memo<CasesProps>(({ caseId, initialData, isLoading })
|
|||
updateKey: 'title',
|
||||
updateValue,
|
||||
});
|
||||
setIsEditTitle(false);
|
||||
}
|
||||
break;
|
||||
case 'description':
|
||||
|
@ -210,6 +210,17 @@ export const Cases = React.memo<CasesProps>(({ caseId, initialData, isLoading })
|
|||
),
|
||||
},
|
||||
];
|
||||
|
||||
const onSubmit = useCallback(
|
||||
newTitle => {
|
||||
onUpdateField('title', newTitle);
|
||||
setTitle(newTitle);
|
||||
},
|
||||
[title]
|
||||
);
|
||||
|
||||
const titleNode = <EditableTitle isLoading={isLoading} title={title} onSubmit={onSubmit} />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<MyWrapper>
|
||||
|
@ -218,14 +229,7 @@ export const Cases = React.memo<CasesProps>(({ caseId, initialData, isLoading })
|
|||
href: getCaseUrl(),
|
||||
text: i18n.BACK_TO_ALL,
|
||||
}}
|
||||
iconAction={{
|
||||
'aria-label': title,
|
||||
iconType: 'pencil',
|
||||
onChange: newTitle => setTitle(newTitle),
|
||||
onSubmit: () => onUpdateField('title', title),
|
||||
onClick: isEdit => setIsEditTitle(isEdit),
|
||||
}}
|
||||
isEditTitle={isEditTitle}
|
||||
titleNode={titleNode}
|
||||
title={title}
|
||||
>
|
||||
<EuiFlexGroup gutterSize="l" justifyContent="flexEnd">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue