Skip to content

Commit

Permalink
UiFramework: Modals in react (#11500) (#11585)
Browse files Browse the repository at this point in the history
* Reactify the confirmation modal

Up next: jest tests

* Add tests

- Relies on #10821 getting
checked in first for commonHtmlProps

* Don't include the overlay as part of the confirm modal component

* Use the react version of a confirmation modal

- Can’t use the modalOverlay or it would be two nested react roots, due
to the way it’s embedded in angular.

* Add snapshots

* Fix tests

* fix confirm_modal_promise tests

I have no idea why the introduction of react would cause this to fail
as it was, but for some reason, grabbing the button reference has to be
after the digest loop.

* Address code review comments

* switch over the remaining React.PropType references (in the modals dir anyway)
  • Loading branch information
stacey-gammon authored May 3, 2017
1 parent 02ad0ac commit 7e74b2d
Show file tree
Hide file tree
Showing 40 changed files with 598 additions and 158 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
"node-uuid": "1.4.7",
"pegjs": "0.9.0",
"postcss-loader": "1.2.1",
"prop-types": "15.5.8",
"pui-react-overlay-trigger": "7.5.4",
"pui-react-tooltip": "7.5.4",
"querystring-browser": "1.0.4",
Expand Down
8 changes: 4 additions & 4 deletions src/ui/public/modals/__tests__/confirm_modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('ui/modals/confirm_modal', function () {
confirmModal(myMessage, { confirmButtonText: 'GREAT!', onConfirm: _.noop });

$rootScope.$digest();
const message = findByDataTestSubj('confirmModalBodyText')[0].innerText;
const message = findByDataTestSubj('confirmModalBodyText')[0].innerText.trim();
expect(message).to.equal(myMessage);
});

Expand All @@ -62,21 +62,21 @@ describe('ui/modals/confirm_modal', function () {
it('for confirm button', () => {
confirmModal('What\'s your favorite dinosaur?', confirmModalOptions);
$rootScope.$digest();
const confirmButtonText = findByDataTestSubj('confirmModalConfirmButton')[0].innerText;
const confirmButtonText = findByDataTestSubj('confirmModalConfirmButton')[0].innerText.trim();
expect(confirmButtonText).to.equal('Troodon');
});

it('for cancel button', () => {
confirmModal('What\'s your favorite dinosaur?', confirmModalOptions);
$rootScope.$digest();
const cancelButtonText = findByDataTestSubj('confirmModalCancelButton')[0].innerText;
const cancelButtonText = findByDataTestSubj('confirmModalCancelButton')[0].innerText.trim();
expect(cancelButtonText).to.equal('Dilophosaurus');
});

it('for title text', () => {
confirmModal('What\'s your favorite dinosaur?', confirmModalOptions);
$rootScope.$digest();
const titleText = findByDataTestSubj('confirmModalTitleText')[0].innerText;
const titleText = findByDataTestSubj('confirmModalTitleText')[0].innerText.trim();
expect(titleText).to.equal('Dinosaurs');
});
});
Expand Down
6 changes: 2 additions & 4 deletions src/ui/public/modals/__tests__/confirm_modal_promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,10 @@ describe('ui/modals/confirm_modal_promise', function () {
const cancelCallback = sinon.spy();

promise.then(confirmCallback, cancelCallback);
$rootScope.$digest();
const confirmButton = angular.element(document.body).find('[data-test-subj=confirmModalConfirmButton]');

$rootScope.$digest();
confirmButton.click();

expect(confirmCallback.called).to.be(true);
expect(cancelCallback.called).to.be(false);
});
Expand All @@ -72,9 +71,8 @@ describe('ui/modals/confirm_modal_promise', function () {
const cancelCallback = sinon.spy();
promise.then(confirmCallback, cancelCallback);

const noButton = angular.element(document.body).find('[data-test-subj=confirmModalCancelButton]');

$rootScope.$digest();
const noButton = angular.element(document.body).find('[data-test-subj=confirmModalCancelButton]');
noButton.click();

expect(cancelCallback.called).to.be(true);
Expand Down
41 changes: 9 additions & 32 deletions src/ui/public/modals/confirm_modal.html
Original file line number Diff line number Diff line change
@@ -1,32 +1,9 @@
<div class="kuiModal" style="width: 450px" data-test-subj="confirmModal">
<div class="kuiModalHeader" ng-if="title">
<div class="kuiModalHeader__title" data-test-subj="confirmModalTitleText">
{{title}}
</div>
</div>
<div class="kuiModalBody">
<div
class="kuiModalBodyText"
data-test-subj="confirmModalBodyText"
>
{{message}}
</div>
</div>

<div class="kuiModalFooter">
<button
class="kuiButton kuiButton--hollow"
data-test-subj="confirmModalCancelButton"
ng-click="onCancel()"
>
{{cancelButtonText}}
</button>
<button
class="kuiButton kuiButton--primary"
data-test-subj="confirmModalConfirmButton"
ng-click="onConfirm()"
>
{{confirmButtonText}}
</button>
</div>
</div>
<confirm-modal
data-test-subj="confirmModal"
on-cancel="onCancel"
on-confirm="onConfirm"
confirm-button-text="confirmButtonText"
cancel-button-text="cancelButtonText"
message="message"
title="title"
></confirm-modal>
5 changes: 5 additions & 0 deletions src/ui/public/react_components.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ import 'ngreact';

import {
KuiToolBarSearchBox,
KuiConfirmModal,
} from 'ui_framework/components';

import { uiModules } from 'ui/modules';

const app = uiModules.get('app/kibana', ['react']);
app.directive('toolBarSearchBox', function (reactDirective) {
return reactDirective(KuiToolBarSearchBox);
});
app.directive('confirmModal', function (reactDirective) {
return reactDirective(KuiConfirmModal);
});
6 changes: 6 additions & 0 deletions ui_framework/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ export {
KuiLinkButton,
KuiSubmitButton,
} from './button';

export {
KuiToolBarSearchBox,
KuiToolBar,
KuiToolBarFooter,
} from './tool_bar';

export {
KuiConfirmModal,
KuiModalOverlay
} from './modal';
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders KuiConfirmModal 1`] = `
<div
aria-label="aria-label"
class="kuiModal testClass1 testClass2"
data-tests-subj="test subject string"
style="width:450px;"
>
<div
class="kuiModalHeader"
>
<div
class="kuiModalHeader__title"
data-test-subj="confirmModalTitleText"
>
A confirmation modal
</div>
</div>
<div
class="kuiModalBody"
>
<div
class="kuiModalBodyText"
data-test-subj="confirmModalBodyText"
>
This is a confirmation modal example
</div>
</div>
<div
class="kuiModalFooter"
>
<button
class="kuiButton kuiButton--hollow"
data-test-subj="confirmModalCancelButton"
>
<span
class="kuiButton__inner"
>
<span>
Cancel Button Text
</span>
</span>
</button>
<button
class="kuiButton kuiButton--primary"
data-test-subj="confirmModalConfirmButton"
>
<span
class="kuiButton__inner"
>
<span>
Confirm Button Text
</span>
</span>
</button>
</div>
</div>
`;
11 changes: 11 additions & 0 deletions ui_framework/components/modal/__snapshots__/modal.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders KuiModal 1`] = `
<div
aria-label="aria-label"
class="kuiModal testClass1 testClass2"
data-test-subj="test subject string"
>
children
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders KuiModalBody 1`] = `
<div
aria-label="aria-label"
class="kuiModalBody testClass1 testClass2"
data-test-subj="test subject string"
>
children
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders KuiModalBodyText 1`] = `
<div
aria-label="aria-label"
class="kuiModalBodyText testClass1 testClass2"
data-test-subj="test subject string"
>
children
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders KuiModalFooter 1`] = `
<div
aria-label="aria-label"
class="kuiModalFooter testClass1 testClass2"
data-test-subj="test subject string"
>
children
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders KuiModalHeader 1`] = `
<div
aria-label="aria-label"
class="kuiModalHeader testClass1 testClass2"
data-test-subj="test subject string"
>
children
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders KuiModalHeaderTitle 1`] = `
<div
aria-label="aria-label"
class="kuiModalHeader__title testClass1 testClass2"
data-test-subj="test subject string"
>
children
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders KuiModalOverlay 1`] = `
<div
aria-label="aria-label"
class="kuiModalOverlay testClass1 testClass2"
data-test-subj="test subject string"
>
children
</div>
`;
1 change: 1 addition & 0 deletions ui_framework/components/modal/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ $modalPadding: 10px;
$modalBorderColor: #6EADC1;
$modalBackgroundColor: #FFF;
$modalOverlayBackground: rgba(#000000, 0.3);
$globalModalDepth: 1000;

@import "modal_overlay";
@import "modal";
1 change: 1 addition & 0 deletions ui_framework/components/modal/_modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
border: 1px solid $modalBorderColor;
border-radius: $globalBorderRadius;
box-shadow: 0 5px 22px rgba(#000000, 0.25);
z-index: $globalModalDepth + 1;
}

.kuiModalHeader {
Expand Down
2 changes: 1 addition & 1 deletion ui_framework/components/modal/_modal_overlay.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.kuiModalOverlay {
position: fixed;
z-index: 1000;
z-index: $globalModalDepth;
top: 0;
left: 0;
right: 0;
Expand Down
75 changes: 75 additions & 0 deletions ui_framework/components/modal/confirm_modal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react';
import PropTypes from 'prop-types';

import { KuiModal } from './modal';
import { KuiModalFooter } from './modal_footer';
import { KuiModalHeader } from './modal_header';
import { KuiModalHeaderTitle } from './modal_header_title';
import { KuiModalBody } from './modal_body';
import { KuiModalBodyText } from './modal_body_text';
import { KuiButton } from '../index';

export function KuiConfirmModal({
message,
title,
onCancel,
onConfirm,
cancelButtonText,
confirmButtonText,
className,
...rest }) {
const ariaLabel = rest['aria-label'];
const dataTestSubj = rest['data-test-subj'];
return (
<KuiModal
style={{ 'width': '450px' }}
data-tests-subj={ dataTestSubj }
aria-label={ ariaLabel }
className={ className }
>
{
title ?
<KuiModalHeader>
<KuiModalHeaderTitle data-test-subj="confirmModalTitleText">
{ title }
</KuiModalHeaderTitle>
</KuiModalHeader>
: null
}
<KuiModalBody>
<KuiModalBodyText data-test-subj="confirmModalBodyText">
{ message }
</KuiModalBodyText>
</KuiModalBody>

<KuiModalFooter>
<KuiButton
type="hollow"
data-test-subj="confirmModalCancelButton"
onClick={ onCancel }
>
{cancelButtonText}
</KuiButton>
<KuiButton
type="primary"
data-test-subj="confirmModalConfirmButton"
onClick={ onConfirm }
>
{confirmButtonText}
</KuiButton>
</KuiModalFooter>
</KuiModal>
);
}

KuiConfirmModal.propTypes = {
message: PropTypes.string,
title: PropTypes.string,
cancelButtonText: PropTypes.string,
confirmButtonText: PropTypes.string,
onCancel: PropTypes.func,
onConfirm: PropTypes.func,
dataTestSubj: PropTypes.string,
ariaLabel: PropTypes.string,
className: PropTypes.string,
};
Loading

0 comments on commit 7e74b2d

Please sign in to comment.