Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show alert upon closing modal via escape keypress; partially close #2613. #2704

Merged
merged 8 commits into from
Apr 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions assets/src/application/services/utilities/dom/canUseDOM.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);

export default canUseDOM;
1 change: 1 addition & 0 deletions assets/src/application/services/utilities/dom/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as canUseDOM } from './canUseDOM';
export { default as getHTMLElementClientRect } from './getHTMLElementClientRect';
6 changes: 3 additions & 3 deletions assets/src/application/ui/display/confirm/useConfirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { Button as ButtonAdapter } from '@infraUI/inputs';

import { ConfirmProps } from './types';

const useConfirm: React.FC<ConfirmProps> = ({ children, buttonProps, onConfirm, title }) => {
const useConfirm: React.FC<ConfirmProps> = ({ buttonProps, onConfirm, title }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = React.useRef();
const onDelete = useCallback(() => {
const onClickHandler = useCallback(() => {
if (typeof onConfirm === 'function') {
onConfirm();
}
Expand All @@ -27,7 +27,7 @@ const useConfirm: React.FC<ConfirmProps> = ({ children, buttonProps, onConfirm,
header={buttonProps?.tooltip}
isOpen={isOpen}
leastDestructiveRef={cancelRef}
okButton={<ButtonAdapter buttonText={__('Yes')} variantColor='red' onClick={onDelete} ml={3} />}
okButton={<ButtonAdapter buttonText={__('Yes')} variantColor='red' onClick={onClickHandler} ml={3} />}
onClose={onClose}
title={title}
/>
Expand Down
21 changes: 6 additions & 15 deletions assets/src/application/ui/forms/modalForm/RenderModalForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { __ } from '@wordpress/i18n';
import { SaveOutlined } from '@ant-design/icons';

import { ButtonProps } from '@infraUI/inputs';
import { Close } from '@appDisplay/icons';
import { ConfirmClose } from '@appDisplay/confirm';
import { Modal } from '@infraUI/layout/modal';
import { ModalWithAlert } from '@appLayout/modal';
import { modalCloseButtonProps } from '@infraUI/layout/modal';

import { RenderModalFormProps } from './types';

Expand All @@ -32,16 +32,7 @@ const RenderModalForm: React.FC<RenderModalFormProps> = ({

const onReset = useCallback(() => form.reset(), [form.reset]);

const closeButton = (
<ConfirmClose
buttonProps={{
className: 'confirm-close',
icon: Close,
variant: 'unstyled',
}}
onConfirm={onClose}
/>
);
const closeButton = !pristine && <ConfirmClose buttonProps={modalCloseButtonProps} onConfirm={onClose} />;

const submitButtonProps: ButtonProps = useMemo(
() => ({
Expand All @@ -66,19 +57,19 @@ const RenderModalForm: React.FC<RenderModalFormProps> = ({
);

return (
<Modal
<ModalWithAlert
bodyClassName='ee-modal-form__body'
cancelButtonProps={resetButtonProps}
className='ee-modal-form'
closeButton={closeButton}
closeOnEsc={pristine}
isOpen={true}
onClose={onClose}
showAlertOnEscape={!pristine}
submitButtonProps={submitButtonProps}
title={title}
>
{children}
</Modal>
</ModalWithAlert>
);
};

Expand Down
12 changes: 0 additions & 12 deletions assets/src/application/ui/forms/modalForm/styles.scss
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
.ee-modal-form {
max-width: 75rem !important;
.confirm-close {
display: inline-flex;
position: absolute;
top: 8px;
right: 12px;
min-width: auto;
width: var(--ee-padding-big);
height: var(--ee-padding-big);
svg {
margin: 0;
}
}
}
1 change: 1 addition & 0 deletions assets/src/application/ui/layout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export * from './formModal';
export * from './entityActionsMenu';
export * from './entityList';
export * from './dropdownMenu';

export { default as EntityPaperFrame } from './EntityPaperFrame';
63 changes: 63 additions & 0 deletions assets/src/application/ui/layout/modal/ModalWithAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { useEffect } from 'react';
import { useDisclosure } from '@chakra-ui/core';
import { __ } from '@wordpress/i18n';
import { canUseDOM } from '@appServices/utilities/dom';
import { ESCAPE } from '@wordpress/keycodes';

import { AlertDialog } from '@infraUI/display';
import { Button as ButtonAdapter } from '@infraUI/inputs';
import { Modal, ModalProps } from '@infraUI/layout/modal';

interface Props extends ModalProps {
cancelBtnText?: string;
header?: string;
okBtnText?: string;
showAlertOnEscape: boolean;
}

const ModalWithAlert: React.FC<Props> = ({ children, showAlertOnEscape, ...props }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = React.useRef();
const cancelBtnText = props.cancelBtnText || __('No');
const header = props.header || __('Are you sure you want to close this?');
const okBtnText = props.okBtnText || __('Yes');
const onEscape = ({ keyCode }): void => {
if (keyCode === ESCAPE) {
onOpen();
}
};

useEffect(() => {
if (canUseDOM) {
document.addEventListener('keydown', onEscape);
}

return () => {
if (canUseDOM) {
document.removeEventListener('keydown', onEscape);
}
};
}, []);

return (
<>
<Modal {...props} closeOnEsc={!showAlertOnEscape}>
{children}
</Modal>
{showAlertOnEscape && (
<AlertDialog
cancelButton={<ButtonAdapter buttonText={cancelBtnText} ref={cancelRef} onClick={onClose} />}
header={header}
isOpen={isOpen}
leastDestructiveRef={cancelRef}
okButton={
<ButtonAdapter buttonText={okBtnText} variantColor='red' onClick={props.onClose} ml={3} />
}
onClose={onClose}
/>
)}
</>
);
};

export default ModalWithAlert;
1 change: 1 addition & 0 deletions assets/src/application/ui/layout/modal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as ModalWithAlert } from './ModalWithAlert';

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { useCallback } from 'react';
import { __ } from '@wordpress/i18n';

import { ConfirmClose } from '@appDisplay/confirm';
import { modalCloseButtonProps } from '@infraUI/layout/modal';
import { useTAMContext } from '../../../context';

const CloseModal: React.FC = () => {
const { dataState, onCloseModal } = useTAMContext();

const { hasOrphanEntities } = dataState;

const hasErrors = hasOrphanEntities();

const onConfirm = useCallback(onCloseModal, [hasErrors]);

return hasErrors ? <ConfirmClose buttonProps={modalCloseButtonProps} onConfirm={onConfirm} /> : null;
};

export default React.memo(CloseModal);
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useCallback, useMemo } from 'react';
import { __ } from '@wordpress/i18n';

import { ButtonProps } from '@infraUI/inputs';
import { useTAMContext } from '../context';
import { useTAMContext } from '../../../context';

const useCancelButtonProps = (): ButtonProps => {
const { dataState, onCloseModal } = useTAMContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { useCallback, useMemo } from 'react';
import { __ } from '@wordpress/i18n';

import { ButtonProps } from '@infraUI/inputs';
import { useOnSubmitAssignments } from '../data';
import { useTAMContext } from '../context';
import { useOnSubmitAssignments } from '../../../data';
import { useTAMContext } from '../../../context';

const useSubmitButtonProps = (): ButtonProps => {
const { dataState, onCloseModal } = useTAMContext();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { __ } from '@wordpress/i18n';

import { ModalWithAlert } from '@appLayout/modal';

import CloseModalButton from './buttons/CloseModal';
import TicketAssignmentsManager from '../TicketAssignmentsManager';
import useCancelButtonProps from './buttons/useCancelButtonProps';
import useSubmitButtonProps from './buttons/useSubmitButtonProps';
import { useTAMContext } from '../../context';

import '../styles.scss';

const TicketAssignmentsManagerModal: React.FC = () => {
const {
dataState: { hasOrphanEntities },
onCloseModal,
title,
} = useTAMContext();
const cancelButtonProps = useCancelButtonProps();
const submitButtonProps = useSubmitButtonProps();

const hasErrors = hasOrphanEntities();

return (
<ModalWithAlert
bodyClassName='ee-ticket-assignments-manager__body'
cancelButtonProps={cancelButtonProps}
className='ee-ticket-assignments-manager'
closeButton={<CloseModalButton />}
isOpen={true}
onClose={onCloseModal}
showAlertOnEscape={hasErrors}
submitButtonProps={submitButtonProps}
title={title || __('Ticket Assignment Manager')}
>
<TicketAssignmentsManager />
</ModalWithAlert>
);
};

export default TicketAssignmentsManagerModal;
1 change: 1 addition & 0 deletions assets/src/infrastructure/ui/layout/modal/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as Modal } from './Modal';
export { default as modalCloseButtonProps } from './modalCloseButtonProps';

export * from './types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { __ } from '@wordpress/i18n';

import { ButtonProps } from '@infraUI/inputs';
import { Close } from '@appDisplay/icons';

import './styles.scss';

const modalCloseButtonProps: ButtonProps = {
className: 'ee-confirm-close',
icon: Close,
variant: 'unstyled',
};

export default modalCloseButtonProps;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// this selector is used for specificity
[role='alertdialog'] {
.ee-confirm-close {
display: inline-flex;
position: absolute;
top: 8px;
right: 12px;
min-width: auto;
width: var(--ee-padding-big);
height: var(--ee-padding-big);
svg {
height: var(--ee-border-radius-big);
margin: 0;
width: var(--ee-border-radius-big);
}
Comment on lines +11 to +15
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this better:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed --ee-border-radius-big to match 12px which is the same dimension as in chakra.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open to better variable names than --ee-border-radius-big

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ya I'll most likely tweak things once everything is converted, but that doesn't look bad as is

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
},
"devDependencies": {
"@apollo/react-testing": "^3.1.4",
"@babel/compat-data": "^7.9.0",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this temporary, to make this failing pass:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I wrote in another comment, this non-sense will be removed/ adjusted here: #2609

"@babel/core": "^7.9.0",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.9.0",
Expand Down