Rewrite to context & update the tests
This commit is contained in:
parent
b9f6390b10
commit
0c3687d013
17 changed files with 125 additions and 177 deletions
|
@ -6,13 +6,13 @@ import Breadcrumb from '../../common/Breadcrumb/Breadcrumb';
|
||||||
import SchemaVersion from './SchemaVersion';
|
import SchemaVersion from './SchemaVersion';
|
||||||
import LatestVersionItem from './LatestVersionItem';
|
import LatestVersionItem from './LatestVersionItem';
|
||||||
import PageLoader from '../../common/PageLoader/PageLoader';
|
import PageLoader from '../../common/PageLoader/PageLoader';
|
||||||
|
import _ReadOnlyContext from '../../contexts/ReadOnlyContext';
|
||||||
|
|
||||||
export interface DetailsProps {
|
export interface DetailsProps {
|
||||||
schema: SchemaSubject;
|
schema: SchemaSubject;
|
||||||
clusterName: ClusterName;
|
clusterName: ClusterName;
|
||||||
versions: SchemaSubject[];
|
versions: SchemaSubject[];
|
||||||
isFetched: boolean;
|
isFetched: boolean;
|
||||||
isReadOnly?: boolean | undefined;
|
|
||||||
fetchSchemaVersions: (
|
fetchSchemaVersions: (
|
||||||
clusterName: ClusterName,
|
clusterName: ClusterName,
|
||||||
schemaName: SchemaName
|
schemaName: SchemaName
|
||||||
|
@ -25,8 +25,8 @@ const Details: React.FC<DetailsProps> = ({
|
||||||
fetchSchemaVersions,
|
fetchSchemaVersions,
|
||||||
versions,
|
versions,
|
||||||
isFetched,
|
isFetched,
|
||||||
isReadOnly,
|
|
||||||
}) => {
|
}) => {
|
||||||
|
const ReadOnlyContext = React.useContext(_ReadOnlyContext);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
fetchSchemaVersions(clusterName, schema.subject as SchemaName);
|
fetchSchemaVersions(clusterName, schema.subject as SchemaName);
|
||||||
}, [fetchSchemaVersions, clusterName]);
|
}, [fetchSchemaVersions, clusterName]);
|
||||||
|
@ -56,7 +56,7 @@ const Details: React.FC<DetailsProps> = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!isReadOnly && (
|
{!ReadOnlyContext.isReadOnly && (
|
||||||
<div className="level-right">
|
<div className="level-right">
|
||||||
<button
|
<button
|
||||||
className="button is-warning is-small level-item"
|
className="button is-warning is-small level-item"
|
||||||
|
|
|
@ -6,7 +6,6 @@ import {
|
||||||
getSchema,
|
getSchema,
|
||||||
getSortedSchemaVersions,
|
getSortedSchemaVersions,
|
||||||
} from 'redux/reducers/schemas/selectors';
|
} from 'redux/reducers/schemas/selectors';
|
||||||
import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
|
|
||||||
import { fetchSchemaVersions } from 'redux/actions';
|
import { fetchSchemaVersions } from 'redux/actions';
|
||||||
import Details from './Details';
|
import Details from './Details';
|
||||||
|
|
||||||
|
@ -29,7 +28,6 @@ const mapStateToProps = (
|
||||||
versions: getSortedSchemaVersions(state),
|
versions: getSortedSchemaVersions(state),
|
||||||
isFetched: getIsSchemaVersionFetched(state),
|
isFetched: getIsSchemaVersionFetched(state),
|
||||||
clusterName,
|
clusterName,
|
||||||
isReadOnly: getClustersReadonlyStatus(clusterName)(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow, mount } from 'enzyme';
|
||||||
import configureStore from 'redux/store/configureStore';
|
import configureStore from 'redux/store/configureStore';
|
||||||
|
import { StaticRouter } from 'react-router';
|
||||||
import DetailsContainer from '../DetailsContainer';
|
import DetailsContainer from '../DetailsContainer';
|
||||||
import Details, { DetailsProps } from '../Details';
|
import Details, { DetailsProps } from '../Details';
|
||||||
import { schema, versions } from './fixtures';
|
import { schema, versions } from './fixtures';
|
||||||
|
import ReadOnlyContext from '../../../contexts/ReadOnlyContext';
|
||||||
|
|
||||||
describe('Details', () => {
|
describe('Details', () => {
|
||||||
describe('Container', () => {
|
describe('Container', () => {
|
||||||
|
@ -103,8 +105,16 @@ describe('Details', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when the readonly flag is set', () => {
|
describe('when the readonly flag is set', () => {
|
||||||
it('mathces the snapshot', () => {
|
it('does not render update & delete buttons', () => {
|
||||||
expect(shallow(setupWrapper({ isReadOnly: true }))).toMatchSnapshot();
|
expect(
|
||||||
|
mount(
|
||||||
|
<StaticRouter>
|
||||||
|
<ReadOnlyContext.Provider value={{ isReadOnly: true }}>
|
||||||
|
{setupWrapper({ versions })}
|
||||||
|
</ReadOnlyContext.Provider>
|
||||||
|
</StaticRouter>
|
||||||
|
).exists('.level-right')
|
||||||
|
).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -322,92 +322,6 @@ exports[`Details View when page with schema versions loaded when schema has vers
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`Details View when page with schema versions loaded when the readonly flag is set mathces the snapshot 1`] = `
|
|
||||||
<div
|
|
||||||
className="section"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="level"
|
|
||||||
>
|
|
||||||
<Breadcrumb
|
|
||||||
links={
|
|
||||||
Array [
|
|
||||||
Object {
|
|
||||||
"href": "/ui/clusters/Test cluster/schemas",
|
|
||||||
"label": "Schema Registry",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
>
|
|
||||||
test
|
|
||||||
</Breadcrumb>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="box"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="level"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="level-left"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="level-item"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="mr-1"
|
|
||||||
>
|
|
||||||
<b>
|
|
||||||
Latest Version
|
|
||||||
</b>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="tag is-info is-light"
|
|
||||||
title="Version"
|
|
||||||
>
|
|
||||||
#
|
|
||||||
1
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<LatestVersionItem
|
|
||||||
schema={
|
|
||||||
Object {
|
|
||||||
"compatibilityLevel": "BACKWARD",
|
|
||||||
"id": 1,
|
|
||||||
"schema": "{\\"type\\":\\"record\\",\\"name\\":\\"MyRecord1\\",\\"namespace\\":\\"com.mycompany\\",\\"fields\\":[{\\"name\\":\\"id\\",\\"type\\":\\"long\\"}]}",
|
|
||||||
"subject": "test",
|
|
||||||
"version": "1",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="box"
|
|
||||||
>
|
|
||||||
<table
|
|
||||||
className="table is-striped is-fullwidth"
|
|
||||||
>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Version
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
ID
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Schema
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody />
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Details View when page with schema versions loaded when versions are empty matches snapshot 1`] = `
|
exports[`Details View when page with schema versions loaded when versions are empty matches snapshot 1`] = `
|
||||||
<div
|
<div
|
||||||
className="section"
|
className="section"
|
||||||
|
|
|
@ -4,13 +4,14 @@ import { NavLink, useParams } from 'react-router-dom';
|
||||||
import { clusterSchemaNewPath } from 'lib/paths';
|
import { clusterSchemaNewPath } from 'lib/paths';
|
||||||
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
||||||
import ListItem from './ListItem';
|
import ListItem from './ListItem';
|
||||||
|
import _ReadOnlyContext from '../../contexts/ReadOnlyContext';
|
||||||
|
|
||||||
export interface ListProps {
|
export interface ListProps {
|
||||||
schemas: SchemaSubject[];
|
schemas: SchemaSubject[];
|
||||||
isReadOnly?: boolean | undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const List: React.FC<ListProps> = ({ schemas, isReadOnly }) => {
|
const List: React.FC<ListProps> = ({ schemas }) => {
|
||||||
|
const ReadOnlyContext = React.useContext(_ReadOnlyContext);
|
||||||
const { clusterName } = useParams<{ clusterName: string }>();
|
const { clusterName } = useParams<{ clusterName: string }>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -18,7 +19,7 @@ const List: React.FC<ListProps> = ({ schemas, isReadOnly }) => {
|
||||||
<Breadcrumb>Schema Registry</Breadcrumb>
|
<Breadcrumb>Schema Registry</Breadcrumb>
|
||||||
<div className="box">
|
<div className="box">
|
||||||
<div className="level">
|
<div className="level">
|
||||||
{!isReadOnly && (
|
{!ReadOnlyContext.isReadOnly && (
|
||||||
<div className="level-item level-right">
|
<div className="level-item level-right">
|
||||||
<NavLink
|
<NavLink
|
||||||
className="button is-primary"
|
className="button is-primary"
|
||||||
|
|
|
@ -1,26 +1,10 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { RootState, ClusterName } from 'redux/interfaces';
|
import { RootState } from 'redux/interfaces';
|
||||||
import { getSchemaList } from 'redux/reducers/schemas/selectors';
|
import { getSchemaList } from 'redux/reducers/schemas/selectors';
|
||||||
import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
|
|
||||||
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
|
||||||
import List from './List';
|
import List from './List';
|
||||||
|
|
||||||
interface RouteProps {
|
const mapStateToProps = (state: RootState) => ({
|
||||||
clusterName: ClusterName;
|
|
||||||
}
|
|
||||||
|
|
||||||
type OwnProps = RouteComponentProps<RouteProps>;
|
|
||||||
|
|
||||||
const mapStateToProps = (
|
|
||||||
state: RootState,
|
|
||||||
{
|
|
||||||
match: {
|
|
||||||
params: { clusterName },
|
|
||||||
},
|
|
||||||
}: OwnProps
|
|
||||||
) => ({
|
|
||||||
schemas: getSchemaList(state),
|
schemas: getSchemaList(state),
|
||||||
isReadOnly: getClustersReadonlyStatus(clusterName)(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withRouter(connect(mapStateToProps)(List));
|
export default connect(mapStateToProps)(List);
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { mount, shallow } from 'enzyme';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { StaticRouter } from 'react-router';
|
import { StaticRouter } from 'react-router';
|
||||||
import configureStore from 'redux/store/configureStore';
|
import configureStore from 'redux/store/configureStore';
|
||||||
|
import ReadOnlyContext from 'components/contexts/ReadOnlyContext';
|
||||||
import ListContainer from '../ListContainer';
|
import ListContainer from '../ListContainer';
|
||||||
import List, { ListProps } from '../List';
|
import List, { ListProps } from '../List';
|
||||||
import { schemas } from './fixtures';
|
import { schemas } from './fixtures';
|
||||||
|
@ -51,7 +52,13 @@ describe('List', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with readonly cluster', () => {
|
describe('with readonly cluster', () => {
|
||||||
const wrapper = shallow(setupWrapper({ schemas, isReadOnly: true }));
|
const wrapper = mount(
|
||||||
|
<StaticRouter>
|
||||||
|
<ReadOnlyContext.Provider value={{ isReadOnly: true }}>
|
||||||
|
{setupWrapper({ schemas: [] })}
|
||||||
|
</ReadOnlyContext.Provider>
|
||||||
|
</StaticRouter>
|
||||||
|
);
|
||||||
it('does not render Create Schema button', () => {
|
it('does not render Create Schema button', () => {
|
||||||
expect(wrapper.exists('NavLink')).toBeFalsy();
|
expect(wrapper.exists('NavLink')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,15 +5,18 @@ import PageLoader from 'components/common/PageLoader/PageLoader';
|
||||||
import ListContainer from './List/ListContainer';
|
import ListContainer from './List/ListContainer';
|
||||||
import DetailsContainer from './Details/DetailsContainer';
|
import DetailsContainer from './Details/DetailsContainer';
|
||||||
import NewContainer from './New/NewContainer';
|
import NewContainer from './New/NewContainer';
|
||||||
|
import ReadOnlyContext from '../contexts/ReadOnlyContext';
|
||||||
|
|
||||||
export interface SchemasProps {
|
export interface SchemasProps {
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
fetchSchemasByClusterName: (clusterName: ClusterName) => void;
|
fetchSchemasByClusterName: (clusterName: ClusterName) => void;
|
||||||
|
isReadOnly?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Schemas: React.FC<SchemasProps> = ({
|
const Schemas: React.FC<SchemasProps> = ({
|
||||||
isFetching,
|
isFetching,
|
||||||
fetchSchemasByClusterName,
|
fetchSchemasByClusterName,
|
||||||
|
isReadOnly,
|
||||||
}) => {
|
}) => {
|
||||||
const { clusterName } = useParams<{ clusterName: string }>();
|
const { clusterName } = useParams<{ clusterName: string }>();
|
||||||
|
|
||||||
|
@ -26,23 +29,25 @@ const Schemas: React.FC<SchemasProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<ReadOnlyContext.Provider value={{ isReadOnly }}>
|
||||||
<Route
|
<Switch>
|
||||||
exact
|
<Route
|
||||||
path="/ui/clusters/:clusterName/schemas"
|
exact
|
||||||
component={ListContainer}
|
path="/ui/clusters/:clusterName/schemas"
|
||||||
/>
|
component={ListContainer}
|
||||||
<Route
|
/>
|
||||||
exact
|
<Route
|
||||||
path="/ui/clusters/:clusterName/schemas/new"
|
exact
|
||||||
component={NewContainer}
|
path="/ui/clusters/:clusterName/schemas/new"
|
||||||
/>
|
component={NewContainer}
|
||||||
<Route
|
/>
|
||||||
exact
|
<Route
|
||||||
path="/ui/clusters/:clusterName/schemas/:subject/latest"
|
exact
|
||||||
component={DetailsContainer}
|
path="/ui/clusters/:clusterName/schemas/:subject/latest"
|
||||||
/>
|
component={DetailsContainer}
|
||||||
</Switch>
|
/>
|
||||||
|
</Switch>
|
||||||
|
</ReadOnlyContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,33 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { RootState } from 'redux/interfaces';
|
import { RootState, ClusterName } from 'redux/interfaces';
|
||||||
import { fetchSchemasByClusterName } from 'redux/actions';
|
import { fetchSchemasByClusterName } from 'redux/actions';
|
||||||
import { getIsSchemaListFetching } from 'redux/reducers/schemas/selectors';
|
import { getIsSchemaListFetching } from 'redux/reducers/schemas/selectors';
|
||||||
|
import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
|
||||||
|
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
||||||
import Schemas from './Schemas';
|
import Schemas from './Schemas';
|
||||||
|
|
||||||
const mapStateToProps = (state: RootState) => ({
|
interface RouteProps {
|
||||||
|
clusterName: ClusterName;
|
||||||
|
}
|
||||||
|
|
||||||
|
type OwnProps = RouteComponentProps<RouteProps>;
|
||||||
|
|
||||||
|
const mapStateToProps = (
|
||||||
|
state: RootState,
|
||||||
|
{
|
||||||
|
match: {
|
||||||
|
params: { clusterName },
|
||||||
|
},
|
||||||
|
}: OwnProps
|
||||||
|
) => ({
|
||||||
isFetching: getIsSchemaListFetching(state),
|
isFetching: getIsSchemaListFetching(state),
|
||||||
|
isReadOnly: getClustersReadonlyStatus(clusterName)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
fetchSchemasByClusterName,
|
fetchSchemasByClusterName,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(Schemas);
|
export default withRouter(
|
||||||
|
connect(mapStateToProps, mapDispatchToProps)(Schemas)
|
||||||
|
);
|
||||||
|
|
|
@ -14,14 +14,15 @@ import OverviewContainer from './Overview/OverviewContainer';
|
||||||
import MessagesContainer from './Messages/MessagesContainer';
|
import MessagesContainer from './Messages/MessagesContainer';
|
||||||
import SettingsContainer from './Settings/SettingsContainer';
|
import SettingsContainer from './Settings/SettingsContainer';
|
||||||
import SettingsEditButton from './Settings/SettingsEditButton';
|
import SettingsEditButton from './Settings/SettingsEditButton';
|
||||||
|
import _ReadOnlyContext from '../../contexts/ReadOnlyContext';
|
||||||
|
|
||||||
interface Props extends Topic, TopicDetails {
|
interface Props extends Topic, TopicDetails {
|
||||||
clusterName: ClusterName;
|
clusterName: ClusterName;
|
||||||
topicName: TopicName;
|
topicName: TopicName;
|
||||||
isReadOnly: boolean | undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Details: React.FC<Props> = ({ clusterName, topicName, isReadOnly }) => {
|
const Details: React.FC<Props> = ({ clusterName, topicName }) => {
|
||||||
|
const ReadOnlyContext = React.useContext(_ReadOnlyContext);
|
||||||
return (
|
return (
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<div className="level">
|
<div className="level">
|
||||||
|
@ -34,7 +35,7 @@ const Details: React.FC<Props> = ({ clusterName, topicName, isReadOnly }) => {
|
||||||
{topicName}
|
{topicName}
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
{!isReadOnly && (
|
{!ReadOnlyContext.isReadOnly && (
|
||||||
<SettingsEditButton
|
<SettingsEditButton
|
||||||
to={clusterTopicsTopicEditPath(clusterName, topicName)}
|
to={clusterTopicsTopicEditPath(clusterName, topicName)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { ClusterName, RootState, TopicName } from 'redux/interfaces';
|
import { ClusterName, RootState, TopicName } from 'redux/interfaces';
|
||||||
import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
|
|
||||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||||
import Details from './Details';
|
import Details from './Details';
|
||||||
|
|
||||||
|
@ -21,7 +20,6 @@ const mapStateToProps = (
|
||||||
) => ({
|
) => ({
|
||||||
clusterName,
|
clusterName,
|
||||||
topicName,
|
topicName,
|
||||||
isReadOnly: getClustersReadonlyStatus(clusterName)(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withRouter(connect(mapStateToProps)(Details));
|
export default withRouter(connect(mapStateToProps)(Details));
|
||||||
|
|
|
@ -4,24 +4,19 @@ import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
|
||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { clusterTopicNewPath } from 'lib/paths';
|
import { clusterTopicNewPath } from 'lib/paths';
|
||||||
import ListItem from './ListItem';
|
import ListItem from './ListItem';
|
||||||
|
import _ReadOnlyContext from '../../contexts/ReadOnlyContext';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
clusterName: ClusterName;
|
clusterName: ClusterName;
|
||||||
topics: TopicWithDetailedInfo[];
|
topics: TopicWithDetailedInfo[];
|
||||||
externalTopics: TopicWithDetailedInfo[];
|
externalTopics: TopicWithDetailedInfo[];
|
||||||
isReadOnly?: boolean | undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const List: React.FC<Props> = ({
|
const List: React.FC<Props> = ({ clusterName, topics, externalTopics }) => {
|
||||||
clusterName,
|
|
||||||
topics,
|
|
||||||
externalTopics,
|
|
||||||
isReadOnly,
|
|
||||||
}) => {
|
|
||||||
const [showInternal, setShowInternal] = React.useState<boolean>(true);
|
const [showInternal, setShowInternal] = React.useState<boolean>(true);
|
||||||
|
|
||||||
const handleSwitch = () => setShowInternal(!showInternal);
|
const handleSwitch = () => setShowInternal(!showInternal);
|
||||||
|
const ReadOnlyContext = React.useContext(_ReadOnlyContext);
|
||||||
const items = showInternal ? topics : externalTopics;
|
const items = showInternal ? topics : externalTopics;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -44,7 +39,7 @@ const List: React.FC<Props> = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="level-item level-right">
|
<div className="level-item level-right">
|
||||||
{!isReadOnly && (
|
{!ReadOnlyContext.isReadOnly && (
|
||||||
<NavLink
|
<NavLink
|
||||||
className="button is-primary"
|
className="button is-primary"
|
||||||
to={clusterTopicNewPath(clusterName)}
|
to={clusterTopicNewPath(clusterName)}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {
|
||||||
getTopicList,
|
getTopicList,
|
||||||
getExternalTopicList,
|
getExternalTopicList,
|
||||||
} from 'redux/reducers/topics/selectors';
|
} from 'redux/reducers/topics/selectors';
|
||||||
import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
|
|
||||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||||
import List from './List';
|
import List from './List';
|
||||||
|
|
||||||
|
@ -25,7 +24,6 @@ const mapStateToProps = (
|
||||||
clusterName,
|
clusterName,
|
||||||
topics: getTopicList(state),
|
topics: getTopicList(state),
|
||||||
externalTopics: getExternalTopicList(state),
|
externalTopics: getExternalTopicList(state),
|
||||||
isReadOnly: getClustersReadonlyStatus(clusterName)(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withRouter(connect(mapStateToProps)(List));
|
export default withRouter(connect(mapStateToProps)(List));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { shallow } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import List from '../List';
|
import List from '../List';
|
||||||
|
import ReadOnlyContext from '../../../contexts/ReadOnlyContext';
|
||||||
|
|
||||||
describe('List', () => {
|
describe('List', () => {
|
||||||
describe('when it has readonly flag', () => {
|
describe('when it has readonly flag', () => {
|
||||||
|
@ -9,9 +10,12 @@ describe('List', () => {
|
||||||
clusterName: 'Cluster',
|
clusterName: 'Cluster',
|
||||||
topics: [],
|
topics: [],
|
||||||
externalTopics: [],
|
externalTopics: [],
|
||||||
isReadOnly: true,
|
|
||||||
};
|
};
|
||||||
const component = shallow(<List {...props} />);
|
const component = mount(
|
||||||
|
<ReadOnlyContext.Provider value={{ isReadOnly: true }}>
|
||||||
|
<List {...props} />
|
||||||
|
</ReadOnlyContext.Provider>
|
||||||
|
);
|
||||||
expect(component.exists('NavLink')).toBeFalsy();
|
expect(component.exists('NavLink')).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,18 +6,21 @@ import EditContainer from 'components/Topics/Edit/EditContainer';
|
||||||
import ListContainer from './List/ListContainer';
|
import ListContainer from './List/ListContainer';
|
||||||
import DetailsContainer from './Details/DetailsContainer';
|
import DetailsContainer from './Details/DetailsContainer';
|
||||||
import NewContainer from './New/NewContainer';
|
import NewContainer from './New/NewContainer';
|
||||||
|
import ReadOnlyContext from '../contexts/ReadOnlyContext';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
clusterName: ClusterName;
|
clusterName: ClusterName;
|
||||||
isFetched: boolean;
|
isFetched: boolean;
|
||||||
fetchBrokers: (clusterName: ClusterName) => void;
|
fetchBrokers: (clusterName: ClusterName) => void;
|
||||||
fetchTopicsList: (clusterName: ClusterName) => void;
|
fetchTopicsList: (clusterName: ClusterName) => void;
|
||||||
|
isReadOnly?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Topics: React.FC<Props> = ({
|
const Topics: React.FC<Props> = ({
|
||||||
clusterName,
|
clusterName,
|
||||||
isFetched,
|
isFetched,
|
||||||
fetchTopicsList,
|
fetchTopicsList,
|
||||||
|
isReadOnly,
|
||||||
}) => {
|
}) => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
fetchTopicsList(clusterName);
|
fetchTopicsList(clusterName);
|
||||||
|
@ -25,27 +28,29 @@ const Topics: React.FC<Props> = ({
|
||||||
|
|
||||||
if (isFetched) {
|
if (isFetched) {
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<ReadOnlyContext.Provider value={{ isReadOnly }}>
|
||||||
<Route
|
<Switch>
|
||||||
exact
|
<Route
|
||||||
path="/ui/clusters/:clusterName/topics"
|
exact
|
||||||
component={ListContainer}
|
path="/ui/clusters/:clusterName/topics"
|
||||||
/>
|
component={ListContainer}
|
||||||
<Route
|
/>
|
||||||
exact
|
<Route
|
||||||
path="/ui/clusters/:clusterName/topics/new"
|
exact
|
||||||
component={NewContainer}
|
path="/ui/clusters/:clusterName/topics/new"
|
||||||
/>
|
component={NewContainer}
|
||||||
<Route
|
/>
|
||||||
exact
|
<Route
|
||||||
path="/ui/clusters/:clusterName/topics/:topicName/edit"
|
exact
|
||||||
component={EditContainer}
|
path="/ui/clusters/:clusterName/topics/:topicName/edit"
|
||||||
/>
|
component={EditContainer}
|
||||||
<Route
|
/>
|
||||||
path="/ui/clusters/:clusterName/topics/:topicName"
|
<Route
|
||||||
component={DetailsContainer}
|
path="/ui/clusters/:clusterName/topics/:topicName"
|
||||||
/>
|
component={DetailsContainer}
|
||||||
</Switch>
|
/>
|
||||||
|
</Switch>
|
||||||
|
</ReadOnlyContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { fetchTopicsList } from 'redux/actions';
|
||||||
import { getIsTopicListFetched } from 'redux/reducers/topics/selectors';
|
import { getIsTopicListFetched } from 'redux/reducers/topics/selectors';
|
||||||
import { RootState, ClusterName } from 'redux/interfaces';
|
import { RootState, ClusterName } from 'redux/interfaces';
|
||||||
import { RouteComponentProps } from 'react-router-dom';
|
import { RouteComponentProps } from 'react-router-dom';
|
||||||
|
import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
|
||||||
import Topics from './Topics';
|
import Topics from './Topics';
|
||||||
|
|
||||||
interface RouteProps {
|
interface RouteProps {
|
||||||
|
@ -21,6 +22,7 @@ const mapStateToProps = (
|
||||||
) => ({
|
) => ({
|
||||||
isFetched: getIsTopicListFetched(state),
|
isFetched: getIsTopicListFetched(state),
|
||||||
clusterName,
|
clusterName,
|
||||||
|
isReadOnly: getClustersReadonlyStatus(clusterName)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const initialValue: { isReadOnly: boolean | undefined } = {
|
||||||
|
isReadOnly: undefined,
|
||||||
|
};
|
||||||
|
const ReadOnlyContext = React.createContext(initialValue);
|
||||||
|
|
||||||
|
export default ReadOnlyContext;
|
Loading…
Add table
Reference in a new issue