Skip to content

Commit

Permalink
[App Search] Convert DocumentCreationModal to DocumentCreationFlyout (#…
Browse files Browse the repository at this point in the history
…86508) (#86542)

* Convert DocumentCreationModal to a Flyout

- Per discussion w/ Davey - it handles longer/detailed content better

* Update instances referencing DocumentCreationFlyout

* Update flyout children

- modal->flyout
- add hasBorder, set EuiTitle sizes, add flexgroup to footer buttons
  • Loading branch information
Constance authored Dec 18, 2020
1 parent 4166446 commit 9eb1ad5
Show file tree
Hide file tree
Showing 18 changed files with 181 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

import { i18n } from '@kbn/i18n';

export const MODAL_CANCEL_BUTTON = i18n.translate(
'xpack.enterpriseSearch.appSearch.documentCreation.modalCancel',
export const FLYOUT_ARIA_LABEL_ID = 'documentCreationFlyoutHeadingId';

export const FLYOUT_CANCEL_BUTTON = i18n.translate(
'xpack.enterpriseSearch.appSearch.documentCreation.flyoutCancel',
{ defaultMessage: 'Cancel' }
);
export const MODAL_CONTINUE_BUTTON = i18n.translate(
'xpack.enterpriseSearch.appSearch.documentCreation.modalContinue',
export const FLYOUT_CONTINUE_BUTTON = i18n.translate(
'xpack.enterpriseSearch.appSearch.documentCreation.flyoutContinue',
{ defaultMessage: 'Continue' }
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { EuiCode, EuiCodeBlock, EuiButtonEmpty } from '@elastic/eui';

import { ApiCodeExample, ModalHeader, ModalBody, ModalFooter } from './api_code_example';
import { ApiCodeExample, FlyoutHeader, FlyoutBody, FlyoutFooter } from './api_code_example';

describe('ApiCodeExample', () => {
const values = {
Expand All @@ -29,23 +29,23 @@ describe('ApiCodeExample', () => {

it('renders', () => {
const wrapper = shallow(<ApiCodeExample />);
expect(wrapper.find(ModalHeader)).toHaveLength(1);
expect(wrapper.find(ModalBody)).toHaveLength(1);
expect(wrapper.find(ModalFooter)).toHaveLength(1);
expect(wrapper.find(FlyoutHeader)).toHaveLength(1);
expect(wrapper.find(FlyoutBody)).toHaveLength(1);
expect(wrapper.find(FlyoutFooter)).toHaveLength(1);
});

describe('ModalHeader', () => {
describe('FlyoutHeader', () => {
it('renders', () => {
const wrapper = shallow(<ModalHeader />);
const wrapper = shallow(<FlyoutHeader />);
expect(wrapper.find('h2').text()).toEqual('Indexing by API');
});
});

describe('ModalBody', () => {
describe('FlyoutBody', () => {
let wrapper: ShallowWrapper;

beforeAll(() => {
wrapper = shallow(<ModalBody />);
wrapper = shallow(<FlyoutBody />);
});

it('renders with the full remote Enterprise Search API URL', () => {
Expand All @@ -64,9 +64,9 @@ describe('ApiCodeExample', () => {
});
});

describe('ModalFooter', () => {
it('closes the modal', () => {
const wrapper = shallow(<ModalFooter />);
describe('FlyoutFooter', () => {
it('closes the flyout', () => {
const wrapper = shallow(<FlyoutFooter />);

wrapper.find(EuiButtonEmpty).simulate('click');
expect(actions.closeDocumentCreation).toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { useValues, useActions } from 'kea';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiModalHeader,
EuiModalHeaderTitle,
EuiModalBody,
EuiModalFooter,
EuiFlyoutHeader,
EuiTitle,
EuiFlyoutBody,
EuiFlyoutFooter,
EuiButtonEmpty,
EuiText,
EuiLink,
Expand All @@ -30,39 +30,43 @@ import { EngineLogic } from '../../engine';
import { EngineDetails } from '../../engine/types';

import { DOCS_PREFIX } from '../../../routes';
import { DOCUMENTS_API_JSON_EXAMPLE, MODAL_CANCEL_BUTTON } from '../constants';
import {
DOCUMENTS_API_JSON_EXAMPLE,
FLYOUT_ARIA_LABEL_ID,
FLYOUT_CANCEL_BUTTON,
} from '../constants';
import { DocumentCreationLogic } from '../';

export const ApiCodeExample: React.FC = () => (
<>
<ModalHeader />
<ModalBody />
<ModalFooter />
<FlyoutHeader />
<FlyoutBody />
<FlyoutFooter />
</>
);

export const ModalHeader: React.FC = () => {
export const FlyoutHeader: React.FC = () => {
return (
<EuiModalHeader>
<EuiModalHeaderTitle>
<h2>
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2 id={FLYOUT_ARIA_LABEL_ID}>
{i18n.translate('xpack.enterpriseSearch.appSearch.documentCreation.api.title', {
defaultMessage: 'Indexing by API',
})}
</h2>
</EuiModalHeaderTitle>
</EuiModalHeader>
</EuiTitle>
</EuiFlyoutHeader>
);
};

export const ModalBody: React.FC = () => {
export const FlyoutBody: React.FC = () => {
const { engineName, engine } = useValues(EngineLogic);
const { apiKey } = engine as EngineDetails;

const documentsApiUrl = getEnterpriseSearchUrl(`/api/as/v1/engines/${engineName}/documents`);

return (
<EuiModalBody>
<EuiFlyoutBody>
<EuiText color="subdued">
<p>
<FormattedMessage
Expand Down Expand Up @@ -113,16 +117,16 @@ export const ModalBody: React.FC = () => {
# ]
`)}
</EuiCodeBlock>
</EuiModalBody>
</EuiFlyoutBody>
);
};

export const ModalFooter: React.FC = () => {
export const FlyoutFooter: React.FC = () => {
const { closeDocumentCreation } = useActions(DocumentCreationLogic);

return (
<EuiModalFooter>
<EuiButtonEmpty onClick={closeDocumentCreation}>{MODAL_CANCEL_BUTTON}</EuiButtonEmpty>
</EuiModalFooter>
<EuiFlyoutFooter>
<EuiButtonEmpty onClick={closeDocumentCreation}>{FLYOUT_CANCEL_BUTTON}</EuiButtonEmpty>
</EuiFlyoutFooter>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import { EuiTextArea, EuiButtonEmpty, EuiButton } from '@elastic/eui';

import { PasteJsonText, ModalHeader, ModalBody, ModalFooter } from './paste_json_text';
import { PasteJsonText, FlyoutHeader, FlyoutBody, FlyoutFooter } from './paste_json_text';

describe('PasteJsonText', () => {
const values = {
Expand All @@ -35,22 +35,22 @@ describe('PasteJsonText', () => {

it('renders', () => {
const wrapper = shallow(<PasteJsonText />);
expect(wrapper.find(ModalHeader)).toHaveLength(1);
expect(wrapper.find(ModalBody)).toHaveLength(1);
expect(wrapper.find(ModalFooter)).toHaveLength(1);
expect(wrapper.find(FlyoutHeader)).toHaveLength(1);
expect(wrapper.find(FlyoutBody)).toHaveLength(1);
expect(wrapper.find(FlyoutFooter)).toHaveLength(1);
});

describe('ModalHeader', () => {
describe('FlyoutHeader', () => {
it('renders', () => {
const wrapper = shallow(<ModalHeader />);
const wrapper = shallow(<FlyoutHeader />);
expect(wrapper.find('h2').text()).toEqual('Create documents');
});
});

describe('ModalBody', () => {
describe('FlyoutBody', () => {
it('renders and updates the textarea value', () => {
setMockValues({ ...values, textInput: 'lorem ipsum' });
const wrapper = shallow(<ModalBody />);
const wrapper = shallow(<FlyoutBody />);
const textarea = wrapper.find(EuiTextArea);

expect(textarea.prop('value')).toEqual('lorem ipsum');
Expand All @@ -60,16 +60,16 @@ describe('PasteJsonText', () => {
});
});

describe('ModalFooter', () => {
describe('FlyoutFooter', () => {
it('closes the modal', () => {
const wrapper = shallow(<ModalFooter />);
const wrapper = shallow(<FlyoutFooter />);

wrapper.find(EuiButtonEmpty).simulate('click');
expect(actions.closeDocumentCreation).toHaveBeenCalled();
});

it('disables/enables the Continue button based on whether text has been entered', () => {
const wrapper = shallow(<ModalFooter />);
const wrapper = shallow(<FlyoutFooter />);
expect(wrapper.find(EuiButton).prop('isDisabled')).toBe(false);

setMockValues({ ...values, textInput: '' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import { useValues, useActions } from 'kea';

import { i18n } from '@kbn/i18n';
import {
EuiModalHeader,
EuiModalHeaderTitle,
EuiModalBody,
EuiModalFooter,
EuiFlyoutHeader,
EuiTitle,
EuiFlyoutBody,
EuiFlyoutFooter,
EuiFlexGroup,
EuiFlexItem,
EuiButton,
EuiButtonEmpty,
EuiTextArea,
Expand All @@ -22,42 +24,42 @@ import {

import { AppLogic } from '../../../app_logic';

import { MODAL_CANCEL_BUTTON, MODAL_CONTINUE_BUTTON } from '../constants';
import { FLYOUT_ARIA_LABEL_ID, FLYOUT_CANCEL_BUTTON, FLYOUT_CONTINUE_BUTTON } from '../constants';
import { DocumentCreationLogic } from '../';

import './paste_json_text.scss';

export const PasteJsonText: React.FC = () => (
<>
<ModalHeader />
<ModalBody />
<ModalFooter />
<FlyoutHeader />
<FlyoutBody />
<FlyoutFooter />
</>
);

export const ModalHeader: React.FC = () => {
export const FlyoutHeader: React.FC = () => {
return (
<EuiModalHeader>
<EuiModalHeaderTitle>
<h2>
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2 id={FLYOUT_ARIA_LABEL_ID}>
{i18n.translate('xpack.enterpriseSearch.appSearch.documentCreation.pasteJsonText.title', {
defaultMessage: 'Create documents',
})}
</h2>
</EuiModalHeaderTitle>
</EuiModalHeader>
</EuiTitle>
</EuiFlyoutHeader>
);
};

export const ModalBody: React.FC = () => {
export const FlyoutBody: React.FC = () => {
const { configuredLimits } = useValues(AppLogic);
const maxDocumentByteSize = configuredLimits?.engine?.maxDocumentByteSize;

const { textInput } = useValues(DocumentCreationLogic);
const { setTextInput } = useActions(DocumentCreationLogic);

return (
<EuiModalBody>
<EuiFlyoutBody>
<EuiText color="subdued">
<p>
{i18n.translate(
Expand All @@ -82,20 +84,26 @@ export const ModalBody: React.FC = () => {
fullWidth
rows={12}
/>
</EuiModalBody>
</EuiFlyoutBody>
);
};

export const ModalFooter: React.FC = () => {
export const FlyoutFooter: React.FC = () => {
const { textInput } = useValues(DocumentCreationLogic);
const { closeDocumentCreation } = useActions(DocumentCreationLogic);

return (
<EuiModalFooter>
<EuiButtonEmpty onClick={closeDocumentCreation}>{MODAL_CANCEL_BUTTON}</EuiButtonEmpty>
<EuiButton fill isDisabled={!textInput.length}>
{MODAL_CONTINUE_BUTTON}
</EuiButton>
</EuiModalFooter>
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={closeDocumentCreation}>{FLYOUT_CANCEL_BUTTON}</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton fill isDisabled={!textInput.length}>
{FLYOUT_CONTINUE_BUTTON}
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutFooter>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('ShowCreationModes', () => {
expect(wrapper.find(DocumentCreationButtons)).toHaveLength(1);
});

it('closes the modal', () => {
it('closes the flyout', () => {
wrapper.find(EuiButtonEmpty).simulate('click');
expect(actions.closeDocumentCreation).toHaveBeenCalled();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,37 @@ import { useActions } from 'kea';

import { i18n } from '@kbn/i18n';
import {
EuiModalHeader,
EuiModalHeaderTitle,
EuiModalBody,
EuiModalFooter,
EuiFlyoutHeader,
EuiTitle,
EuiFlyoutBody,
EuiFlyoutFooter,
EuiButtonEmpty,
} from '@elastic/eui';

import { MODAL_CANCEL_BUTTON } from '../constants';
import { FLYOUT_ARIA_LABEL_ID, FLYOUT_CANCEL_BUTTON } from '../constants';
import { DocumentCreationLogic, DocumentCreationButtons } from '../';

export const ShowCreationModes: React.FC = () => {
const { closeDocumentCreation } = useActions(DocumentCreationLogic);

return (
<>
<EuiModalHeader>
<EuiModalHeaderTitle>
<h2>
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2 id={FLYOUT_ARIA_LABEL_ID}>
{i18n.translate(
'xpack.enterpriseSearch.appSearch.documentCreation.showCreationModes.title',
{ defaultMessage: 'Add new documents' }
)}
</h2>
</EuiModalHeaderTitle>
</EuiModalHeader>
<EuiModalBody>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<DocumentCreationButtons />
</EuiModalBody>
<EuiModalFooter>
<EuiButtonEmpty onClick={closeDocumentCreation}>{MODAL_CANCEL_BUTTON}</EuiButtonEmpty>
</EuiModalFooter>
</EuiFlyoutBody>
<EuiFlyoutFooter>
<EuiButtonEmpty onClick={closeDocumentCreation}>{FLYOUT_CANCEL_BUTTON}</EuiButtonEmpty>
</EuiFlyoutFooter>
</>
);
};
Loading

0 comments on commit 9eb1ad5

Please sign in to comment.