KC: Make viewing/editing config a single view (#2613)
* Get rid of KC edit config page * fix e2e-checks Co-authored-by: VladSenyuta <vlad.senyuta@gmail.com>
This commit is contained in:
parent
b940c28b5c
commit
bae5c39cf2
13 changed files with 103 additions and 236 deletions
|
@ -23,9 +23,9 @@ public class ConnectorsView {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step("Open 'Edit Config' of connector")
|
@Step()
|
||||||
public ConnectorUpdateView openEditConfig() {
|
public ConnectorUpdateView openConfigTab() {
|
||||||
BrowserUtils.javaExecutorClick($x("//button[text()='Edit Config']"));
|
BrowserUtils.javaExecutorClick($(By.xpath("//a[text() ='Config']")));
|
||||||
return new ConnectorUpdateView();
|
return new ConnectorUpdateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class ConnectorsTests extends BaseTest {
|
||||||
.waitUntilScreenReady()
|
.waitUntilScreenReady()
|
||||||
.openConnector(CONNECTOR_FOR_UPDATE.getName());
|
.openConnector(CONNECTOR_FOR_UPDATE.getName());
|
||||||
pages.connectorsView.connectorIsVisibleOnOverview();
|
pages.connectorsView.connectorIsVisibleOnOverview();
|
||||||
pages.connectorsView.openEditConfig()
|
pages.connectorsView.openConfigTab()
|
||||||
.updConnectorConfig(CONNECTOR_FOR_UPDATE.getConfig());
|
.updConnectorConfig(CONNECTOR_FOR_UPDATE.getConfig());
|
||||||
pages.openConnectorsList(CLUSTER_NAME);
|
pages.openConnectorsList(CLUSTER_NAME);
|
||||||
Assertions.assertTrue(pages.connectorsList.isConnectorVisible(CONNECTOR_FOR_UPDATE.getName()),"isConnectorVisible()");
|
Assertions.assertTrue(pages.connectorsList.isConnectorVisible(CONNECTOR_FOR_UPDATE.getName()),"isConnectorVisible()");
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||||
import { Navigate, Routes, Route } from 'react-router-dom';
|
import { Navigate, Routes, Route } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
RouteParams,
|
RouteParams,
|
||||||
clusterConnectConnectorEditRelativePath,
|
|
||||||
clusterConnectConnectorRelativePath,
|
clusterConnectConnectorRelativePath,
|
||||||
clusterConnectConnectorsRelativePath,
|
clusterConnectConnectorsRelativePath,
|
||||||
clusterConnectorNewRelativePath,
|
clusterConnectorNewRelativePath,
|
||||||
|
@ -13,7 +12,6 @@ import useAppParams from 'lib/hooks/useAppParams';
|
||||||
|
|
||||||
import ListPage from './List/ListPage';
|
import ListPage from './List/ListPage';
|
||||||
import New from './New/New';
|
import New from './New/New';
|
||||||
import Edit from './Edit/Edit';
|
|
||||||
import DetailsPage from './Details/DetailsPage';
|
import DetailsPage from './Details/DetailsPage';
|
||||||
|
|
||||||
const Connect: React.FC = () => {
|
const Connect: React.FC = () => {
|
||||||
|
@ -23,10 +21,6 @@ const Connect: React.FC = () => {
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route index element={<ListPage />} />
|
<Route index element={<ListPage />} />
|
||||||
<Route path={clusterConnectorNewRelativePath} element={<New />} />
|
<Route path={clusterConnectorNewRelativePath} element={<New />} />
|
||||||
<Route
|
|
||||||
path={clusterConnectConnectorEditRelativePath}
|
|
||||||
element={<Edit />}
|
|
||||||
/>
|
|
||||||
<Route
|
<Route
|
||||||
path={getNonExactPath(clusterConnectConnectorRelativePath)}
|
path={getNonExactPath(clusterConnectConnectorRelativePath)}
|
||||||
element={<DetailsPage />}
|
element={<DetailsPage />}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import {
|
||||||
useUpdateConnectorState,
|
useUpdateConnectorState,
|
||||||
} from 'lib/hooks/api/kafkaConnect';
|
} from 'lib/hooks/api/kafkaConnect';
|
||||||
import {
|
import {
|
||||||
clusterConnectConnectorEditPath,
|
|
||||||
clusterConnectorsPath,
|
clusterConnectorsPath,
|
||||||
RouterParamsClusterConnectConnector,
|
RouterParamsClusterConnectConnector,
|
||||||
} from 'lib/paths';
|
} from 'lib/paths';
|
||||||
|
@ -115,20 +114,6 @@ const Actions: React.FC = () => {
|
||||||
>
|
>
|
||||||
Restart Failed Tasks
|
Restart Failed Tasks
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
|
||||||
buttonSize="M"
|
|
||||||
buttonType="primary"
|
|
||||||
type="button"
|
|
||||||
disabled={isMutating}
|
|
||||||
to={clusterConnectConnectorEditPath(
|
|
||||||
routerProps.clusterName,
|
|
||||||
routerProps.connectName,
|
|
||||||
routerProps.connectorName
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Edit Config
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
buttonSize="M"
|
buttonSize="M"
|
||||||
buttonType="secondary"
|
buttonType="secondary"
|
||||||
|
|
|
@ -31,7 +31,6 @@ const expectActionButtonsExists = () => {
|
||||||
expect(screen.getByText('Restart Connector')).toBeInTheDocument();
|
expect(screen.getByText('Restart Connector')).toBeInTheDocument();
|
||||||
expect(screen.getByText('Restart All Tasks')).toBeInTheDocument();
|
expect(screen.getByText('Restart All Tasks')).toBeInTheDocument();
|
||||||
expect(screen.getByText('Restart Failed Tasks')).toBeInTheDocument();
|
expect(screen.getByText('Restart Failed Tasks')).toBeInTheDocument();
|
||||||
expect(screen.getByText('Edit Config')).toBeInTheDocument();
|
|
||||||
expect(screen.getByText('Delete')).toBeInTheDocument();
|
expect(screen.getByText('Delete')).toBeInTheDocument();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,7 +62,7 @@ describe('Actions', () => {
|
||||||
data: set({ ...connector }, 'status.state', ConnectorState.PAUSED),
|
data: set({ ...connector }, 'status.state', ConnectorState.PAUSED),
|
||||||
}));
|
}));
|
||||||
renderComponent();
|
renderComponent();
|
||||||
expect(screen.getAllByRole('button').length).toEqual(6);
|
expect(screen.getAllByRole('button').length).toEqual(5);
|
||||||
expect(screen.getByText('Resume')).toBeInTheDocument();
|
expect(screen.getByText('Resume')).toBeInTheDocument();
|
||||||
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
|
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
|
||||||
expectActionButtonsExists();
|
expectActionButtonsExists();
|
||||||
|
@ -74,7 +73,7 @@ describe('Actions', () => {
|
||||||
data: set({ ...connector }, 'status.state', ConnectorState.FAILED),
|
data: set({ ...connector }, 'status.state', ConnectorState.FAILED),
|
||||||
}));
|
}));
|
||||||
renderComponent();
|
renderComponent();
|
||||||
expect(screen.getAllByRole('button').length).toEqual(5);
|
expect(screen.getAllByRole('button').length).toEqual(4);
|
||||||
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
|
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
|
||||||
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
|
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
|
||||||
expectActionButtonsExists();
|
expectActionButtonsExists();
|
||||||
|
@ -85,7 +84,7 @@ describe('Actions', () => {
|
||||||
data: set({ ...connector }, 'status.state', ConnectorState.UNASSIGNED),
|
data: set({ ...connector }, 'status.state', ConnectorState.UNASSIGNED),
|
||||||
}));
|
}));
|
||||||
renderComponent();
|
renderComponent();
|
||||||
expect(screen.getAllByRole('button').length).toEqual(5);
|
expect(screen.getAllByRole('button').length).toEqual(4);
|
||||||
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
|
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
|
||||||
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
|
expect(screen.queryByText('Pause')).not.toBeInTheDocument();
|
||||||
expectActionButtonsExists();
|
expectActionButtonsExists();
|
||||||
|
@ -96,7 +95,7 @@ describe('Actions', () => {
|
||||||
data: set({ ...connector }, 'status.state', ConnectorState.RUNNING),
|
data: set({ ...connector }, 'status.state', ConnectorState.RUNNING),
|
||||||
}));
|
}));
|
||||||
renderComponent();
|
renderComponent();
|
||||||
expect(screen.getAllByRole('button').length).toEqual(6);
|
expect(screen.getAllByRole('button').length).toEqual(5);
|
||||||
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
|
expect(screen.queryByText('Resume')).not.toBeInTheDocument();
|
||||||
expect(screen.getByText('Pause')).toBeInTheDocument();
|
expect(screen.getByText('Pause')).toBeInTheDocument();
|
||||||
expectActionButtonsExists();
|
expectActionButtonsExists();
|
||||||
|
|
|
@ -1,23 +1,95 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import useAppParams from 'lib/hooks/useAppParams';
|
import useAppParams from 'lib/hooks/useAppParams';
|
||||||
import Editor from 'components/common/Editor/Editor';
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
|
import { ErrorMessage } from '@hookform/error-message';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
import { RouterParamsClusterConnectConnector } from 'lib/paths';
|
import { RouterParamsClusterConnectConnector } from 'lib/paths';
|
||||||
import { useConnectorConfig } from 'lib/hooks/api/kafkaConnect';
|
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 './Config.styled';
|
||||||
|
|
||||||
|
const validationSchema = yup.object().shape({
|
||||||
|
config: yup.string().required().isJsonObject(),
|
||||||
|
});
|
||||||
|
|
||||||
|
interface FormValues {
|
||||||
|
config: string;
|
||||||
|
}
|
||||||
|
|
||||||
const Config: React.FC = () => {
|
const Config: React.FC = () => {
|
||||||
const routerProps = useAppParams<RouterParamsClusterConnectConnector>();
|
const routerParams = useAppParams<RouterParamsClusterConnectConnector>();
|
||||||
const { data: config } = useConnectorConfig(routerProps);
|
const { data: config } = useConnectorConfig(routerParams);
|
||||||
|
const mutation = useUpdateConnectorConfig(routerParams);
|
||||||
|
|
||||||
if (!config) return null;
|
const {
|
||||||
|
handleSubmit,
|
||||||
|
control,
|
||||||
|
reset,
|
||||||
|
formState: { isDirty, isSubmitting, isValid, errors },
|
||||||
|
setValue,
|
||||||
|
} = useForm<FormValues>({
|
||||||
|
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());
|
||||||
|
await mutation.mutateAsync(requestBody);
|
||||||
|
reset(values);
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasCredentials = JSON.stringify(config, null, '\t').includes(
|
||||||
|
'"******"'
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<Editor
|
<ConnectEditWrapperStyled>
|
||||||
readOnly
|
{hasCredentials && (
|
||||||
value={JSON.stringify(config, null, '\t')}
|
<ConnectEditWarningMessageStyled>
|
||||||
highlightActiveLine={false}
|
Please replace ****** with the real credential values to avoid
|
||||||
isFixedHeight
|
accidentally breaking your connector config!
|
||||||
style={{ margin: '16px' }}
|
</ConnectEditWarningMessageStyled>
|
||||||
/>
|
)}
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)} aria-label="Edit connect form">
|
||||||
|
<div>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="config"
|
||||||
|
render={({ field }) => (
|
||||||
|
<Editor {...field} readOnly={isSubmitting} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<ErrorMessage errors={errors} name="config" />
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
buttonSize="M"
|
||||||
|
buttonType="primary"
|
||||||
|
type="submit"
|
||||||
|
disabled={!isValid || isSubmitting || !isDirty}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</ConnectEditWrapperStyled>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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', () => () => (
|
|
||||||
<div>mock-Editor</div>
|
|
||||||
));
|
|
||||||
jest.mock('lib/hooks/api/kafkaConnect', () => ({
|
|
||||||
useConnectorConfig: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('Config', () => {
|
|
||||||
const renderComponent = () =>
|
|
||||||
render(
|
|
||||||
<WithRoute path={clusterConnectConnectorConfigPath()}>
|
|
||||||
<Config />
|
|
||||||
</WithRoute>,
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,10 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render, WithRoute } from 'lib/testHelpers';
|
import { render, WithRoute } from 'lib/testHelpers';
|
||||||
import {
|
import { clusterConnectConnectorConfigPath } from 'lib/paths';
|
||||||
clusterConnectConnectorConfigPath,
|
import Config from 'components/Connect/Details/Config/Config';
|
||||||
clusterConnectConnectorEditPath,
|
|
||||||
} from 'lib/paths';
|
|
||||||
import Edit from 'components/Connect/Edit/Edit';
|
|
||||||
import { connector } from 'lib/fixtures/kafkaConnect';
|
import { connector } from 'lib/fixtures/kafkaConnect';
|
||||||
import { waitFor } from '@testing-library/dom';
|
import { waitFor } from '@testing-library/dom';
|
||||||
import { act, fireEvent, screen } from '@testing-library/react';
|
import { act, fireEvent, screen } from '@testing-library/react';
|
||||||
|
@ -31,16 +28,16 @@ const [clusterName, connectName, connectorName] = [
|
||||||
'my-connector',
|
'my-connector',
|
||||||
];
|
];
|
||||||
|
|
||||||
describe('Edit', () => {
|
describe('Config', () => {
|
||||||
const pathname = clusterConnectConnectorEditPath();
|
const pathname = clusterConnectConnectorConfigPath();
|
||||||
const renderComponent = () =>
|
const renderComponent = () =>
|
||||||
render(
|
render(
|
||||||
<WithRoute path={pathname}>
|
<WithRoute path={pathname}>
|
||||||
<Edit />
|
<Config />
|
||||||
</WithRoute>,
|
</WithRoute>,
|
||||||
{
|
{
|
||||||
initialEntries: [
|
initialEntries: [
|
||||||
clusterConnectConnectorEditPath(
|
clusterConnectConnectorConfigPath(
|
||||||
clusterName,
|
clusterName,
|
||||||
connectName,
|
connectName,
|
||||||
connectorName
|
connectorName
|
||||||
|
@ -66,11 +63,6 @@ describe('Edit', () => {
|
||||||
renderComponent();
|
renderComponent();
|
||||||
fireEvent.submit(screen.getByRole('form'));
|
fireEvent.submit(screen.getByRole('form'));
|
||||||
await waitFor(() => expect(updateConfig).toHaveBeenCalledTimes(1));
|
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 () => {
|
it('does not redirect to connector config view on unsuccessful submit', async () => {
|
|
@ -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<RouterParamsClusterConnectConnector>();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const { data: config } = useConnectorConfig(routerParams);
|
|
||||||
const mutation = useUpdateConnectorConfig(routerParams);
|
|
||||||
|
|
||||||
const {
|
|
||||||
handleSubmit,
|
|
||||||
control,
|
|
||||||
formState: { isDirty, isSubmitting, isValid, errors },
|
|
||||||
setValue,
|
|
||||||
} = useForm<FormValues>({
|
|
||||||
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 (
|
|
||||||
<ConnectEditWrapperStyled>
|
|
||||||
{hasCredentials && (
|
|
||||||
<ConnectEditWarningMessageStyled>
|
|
||||||
Please replace ****** with the real credential values to avoid
|
|
||||||
accidentally breaking your connector config!
|
|
||||||
</ConnectEditWarningMessageStyled>
|
|
||||||
)}
|
|
||||||
<form onSubmit={handleSubmit(onSubmit)} aria-label="Edit connect form">
|
|
||||||
<div>
|
|
||||||
<Controller
|
|
||||||
control={control}
|
|
||||||
name="config"
|
|
||||||
render={({ field }) => (
|
|
||||||
<Editor {...field} readOnly={isSubmitting} />
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<ErrorMessage errors={errors} name="config" />
|
|
||||||
</div>
|
|
||||||
<Button
|
|
||||||
buttonSize="M"
|
|
||||||
buttonType="primary"
|
|
||||||
type="submit"
|
|
||||||
disabled={!isValid || isSubmitting || !isDirty}
|
|
||||||
>
|
|
||||||
Submit
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
</ConnectEditWrapperStyled>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Edit;
|
|
|
@ -2,12 +2,10 @@ import React from 'react';
|
||||||
import { render, WithRoute } from 'lib/testHelpers';
|
import { render, WithRoute } from 'lib/testHelpers';
|
||||||
import { screen } from '@testing-library/react';
|
import { screen } from '@testing-library/react';
|
||||||
import Connect from 'components/Connect/Connect';
|
import Connect from 'components/Connect/Connect';
|
||||||
import { store } from 'redux/store';
|
|
||||||
import {
|
import {
|
||||||
clusterConnectorsPath,
|
clusterConnectorsPath,
|
||||||
clusterConnectorNewPath,
|
clusterConnectorNewPath,
|
||||||
clusterConnectConnectorPath,
|
clusterConnectConnectorPath,
|
||||||
clusterConnectConnectorEditPath,
|
|
||||||
getNonExactPath,
|
getNonExactPath,
|
||||||
clusterConnectsPath,
|
clusterConnectsPath,
|
||||||
} from 'lib/paths';
|
} from 'lib/paths';
|
||||||
|
@ -16,7 +14,6 @@ const ConnectCompText = {
|
||||||
new: 'New Page',
|
new: 'New Page',
|
||||||
list: 'List Page',
|
list: 'List Page',
|
||||||
details: 'Details Page',
|
details: 'Details Page',
|
||||||
edit: 'Edit Page',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
jest.mock('components/Connect/New/New', () => () => (
|
jest.mock('components/Connect/New/New', () => () => (
|
||||||
|
@ -28,9 +25,6 @@ jest.mock('components/Connect/List/ListPage', () => () => (
|
||||||
jest.mock('components/Connect/Details/DetailsPage', () => () => (
|
jest.mock('components/Connect/Details/DetailsPage', () => () => (
|
||||||
<div>{ConnectCompText.details}</div>
|
<div>{ConnectCompText.details}</div>
|
||||||
));
|
));
|
||||||
jest.mock('components/Connect/Edit/Edit', () => () => (
|
|
||||||
<div>{ConnectCompText.edit}</div>
|
|
||||||
));
|
|
||||||
|
|
||||||
describe('Connect', () => {
|
describe('Connect', () => {
|
||||||
const renderComponent = (pathname: string, routePath: string) =>
|
const renderComponent = (pathname: string, routePath: string) =>
|
||||||
|
@ -38,7 +32,7 @@ describe('Connect', () => {
|
||||||
<WithRoute path={getNonExactPath(routePath)}>
|
<WithRoute path={getNonExactPath(routePath)}>
|
||||||
<Connect />
|
<Connect />
|
||||||
</WithRoute>,
|
</WithRoute>,
|
||||||
{ initialEntries: [pathname], store }
|
{ initialEntries: [pathname] }
|
||||||
);
|
);
|
||||||
|
|
||||||
it('renders ListPage', () => {
|
it('renders ListPage', () => {
|
||||||
|
@ -64,16 +58,4 @@ describe('Connect', () => {
|
||||||
);
|
);
|
||||||
expect(screen.getByText(ConnectCompText.details)).toBeInTheDocument();
|
expect(screen.getByText(ConnectCompText.details)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders EditContainer', () => {
|
|
||||||
renderComponent(
|
|
||||||
clusterConnectConnectorEditPath(
|
|
||||||
'my-cluster',
|
|
||||||
'my-connect',
|
|
||||||
'my-connector'
|
|
||||||
),
|
|
||||||
clusterConnectsPath()
|
|
||||||
);
|
|
||||||
expect(screen.getByText(ConnectCompText.edit)).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { kafkaConnectApiClient as api } from 'lib/api';
|
||||||
import sortBy from 'lodash/sortBy';
|
import sortBy from 'lodash/sortBy';
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { ClusterName } from 'redux/interfaces';
|
import { ClusterName } from 'redux/interfaces';
|
||||||
|
import { showSuccessAlert } from 'lib/errorHandling';
|
||||||
|
|
||||||
interface UseConnectorProps {
|
interface UseConnectorProps {
|
||||||
clusterName: ClusterName;
|
clusterName: ClusterName;
|
||||||
|
@ -43,10 +44,6 @@ const connectorTasksKey = (props: UseConnectorProps) => [
|
||||||
...connectorKey(props),
|
...connectorKey(props),
|
||||||
'tasks',
|
'tasks',
|
||||||
];
|
];
|
||||||
const connectorConfigKey = (props: UseConnectorProps) => [
|
|
||||||
...connectorKey(props),
|
|
||||||
'config',
|
|
||||||
];
|
|
||||||
|
|
||||||
export function useConnects(clusterName: ClusterName) {
|
export function useConnects(clusterName: ClusterName) {
|
||||||
return useQuery(connectsKey(clusterName), () =>
|
return useQuery(connectsKey(clusterName), () =>
|
||||||
|
@ -104,8 +101,10 @@ export function useUpdateConnectorConfig(props: UseConnectorProps) {
|
||||||
api.setConnectorConfig({ ...props, requestBody }),
|
api.setConnectorConfig({ ...props, requestBody }),
|
||||||
{
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
showSuccessAlert({
|
||||||
|
message: `Config successfully updated.`,
|
||||||
|
});
|
||||||
client.invalidateQueries(connectorKey(props));
|
client.invalidateQueries(connectorKey(props));
|
||||||
client.invalidateQueries(connectorConfigKey(props));
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -201,7 +201,6 @@ export const clusterConnectorsRelativePath = 'connectors';
|
||||||
export const clusterConnectorNewRelativePath = 'create-new';
|
export const clusterConnectorNewRelativePath = 'create-new';
|
||||||
export const clusterConnectConnectorsRelativePath = `${RouteParams.connectName}/connectors`;
|
export const clusterConnectConnectorsRelativePath = `${RouteParams.connectName}/connectors`;
|
||||||
export const clusterConnectConnectorRelativePath = `${clusterConnectConnectorsRelativePath}/${RouteParams.connectorName}`;
|
export const clusterConnectConnectorRelativePath = `${clusterConnectConnectorsRelativePath}/${RouteParams.connectorName}`;
|
||||||
export const clusterConnectConnectorEditRelativePath = `${clusterConnectConnectorRelativePath}/edit`;
|
|
||||||
export const clusterConnectConnectorTasksRelativePath = 'tasks';
|
export const clusterConnectConnectorTasksRelativePath = 'tasks';
|
||||||
export const clusterConnectConnectorConfigRelativePath = 'config';
|
export const clusterConnectConnectorConfigRelativePath = 'config';
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue