Simplify kebab modal open logic

This commit is contained in:
mabashian
2020-09-10 15:31:32 -04:00
parent 0fc6affe85
commit 130a43f5c4
5 changed files with 43 additions and 33 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
@@ -42,15 +42,21 @@ function DataListToolbar({
pagination, pagination,
}) { }) {
const showExpandCollapse = onCompact && onExpand; const showExpandCollapse = onCompact && onExpand;
const [kebabIsOpen, setKebabIsOpen] = useState(false); const [isKebabOpen, setIsKebabOpen] = useState(false);
const [kebabModalIsOpen, setKebabModalIsOpen] = useState(false); const [isKebabModalOpen, setIsKebabModalOpen] = useState(false);
const [advancedSearchShown, setAdvancedSearchShown] = useState(false); const [isAdvancedSearchShown, setIsAdvancedSearchShown] = useState(false);
const onShowAdvancedSearch = shown => { const onShowAdvancedSearch = shown => {
setAdvancedSearchShown(shown); setIsAdvancedSearchShown(shown);
setKebabIsOpen(false); setIsKebabOpen(false);
}; };
useEffect(() => {
if (!isKebabModalOpen) {
setIsKebabOpen(false);
}
}, [isKebabModalOpen]);
return ( return (
<Toolbar <Toolbar
id={`${qsConfig.namespace}-list-toolbar`} id={`${qsConfig.namespace}-list-toolbar`}
@@ -103,44 +109,39 @@ function DataListToolbar({
</> </>
</ToolbarGroup> </ToolbarGroup>
)} )}
{advancedSearchShown && ( {isAdvancedSearchShown && (
<ToolbarItem> <ToolbarItem>
<KebabifiedProvider <KebabifiedProvider
value={{ value={{
isKebabified: true, isKebabified: true,
onKebabModalChange: isOpen => { onKebabModalChange: setIsKebabModalOpen,
if (kebabIsOpen && kebabModalIsOpen && !isOpen) {
setKebabIsOpen(false);
}
setKebabModalIsOpen(isOpen);
},
}} }}
> >
<Dropdown <Dropdown
toggle={ toggle={
<KebabToggle <KebabToggle
onToggle={isOpen => { onToggle={isOpen => {
if (!kebabModalIsOpen) { if (!isKebabModalOpen) {
setKebabIsOpen(isOpen); setIsKebabOpen(isOpen);
} }
}} }}
/> />
} }
isOpen={kebabIsOpen || kebabModalIsOpen} isOpen={isKebabOpen}
isPlain isPlain
dropdownItems={additionalControls} dropdownItems={additionalControls}
/> />
</KebabifiedProvider> </KebabifiedProvider>
</ToolbarItem> </ToolbarItem>
)} )}
{!advancedSearchShown && ( {!isAdvancedSearchShown && (
<ToolbarGroup> <ToolbarGroup>
{additionalControls.map(control => ( {additionalControls.map(control => (
<ToolbarItem key={control.key}>{control}</ToolbarItem> <ToolbarItem key={control.key}>{control}</ToolbarItem>
))} ))}
</ToolbarGroup> </ToolbarGroup>
)} )}
{!advancedSearchShown && pagination && itemCount > 0 && ( {!isAdvancedSearchShown && pagination && itemCount > 0 && (
<ToolbarItem variant="pagination">{pagination}</ToolbarItem> <ToolbarItem variant="pagination">{pagination}</ToolbarItem>
)} )}
</ToolbarContent> </ToolbarContent>

View File

@@ -1,4 +1,4 @@
import React, { useContext, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { arrayOf, func } from 'prop-types'; import { arrayOf, func } from 'prop-types';
@@ -23,12 +23,15 @@ function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
}; };
const toggleModal = () => { const toggleModal = () => {
if (isKebabified) {
onKebabModalChange(!isModalOpen);
}
setIsModalOpen(!isModalOpen); setIsModalOpen(!isModalOpen);
}; };
useEffect(() => {
if (isKebabified) {
onKebabModalChange(isModalOpen);
}
}, [isKebabified, isModalOpen, onKebabModalChange]);
const renderTooltip = () => { const renderTooltip = () => {
const jobsUnableToCancel = jobsToCancel const jobsUnableToCancel = jobsToCancel
.filter(cannotCancel) .filter(cannotCancel)

View File

@@ -1,4 +1,4 @@
import React, { useContext, useState } from 'react'; import React, { useContext, useEffect, useState } from 'react';
import { import {
func, func,
bool, bool,
@@ -75,12 +75,15 @@ function ToolbarDeleteButton({
}; };
const toggleModal = () => { const toggleModal = () => {
if (isKebabified) {
onKebabModalChange(!isModalOpen);
}
setIsModalOpen(!isModalOpen); setIsModalOpen(!isModalOpen);
}; };
useEffect(() => {
if (isKebabified) {
onKebabModalChange(isModalOpen);
}
}, [isKebabified, isModalOpen, onKebabModalChange]);
const renderTooltip = () => { const renderTooltip = () => {
const itemsUnableToDelete = itemsToDelete const itemsUnableToDelete = itemsToDelete
.filter(cannotDelete) .filter(cannotDelete)

View File

@@ -26,8 +26,8 @@ describe('<ToolbarDeleteButton />', () => {
const wrapper = mountWithContexts( const wrapper = mountWithContexts(
<ToolbarDeleteButton onDelete={() => {}} itemsToDelete={[itemA]} /> <ToolbarDeleteButton onDelete={() => {}} itemsToDelete={[itemA]} />
); );
expect(wrapper.find('Modal')).toHaveLength(0);
wrapper.find('button').simulate('click'); wrapper.find('button').simulate('click');
expect(wrapper.find('ToolbarDeleteButton').state('isModalOpen')).toBe(true);
wrapper.update(); wrapper.update();
expect(wrapper.find('Modal')).toHaveLength(1); expect(wrapper.find('Modal')).toHaveLength(1);
}); });
@@ -37,15 +37,14 @@ describe('<ToolbarDeleteButton />', () => {
const wrapper = mountWithContexts( const wrapper = mountWithContexts(
<ToolbarDeleteButton onDelete={onDelete} itemsToDelete={[itemA]} /> <ToolbarDeleteButton onDelete={onDelete} itemsToDelete={[itemA]} />
); );
wrapper.find('ToolbarDeleteButton').setState({ isModalOpen: true }); wrapper.find('button').simulate('click');
wrapper.update(); wrapper.update();
wrapper wrapper
.find('ModalBoxFooter button[aria-label="confirm delete"]') .find('ModalBoxFooter button[aria-label="confirm delete"]')
.simulate('click'); .simulate('click');
wrapper.update();
expect(onDelete).toHaveBeenCalled(); expect(onDelete).toHaveBeenCalled();
expect(wrapper.find('ToolbarDeleteButton').state('isModalOpen')).toBe( expect(wrapper.find('Modal')).toHaveLength(0);
false
);
}); });
test('should disable button when no delete permissions', () => { test('should disable button when no delete permissions', () => {

View File

@@ -261,7 +261,9 @@ describe('<TemplateList />', () => {
}, },
}); });
wrapper.find('button[aria-label="Delete"]').prop('onClick')(); await act(async () => {
wrapper.find('button[aria-label="Delete"]').prop('onClick')();
});
wrapper.update(); wrapper.update();
await act(async () => { await act(async () => {
await wrapper await wrapper
@@ -302,7 +304,9 @@ describe('<TemplateList />', () => {
summary_fields: { user_capabilities: { delete: true } }, summary_fields: { user_capabilities: { delete: true } },
}, },
}); });
wrapper.find('button[aria-label="Delete"]').prop('onClick')(); await act(async () => {
wrapper.find('button[aria-label="Delete"]').prop('onClick')();
});
wrapper.update(); wrapper.update();
await act(async () => { await act(async () => {
await wrapper await wrapper