Dependabot/npm and yarn/kafka UI react app/eslint plugin react 7.30.1 (#2232)

* Bump eslint-plugin-react from 7.29.4 to 7.30.1 in /kafka-ui-react-app

Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.29.4 to 7.30.1.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.29.4...v7.30.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-react
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* taking ActionsCell out of List

* removing package-lock

* refactoring props

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
Robert Azizbekyan 2022-07-19 18:53:07 +04:00 committed by GitHub
parent 96b00785b5
commit 30f836645d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 148 additions and 184 deletions

View file

@ -104,7 +104,7 @@
"eslint-plugin-jest-dom": "^4.0.2",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.29.4",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.5.0",
"fetch-mock-jest": "^1.5.1",
"husky": "^8.0.1",

View file

@ -50,7 +50,7 @@ specifiers:
eslint-plugin-jest-dom: ^4.0.2
eslint-plugin-jsx-a11y: ^6.5.1
eslint-plugin-prettier: ^4.0.0
eslint-plugin-react: ^7.29.4
eslint-plugin-react: ^7.30.1
eslint-plugin-react-hooks: ^4.5.0
fetch-mock: ^9.11.0
fetch-mock-jest: ^1.5.1
@ -155,7 +155,7 @@ devDependencies:
'@typescript-eslint/parser': 5.29.0_vjep2yp2sits3sqnodefgcbnfi
dotenv: 16.0.1
eslint: 8.16.0
eslint-config-airbnb: 19.0.4_pamhosqcenlxoxj4ke2dmvzava
eslint-config-airbnb: 19.0.4_iayhaebzx3saen2ll7sn5gqmdq
eslint-config-airbnb-typescript: 17.0.0_l6wia5brkiej5f4nhesunbzj5y
eslint-config-prettier: 8.5.0_eslint@8.16.0
eslint-config-react-app: 7.0.1_y3w6q4zxtal6gz5auqli3lo3ny
@ -165,7 +165,7 @@ devDependencies:
eslint-plugin-jest-dom: 4.0.2_eslint@8.16.0
eslint-plugin-jsx-a11y: 6.5.1_eslint@8.16.0
eslint-plugin-prettier: 4.0.0_q7a4ir2sdihdzpzdlnbgmzjlpq
eslint-plugin-react: 7.29.4_eslint@8.16.0
eslint-plugin-react: 7.30.1_eslint@8.16.0
eslint-plugin-react-hooks: 4.5.0_eslint@8.16.0
fetch-mock-jest: 1.5.1
husky: 8.0.1
@ -4208,7 +4208,7 @@ packages:
eslint-plugin-import: 2.26.0_h5azci6ujakbaa2xblg2jlxooy
dev: true
/eslint-config-airbnb/19.0.4_pamhosqcenlxoxj4ke2dmvzava:
/eslint-config-airbnb/19.0.4_iayhaebzx3saen2ll7sn5gqmdq:
resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==}
engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -4222,7 +4222,7 @@ packages:
eslint-config-airbnb-base: 15.0.0_btspkuwbqkl4adpiufzbathtpi
eslint-plugin-import: 2.26.0_h5azci6ujakbaa2xblg2jlxooy
eslint-plugin-jsx-a11y: 6.5.1_eslint@8.16.0
eslint-plugin-react: 7.29.4_eslint@8.16.0
eslint-plugin-react: 7.30.1_eslint@8.16.0
eslint-plugin-react-hooks: 4.5.0_eslint@8.16.0
object.assign: 4.1.2
object.entries: 1.1.5
@ -4259,7 +4259,7 @@ packages:
eslint-plugin-import: 2.26.0_h5azci6ujakbaa2xblg2jlxooy
eslint-plugin-jest: 25.7.0_lemdnf4suuyhpl5s2mhp2xyjqi
eslint-plugin-jsx-a11y: 6.5.1_eslint@8.16.0
eslint-plugin-react: 7.29.4_eslint@8.16.0
eslint-plugin-react: 7.30.1_eslint@8.16.0
eslint-plugin-react-hooks: 4.5.0_eslint@8.16.0
eslint-plugin-testing-library: 5.5.0_vjep2yp2sits3sqnodefgcbnfi
typescript: 4.7.4
@ -4455,8 +4455,8 @@ packages:
eslint: 8.16.0
dev: true
/eslint-plugin-react/7.29.4_eslint@8.16.0:
resolution: {integrity: sha512-CVCXajliVh509PcZYRFyu/BoUEz452+jtQJq2b3Bae4v3xBUWPLCmtmBM+ZinG4MzwmxJgJ2M5rMqhqLVn7MtQ==}
/eslint-plugin-react/7.30.1_eslint@8.16.0:
resolution: {integrity: sha512-NbEvI9jtqO46yJA3wcRF9Mo0lF9T/jhdHqhCHXiXtD+Zcb98812wvokjWpU7Q4QH5edo6dmqrukxVvWWXHlsUg==}
engines: {node: '>=4'}
peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
@ -4475,7 +4475,7 @@ packages:
prop-types: 15.8.1
resolve: 2.0.0-next.3
semver: 6.3.0
string.prototype.matchall: 4.0.6
string.prototype.matchall: 4.0.7
dev: true
/eslint-plugin-testing-library/5.5.0_vjep2yp2sits3sqnodefgcbnfi:
@ -7206,8 +7206,8 @@ packages:
strip-ansi: 7.0.1
dev: true
/string.prototype.matchall/4.0.6:
resolution: {integrity: sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==}
/string.prototype.matchall/4.0.7:
resolution: {integrity: sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==}
dependencies:
call-bind: 1.0.2
define-properties: 1.1.4

View file

@ -0,0 +1,131 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import {
CleanUpPolicy,
SortOrder,
TopicColumnsToSort,
} from 'generated-sources';
import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
import DropdownItem from 'components/common/Dropdown/DropdownItem';
import { TableCellProps } from 'components/common/SmartTable/TableColumn';
import { TopicWithDetailedInfo } from 'redux/interfaces';
import VerticalElipsisIcon from 'components/common/Icons/VerticalElipsisIcon';
import Dropdown from 'components/common/Dropdown/Dropdown';
import ClusterContext from 'components/contexts/ClusterContext';
import * as S from 'components/Topics/List/List.styled';
import { ClusterNameRoute } from 'lib/paths';
import useModal from 'lib/hooks/useModal';
import useAppParams from 'lib/hooks/useAppParams';
import {
deleteTopic,
fetchTopicsList,
recreateTopic,
} from 'redux/reducers/topics/topicsSlice';
import { clearTopicMessages } from 'redux/reducers/topicMessages/topicMessagesSlice';
interface TopicsListParams {
clusterName: string;
page?: number;
perPage?: number;
showInternal?: boolean;
search?: string;
orderBy?: TopicColumnsToSort;
sortOrder?: SortOrder;
}
export interface ActionsCellProps {
topicsListParams: TopicsListParams;
}
const ActionsCell: React.FC<
TableCellProps<TopicWithDetailedInfo, string> & ActionsCellProps
> = ({
hovered,
dataItem: { internal, cleanUpPolicy, name },
topicsListParams,
}) => {
const { isReadOnly, isTopicDeletionAllowed } =
React.useContext(ClusterContext);
const dispatch = useDispatch();
const { clusterName } = useAppParams<ClusterNameRoute>();
const {
isOpen: isDeleteTopicModalOpen,
setClose: closeDeleteTopicModal,
setOpen: openDeleteTopicModal,
} = useModal(false);
const {
isOpen: isRecreateTopicModalOpen,
setClose: closeRecreateTopicModal,
setOpen: openRecreateTopicModal,
} = useModal(false);
const {
isOpen: isClearMessagesModalOpen,
setClose: closeClearMessagesModal,
setOpen: openClearMessagesModal,
} = useModal(false);
const isHidden = internal || isReadOnly || !hovered;
const deleteTopicHandler = () =>
dispatch(deleteTopic({ clusterName, topicName: name }));
const clearTopicMessagesHandler = () => {
dispatch(clearTopicMessages({ clusterName, topicName: name }));
dispatch(fetchTopicsList(topicsListParams));
closeClearMessagesModal();
};
const recreateTopicHandler = () => {
dispatch(recreateTopic({ clusterName, topicName: name }));
closeRecreateTopicModal();
};
return (
<>
<S.ActionsContainer>
{!isHidden && (
<Dropdown label={<VerticalElipsisIcon />} right>
{cleanUpPolicy === CleanUpPolicy.DELETE && (
<DropdownItem onClick={openClearMessagesModal} danger>
Clear Messages
</DropdownItem>
)}
{isTopicDeletionAllowed && (
<DropdownItem onClick={openDeleteTopicModal} danger>
Remove Topic
</DropdownItem>
)}
<DropdownItem onClick={openRecreateTopicModal} danger>
Recreate Topic
</DropdownItem>
</Dropdown>
)}
</S.ActionsContainer>
<ConfirmationModal
isOpen={isClearMessagesModalOpen}
onCancel={closeClearMessagesModal}
onConfirm={clearTopicMessagesHandler}
>
Are you sure want to clear topic messages?
</ConfirmationModal>
<ConfirmationModal
isOpen={isDeleteTopicModalOpen}
onCancel={closeDeleteTopicModal}
onConfirm={deleteTopicHandler}
>
Are you sure want to remove <b>{name}</b> topic?
</ConfirmationModal>
<ConfirmationModal
isOpen={isRecreateTopicModalOpen}
onCancel={closeRecreateTopicModal}
onConfirm={recreateTopicHandler}
>
Are you sure to recreate <b>{name}</b> topic?
</ConfirmationModal>
</>
);
};
export default React.memo(ActionsCell);

