From bae5c39cf2f4ace9acf314e57ae62cb7b70d1371 Mon Sep 17 00:00:00 2001 From: Oleg Shur Date: Mon, 26 Sep 2022 12:05:01 +0300 Subject: [PATCH] KC: Make viewing/editing config a single view (#2613) * Get rid of KC edit config page * fix e2e-checks Co-authored-by: VladSenyuta --- .../ui/pages/connector/ConnectorsView.java | 6 +- .../kafka/ui/tests/ConnectorsTests.java | 2 +- .../src/components/Connect/Connect.tsx | 6 - .../Connect/Details/Actions/Actions.tsx | 15 --- .../Actions/__tests__/Actions.spec.tsx | 9 +- .../Config/Config.styled.ts} | 0 .../Connect/Details/Config/Config.tsx | 96 +++++++++++++-- .../Details/Config/__test__/Config.spec.tsx | 46 -------- .../Config/__tests__/Config.spec.tsx} | 20 +--- .../src/components/Connect/Edit/Edit.tsx | 109 ------------------ .../Connect/__tests__/Connect.spec.tsx | 20 +--- .../src/lib/hooks/api/kafkaConnect.ts | 9 +- kafka-ui-react-app/src/lib/paths.ts | 1 - 13 files changed, 103 insertions(+), 236 deletions(-) rename kafka-ui-react-app/src/components/Connect/{Edit/Edit.styled.ts => Details/Config/Config.styled.ts} (100%) delete mode 100644 kafka-ui-react-app/src/components/Connect/Details/Config/__test__/Config.spec.tsx rename kafka-ui-react-app/src/components/Connect/{Edit/__tests__/Edit.spec.tsx => Details/Config/__tests__/Config.spec.tsx} (80%) delete mode 100644 kafka-ui-react-app/src/components/Connect/Edit/Edit.tsx diff --git a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/connector/ConnectorsView.java b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/connector/ConnectorsView.java index 205950b778..772549c1c3 100644 --- a/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/connector/ConnectorsView.java +++ b/kafka-ui-e2e-checks/src/main/java/com/provectus/kafka/ui/pages/connector/ConnectorsView.java @@ -23,9 +23,9 @@ public class ConnectorsView { return this; } - @Step("Open 'Edit Config' of connector") - public ConnectorUpdateView openEditConfig() { - BrowserUtils.javaExecutorClick($x("//button[text()='Edit Config']")); + @Step() + public ConnectorUpdateView openConfigTab() { + BrowserUtils.javaExecutorClick($(By.xpath("//a[text() ='Config']"))); return new ConnectorUpdateView(); } diff --git a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/tests/ConnectorsTests.java b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/tests/ConnectorsTests.java index 3ec1eff890..2b858eec1b 100644 --- a/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/tests/ConnectorsTests.java +++ b/kafka-ui-e2e-checks/src/test/java/com/provectus/kafka/ui/tests/ConnectorsTests.java @@ -81,7 +81,7 @@ public class ConnectorsTests extends BaseTest { .waitUntilScreenReady() .openConnector(CONNECTOR_FOR_UPDATE.getName()); pages.connectorsView.connectorIsVisibleOnOverview(); - pages.connectorsView.openEditConfig() + pages.connectorsView.openConfigTab() .updConnectorConfig(CONNECTOR_FOR_UPDATE.getConfig()); pages.openConnectorsList(CLUSTER_NAME); Assertions.assertTrue(pages.connectorsList.isConnectorVisible(CONNECTOR_FOR_UPDATE.getName()),"isConnectorVisible()"); diff --git a/kafka-ui-react-app/src/components/Connect/Connect.tsx b/kafka-ui-react-app/src/components/Connect/Connect.tsx index 6689d249b4..efbac701ec 100644 --- a/kafka-ui-react-app/src/components/Connect/Connect.tsx +++ b/kafka-ui-react-app/src/components/Connect/Connect.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { Navigate, Routes, Route } from 'react-router-dom'; import { RouteParams, - clusterConnectConnectorEditRelativePath, clusterConnectConnectorRelativePath, clusterConnectConnectorsRelativePath, clusterConnectorNewRelativePath, @@ -13,7 +12,6 @@ import useAppParams from 'lib/hooks/useAppParams'; import ListPage from './List/ListPage'; import New from './New/New'; -import Edit from './Edit/Edit'; import DetailsPage from './Details/DetailsPage'; const Connect: React.FC = () => { @@ -23,10 +21,6 @@ const Connect: React.FC = () => { } /> } /> - } - /> } diff --git a/kafka-ui-react-app/src/components/Connect/Details/Actions/Actions.tsx b/kafka-ui-react-app/src/components/Connect/Details/Actions/Actions.tsx index 776afe8e8d..ee0f306346 100644 --- a/kafka-ui-react-app/src/components/Connect/Details/Actions/Actions.tsx +++ b/kafka-ui-react-app/src/components/Connect/Details/Actions/Actions.tsx @@ -10,7 +10,6 @@ import { useUpdateConnectorState, } from 'lib/hooks/api/kafkaConnect'; import { - clusterConnectConnectorEditPath, clusterConnectorsPath, RouterParamsClusterConnectConnector, } from 'lib/paths'; @@ -115,20 +114,6 @@ const Actions: React.FC = () => { > Restart Failed Tasks - - + + ); }; diff --git a/kafka-ui-react-app/src/components/Connect/Details/Config/__test__/Config.spec.tsx b/kafka-ui-react-app/src/components/Connect/Details/Config/__test__/Config.spec.tsx deleted file mode 100644 index 8cf11c0989..0000000000 --- a/kafka-ui-react-app/src/components/Connect/Details/Config/__test__/Config.spec.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import { render, WithRoute } from 'lib/testHelpers'; -import { clusterConnectConnectorConfigPath } from 'lib/paths'; -import Config from 'components/Connect/Details/Config/Config'; -import { screen } from '@testing-library/dom'; -import { useConnectorConfig } from 'lib/hooks/api/kafkaConnect'; -import { connector } from 'lib/fixtures/kafkaConnect'; - -jest.mock('components/common/Editor/Editor', () => () => ( -
mock-Editor
-)); -jest.mock('lib/hooks/api/kafkaConnect', () => ({ - useConnectorConfig: jest.fn(), -})); - -describe('Config', () => { - const renderComponent = () => - render( - - - , - { - initialEntries: [ - clusterConnectConnectorConfigPath( - 'my-cluster', - 'my-connect', - 'my-connector' - ), - ], - } - ); - - it('is empty when no config', () => { - (useConnectorConfig as jest.Mock).mockImplementation(() => ({})); - renderComponent(); - expect(screen.queryByText('mock-Editor')).not.toBeInTheDocument(); - }); - - it('renders editor', () => { - (useConnectorConfig as jest.Mock).mockImplementation(() => ({ - data: connector.config, - })); - renderComponent(); - expect(screen.getByText('mock-Editor')).toBeInTheDocument(); - }); -}); diff --git a/kafka-ui-react-app/src/components/Connect/Edit/__tests__/Edit.spec.tsx b/kafka-ui-react-app/src/components/Connect/Details/Config/__tests__/Config.spec.tsx similarity index 80% rename from kafka-ui-react-app/src/components/Connect/Edit/__tests__/Edit.spec.tsx rename to kafka-ui-react-app/src/components/Connect/Details/Config/__tests__/Config.spec.tsx index 6adbd22399..16611072fc 100644 --- a/kafka-ui-react-app/src/components/Connect/Edit/__tests__/Edit.spec.tsx +++ b/kafka-ui-react-app/src/components/Connect/Details/Config/__tests__/Config.spec.tsx @@ -1,10 +1,7 @@ import React from 'react'; import { render, WithRoute } from 'lib/testHelpers'; -import { - clusterConnectConnectorConfigPath, - clusterConnectConnectorEditPath, -} from 'lib/paths'; -import Edit from 'components/Connect/Edit/Edit'; +import { clusterConnectConnectorConfigPath } from 'lib/paths'; +import Config from 'components/Connect/Details/Config/Config'; import { connector } from 'lib/fixtures/kafkaConnect'; import { waitFor } from '@testing-library/dom'; import { act, fireEvent, screen } from '@testing-library/react'; @@ -31,16 +28,16 @@ const [clusterName, connectName, connectorName] = [ 'my-connector', ]; -describe('Edit', () => { - const pathname = clusterConnectConnectorEditPath(); +describe('Config', () => { + const pathname = clusterConnectConnectorConfigPath(); const renderComponent = () => render( - + , { initialEntries: [ - clusterConnectConnectorEditPath( + clusterConnectConnectorConfigPath( clusterName, connectName, connectorName @@ -66,11 +63,6 @@ describe('Edit', () => { renderComponent(); fireEvent.submit(screen.getByRole('form')); await waitFor(() => expect(updateConfig).toHaveBeenCalledTimes(1)); - - await waitFor(() => expect(mockHistoryPush).toHaveBeenCalledTimes(1)); - expect(mockHistoryPush).toHaveBeenCalledWith( - clusterConnectConnectorConfigPath(clusterName, connectName, connectorName) - ); }); it('does not redirect to connector config view on unsuccessful submit', async () => { diff --git a/kafka-ui-react-app/src/components/Connect/Edit/Edit.tsx b/kafka-ui-react-app/src/components/Connect/Edit/Edit.tsx deleted file mode 100644 index 60c7c1370a..0000000000 --- a/kafka-ui-react-app/src/components/Connect/Edit/Edit.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React from 'react'; -import { useNavigate } from 'react-router-dom'; -import useAppParams from 'lib/hooks/useAppParams'; -import { Controller, useForm } from 'react-hook-form'; -import { ErrorMessage } from '@hookform/error-message'; -import { yupResolver } from '@hookform/resolvers/yup'; -import { - clusterConnectConnectorConfigPath, - RouterParamsClusterConnectConnector, -} from 'lib/paths'; -import yup from 'lib/yupExtended'; -import Editor from 'components/common/Editor/Editor'; -import { Button } from 'components/common/Button/Button'; -import { - useConnectorConfig, - useUpdateConnectorConfig, -} from 'lib/hooks/api/kafkaConnect'; - -import { - ConnectEditWarningMessageStyled, - ConnectEditWrapperStyled, -} from './Edit.styled'; - -const validationSchema = yup.object().shape({ - config: yup.string().required().isJsonObject(), -}); - -interface FormValues { - config: string; -} - -const Edit: React.FC = () => { - const routerParams = useAppParams(); - const navigate = useNavigate(); - const { data: config } = useConnectorConfig(routerParams); - const mutation = useUpdateConnectorConfig(routerParams); - - const { - handleSubmit, - control, - formState: { isDirty, isSubmitting, isValid, errors }, - setValue, - } = useForm({ - mode: 'onTouched', - resolver: yupResolver(validationSchema), - defaultValues: { - config: JSON.stringify(config, null, '\t'), - }, - }); - - React.useEffect(() => { - if (config) { - setValue('config', JSON.stringify(config, null, '\t')); - } - }, [config, setValue]); - - const onSubmit = async (values: FormValues) => { - const requestBody = JSON.parse(values.config.trim()); - const connector = await mutation.mutateAsync(requestBody); - - if (connector) { - navigate( - clusterConnectConnectorConfigPath( - routerParams.clusterName, - routerParams.connectName, - routerParams.connectorName - ) - ); - } - }; - - const hasCredentials = JSON.stringify(config, null, '\t').includes( - '"******"' - ); - return ( - - {hasCredentials && ( - - Please replace ****** with the real credential values to avoid - accidentally breaking your connector config! - - )} -
-
- ( - - )} - /> -
-
- -
- -
-
- ); -}; - -export default Edit; diff --git a/kafka-ui-react-app/src/components/Connect/__tests__/Connect.spec.tsx b/kafka-ui-react-app/src/components/Connect/__tests__/Connect.spec.tsx index 8d07b0ebb5..855e546458 100644 --- a/kafka-ui-react-app/src/components/Connect/__tests__/Connect.spec.tsx +++ b/kafka-ui-react-app/src/components/Connect/__tests__/Connect.spec.tsx @@ -2,12 +2,10 @@ import React from 'react'; import { render, WithRoute } from 'lib/testHelpers'; import { screen } from '@testing-library/react'; import Connect from 'components/Connect/Connect'; -import { store } from 'redux/store'; import { clusterConnectorsPath, clusterConnectorNewPath, clusterConnectConnectorPath, - clusterConnectConnectorEditPath, getNonExactPath, clusterConnectsPath, } from 'lib/paths'; @@ -16,7 +14,6 @@ const ConnectCompText = { new: 'New Page', list: 'List Page', details: 'Details Page', - edit: 'Edit Page', }; jest.mock('components/Connect/New/New', () => () => ( @@ -28,9 +25,6 @@ jest.mock('components/Connect/List/ListPage', () => () => ( jest.mock('components/Connect/Details/DetailsPage', () => () => (
{ConnectCompText.details}
)); -jest.mock('components/Connect/Edit/Edit', () => () => ( -
{ConnectCompText.edit}
-)); describe('Connect', () => { const renderComponent = (pathname: string, routePath: string) => @@ -38,7 +32,7 @@ describe('Connect', () => { , - { initialEntries: [pathname], store } + { initialEntries: [pathname] } ); it('renders ListPage', () => { @@ -64,16 +58,4 @@ describe('Connect', () => { ); expect(screen.getByText(ConnectCompText.details)).toBeInTheDocument(); }); - - it('renders EditContainer', () => { - renderComponent( - clusterConnectConnectorEditPath( - 'my-cluster', - 'my-connect', - 'my-connector' - ), - clusterConnectsPath() - ); - expect(screen.getByText(ConnectCompText.edit)).toBeInTheDocument(); - }); }); diff --git a/kafka-ui-react-app/src/lib/hooks/api/kafkaConnect.ts b/kafka-ui-react-app/src/lib/hooks/api/kafkaConnect.ts index 49983da82a..7da7c5f875 100644 --- a/kafka-ui-react-app/src/lib/hooks/api/kafkaConnect.ts +++ b/kafka-ui-react-app/src/lib/hooks/api/kafkaConnect.ts @@ -8,6 +8,7 @@ import { kafkaConnectApiClient as api } from 'lib/api'; import sortBy from 'lodash/sortBy'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { ClusterName } from 'redux/interfaces'; +import { showSuccessAlert } from 'lib/errorHandling'; interface UseConnectorProps { clusterName: ClusterName; @@ -43,10 +44,6 @@ const connectorTasksKey = (props: UseConnectorProps) => [ ...connectorKey(props), 'tasks', ]; -const connectorConfigKey = (props: UseConnectorProps) => [ - ...connectorKey(props), - 'config', -]; export function useConnects(clusterName: ClusterName) { return useQuery(connectsKey(clusterName), () => @@ -104,8 +101,10 @@ export function useUpdateConnectorConfig(props: UseConnectorProps) { api.setConnectorConfig({ ...props, requestBody }), { onSuccess: () => { + showSuccessAlert({ + message: `Config successfully updated.`, + }); client.invalidateQueries(connectorKey(props)); - client.invalidateQueries(connectorConfigKey(props)); }, } ); diff --git a/kafka-ui-react-app/src/lib/paths.ts b/kafka-ui-react-app/src/lib/paths.ts index 94609de491..1b3d4b1301 100644 --- a/kafka-ui-react-app/src/lib/paths.ts +++ b/kafka-ui-react-app/src/lib/paths.ts @@ -201,7 +201,6 @@ export const clusterConnectorsRelativePath = 'connectors'; export const clusterConnectorNewRelativePath = 'create-new'; export const clusterConnectConnectorsRelativePath = `${RouteParams.connectName}/connectors`; export const clusterConnectConnectorRelativePath = `${clusterConnectConnectorsRelativePath}/${RouteParams.connectorName}`; -export const clusterConnectConnectorEditRelativePath = `${clusterConnectConnectorRelativePath}/edit`; export const clusterConnectConnectorTasksRelativePath = 'tasks'; export const clusterConnectConnectorConfigRelativePath = 'config';