mirror of
https://github.com/ansible/awx.git
synced 2026-05-15 21:37:42 -02:30
Simplify kebab modal open logic
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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', () => {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user