View file

@ -12,15 +12,11 @@ import {
clusterTopicNewRelativePath,
} from 'lib/paths';
import usePagination from 'lib/hooks/usePagination';
import useModal from 'lib/hooks/useModal';
import ClusterContext from 'components/contexts/ClusterContext';
import PageLoader from 'components/common/PageLoader/PageLoader';
import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
import {
CleanUpPolicy,
DeleteTopicRequest,
GetTopicsRequest,
RecreateTopicRequest,
SortOrder,
TopicColumnsToSort,
} from 'generated-sources';
@ -31,14 +27,8 @@ import PageHeading from 'components/common/PageHeading/PageHeading';
import { ControlPanelWrapper } from 'components/common/ControlPanel/ControlPanel.styled';
import Switch from 'components/common/Switch/Switch';
import { SmartTable } from 'components/common/SmartTable/SmartTable';
import {
TableCellProps,
TableColumn,
} from 'components/common/SmartTable/TableColumn';
import { TableColumn } from 'components/common/SmartTable/TableColumn';
import { useTableState } from 'lib/hooks/useTableState';
import Dropdown from 'components/common/Dropdown/Dropdown';
import VerticalElipsisIcon from 'components/common/Icons/VerticalElipsisIcon';
import DropdownItem from 'components/common/Dropdown/DropdownItem';
import {
MessagesCell,
@ -47,18 +37,17 @@ import {
TopicSizeCell,
} from './TopicsTableCells';
import * as S from './List.styled';
import ActionsCell from './ActionsCell/ActionsCell';
export interface TopicsListProps {
areTopicsFetching: boolean;
topics: TopicWithDetailedInfo[];
totalPages: number;
fetchTopicsList(payload: GetTopicsRequest): void;
deleteTopic(payload: DeleteTopicRequest): void;
deleteTopics(payload: {
clusterName: ClusterName;
topicNames: TopicName[];
}): void;
recreateTopic(payload: RecreateTopicRequest): void;
clearTopicsMessages(payload: {
clusterName: ClusterName;
topicNames: TopicName[];
@ -80,10 +69,7 @@ const List: React.FC<TopicsListProps> = ({
topics,
totalPages,
fetchTopicsList,
deleteTopic,
deleteTopics,
recreateTopic,
clearTopicMessages,
clearTopicsMessages,
search,
orderBy,
@ -91,8 +77,7 @@ const List: React.FC<TopicsListProps> = ({
setTopicsSearch,
setTopicsOrderBy,
}) => {
const { isReadOnly, isTopicDeletionAllowed } =
React.useContext(ClusterContext);
const { isReadOnly } = React.useContext(ClusterContext);
const { clusterName } = useAppParams<ClusterNameRoute>();
const { page, perPage } = usePagination();
const [showInternal, setShowInternal] = React.useState<boolean>(
@ -197,89 +182,6 @@ const List: React.FC<TopicsListProps> = ({
fetchTopicsList(topicsListParams);
};
const ActionsCell = React.memo<TableCellProps<TopicWithDetailedInfo, string>>(
({ hovered, dataItem: { internal, cleanUpPolicy, name } }) => {
const {
isOpen: isDeleteTopicModalOpen,
setClose: closeDeleteTopicModal,
setOpen: openDeleteTopicModal,
} = useModal(false);
const {
isOpen: isRecreateTopicModalOpen,
setClose: closeRecreateTopicModal,
setOpen: openRecreateTopicModal,
} = useModal(false);
const {
isOpen: isClearMessagesModalOpen,
setClose: closeClearMessagesModal,
setOpen: openClearMessagesModal,
} = useModal(false);
const isHidden = internal || isReadOnly || !hovered;
const deleteTopicHandler = () =>
deleteTopic({ clusterName, topicName: name });
const clearTopicMessagesHandler = () => {
clearTopicMessages({ clusterName, topicName: name });
fetchTopicsList(topicsListParams);
closeClearMessagesModal();
};
const recreateTopicHandler = () => {
recreateTopic({ clusterName, topicName: name });
closeRecreateTopicModal();
};
return (
<>
<S.ActionsContainer>
{!isHidden && (
<Dropdown label={<VerticalElipsisIcon />} right>
{cleanUpPolicy === CleanUpPolicy.DELETE && (
<DropdownItem onClick={openClearMessagesModal} danger>
Clear Messages
</DropdownItem>
)}
{isTopicDeletionAllowed && (
<DropdownItem onClick={openDeleteTopicModal} danger>
Remove Topic
</DropdownItem>
)}
<DropdownItem onClick={openRecreateTopicModal} danger>
Recreate Topic
</DropdownItem>
</Dropdown>
)}
</S.ActionsContainer>
<ConfirmationModal
isOpen={isClearMessagesModalOpen}
onCancel={closeClearMessagesModal}
onConfirm={clearTopicMessagesHandler}
>
Are you sure want to clear topic messages?
</ConfirmationModal>
<ConfirmationModal
isOpen={isDeleteTopicModalOpen}
onCancel={closeDeleteTopicModal}
onConfirm={deleteTopicHandler}
>
Are you sure want to remove <b>{name}</b> topic?
</ConfirmationModal>
<ConfirmationModal
isOpen={isRecreateTopicModalOpen}
onCancel={closeRecreateTopicModal}
onConfirm={recreateTopicHandler}
>
Are you sure to recreate <b>{name}</b> topic?
</ConfirmationModal>
</>
);
}
);
return (
<div>
<div>

View file

@ -3,8 +3,6 @@ import { RootState } from 'redux/interfaces';
import { clearTopicMessages } from 'redux/reducers/topicMessages/topicMessagesSlice';
import {
fetchTopicsList,
deleteTopic,
recreateTopic,
setTopicsSearch,
setTopicsOrderBy,
deleteTopics,
@ -32,9 +30,7 @@ const mapStateToProps = (state: RootState) => ({
const mapDispatchToProps = {
fetchTopicsList,
deleteTopic,
deleteTopics,
recreateTopic,
clearTopicsMessages,
clearTopicMessages,
setTopicsSearch,

View file

@ -27,11 +27,9 @@ describe('List', () => {
topics={[]}
totalPages={1}
fetchTopicsList={jest.fn()}
deleteTopic={jest.fn()}
deleteTopics={jest.fn()}
clearTopicsMessages={jest.fn()}
clearTopicMessages={jest.fn()}
recreateTopic={jest.fn()}
search=""
orderBy={null}
sortOrder={SortOrder.ASC}
@ -174,10 +172,8 @@ describe('List', () => {
describe('when some list items are selected', () => {
const mockDeleteTopics = jest.fn();
const mockDeleteTopic = jest.fn();
const mockClearTopic = jest.fn();
const mockClearTopicsMessages = jest.fn();
const mockRecreate = jest.fn();
const fetchTopicsList = jest.fn();
jest.useFakeTimers();
@ -204,8 +200,6 @@ describe('List', () => {
],
deleteTopics: mockDeleteTopics,
clearTopicsMessages: mockClearTopicsMessages,
recreateTopic: mockRecreate,
deleteTopic: mockDeleteTopic,
clearTopicMessages: mockClearTopic,
fetchTopicsList,
})}
@ -218,8 +212,6 @@ describe('List', () => {
afterEach(() => {
mockDeleteTopics.mockClear();
mockClearTopicsMessages.mockClear();
mockRecreate.mockClear();
mockDeleteTopic.mockClear();
});
const getCheckboxInput = (at: number) => {
@ -335,63 +327,5 @@ describe('List', () => {
expect(mockDeleteTopics).not.toHaveBeenCalled();
});
const tableRowActionClickAndCheck = async (
action: 'deleteTopics' | 'clearTopicsMessages' | 'recreate'
) => {
const row = screen.getAllByRole('row')[1];
userEvent.hover(row);
const actionBtn = within(row).getByRole('menu', { hidden: true });
userEvent.click(actionBtn);
let textBtn;
let mock: jest.Mock;
if (action === 'clearTopicsMessages') {
textBtn = 'Clear Messages';
mock = mockClearTopic;
} else if (action === 'deleteTopics') {
textBtn = 'Remove Topic';
mock = mockDeleteTopic;
} else {
textBtn = 'Recreate Topic';
mock = mockRecreate;
}
const ourAction = screen.getByText(textBtn);
userEvent.click(ourAction);
let dialog = screen.getByRole('dialog');
expect(dialog).toBeInTheDocument();
userEvent.click(within(dialog).getByRole('button', { name: 'Submit' }));
await waitFor(() => {
expect(mock).toHaveBeenCalled();
if (action === 'clearTopicsMessages') {
expect(fetchTopicsList).toHaveBeenCalled();
}
});
userEvent.click(ourAction);
dialog = screen.getByRole('dialog');
expect(dialog).toBeInTheDocument();
userEvent.click(within(dialog).getByRole('button', { name: 'Cancel' }));
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
expect(mock).toHaveBeenCalledTimes(1);
};
it('should test the actions of the row and their modal and fetching for removing', async () => {
await tableRowActionClickAndCheck('deleteTopics');
});
it('should test the actions of the row and their modal and fetching for clear', async () => {
await tableRowActionClickAndCheck('clearTopicsMessages');
});
it('should test the actions of the row and their modal and fetching for recreate', async () => {
await tableRowActionClickAndCheck('recreate');
});
});
});

View file

@ -3,6 +3,7 @@ import { TableState } from 'lib/hooks/useTableState';
import { SortOrder } from 'generated-sources';
import * as S from 'components/common/table/TableHeaderCell/TableHeaderCell.styled';
import { DefaultTheme, StyledComponent } from 'styled-components';
import { ActionsCellProps } from 'components/Topics/List/ActionsCell/ActionsCell';
export interface OrderableProps {
orderBy: string | null;
@ -28,7 +29,7 @@ export interface TableCellProps<T, TId extends IdType>
}
interface TableColumnProps<T, TId extends IdType> {
cell?: React.FC<TableCellProps<T, TId>>;
cell?: React.FC<TableCellProps<T, TId> & ActionsCellProps>;
children?: React.ReactElement;
headerCell?: React.FC<TableHeaderCellProps<T, TId>>;
field?: string;