Implement readonly flag logic
This commit is contained in:
parent
a9cb9567d6
commit
93d471f408
10 changed files with 91 additions and 41 deletions
|
@ -17,6 +17,7 @@ const ClusterWidget: React.FC<ClusterWidgetProps> = ({
|
||||||
bytesInPerSec,
|
bytesInPerSec,
|
||||||
bytesOutPerSec,
|
bytesOutPerSec,
|
||||||
onlinePartitionCount,
|
onlinePartitionCount,
|
||||||
|
readOnly,
|
||||||
},
|
},
|
||||||
}) => (
|
}) => (
|
||||||
<div className="column is-full-modile is-6">
|
<div className="column is-full-modile is-6">
|
||||||
|
@ -29,6 +30,9 @@ const ClusterWidget: React.FC<ClusterWidgetProps> = ({
|
||||||
>
|
>
|
||||||
{status}
|
{status}
|
||||||
</div>
|
</div>
|
||||||
|
{readOnly && (
|
||||||
|
<div className="tag has-margin-right is-info is-light">readonly</div>
|
||||||
|
)}
|
||||||
{name}
|
{name}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ export interface DetailsProps {
|
||||||
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
|
||||||
|
@ -24,6 +25,7 @@ const Details: React.FC<DetailsProps> = ({
|
||||||
fetchSchemaVersions,
|
fetchSchemaVersions,
|
||||||
versions,
|
versions,
|
||||||
isFetched,
|
isFetched,
|
||||||
|
isReadOnly,
|
||||||
}) => {
|
}) => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
fetchSchemaVersions(clusterName, schema.subject as SchemaName);
|
fetchSchemaVersions(clusterName, schema.subject as SchemaName);
|
||||||
|
@ -54,6 +56,7 @@ const Details: React.FC<DetailsProps> = ({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{!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"
|
||||||
|
@ -72,6 +75,7 @@ const Details: React.FC<DetailsProps> = ({
|
||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<LatestVersionItem schema={schema} />
|
<LatestVersionItem schema={schema} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ const mapStateToProps = (
|
||||||
versions: getSortedSchemaVersions(state),
|
versions: getSortedSchemaVersions(state),
|
||||||
isFetched: getIsSchemaVersionFetched(state),
|
isFetched: getIsSchemaVersionFetched(state),
|
||||||
clusterName,
|
clusterName,
|
||||||
|
isReadOnly: getClustersReadonlyStatus(clusterName)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
|
|
|
@ -7,9 +7,10 @@ import ListItem from './ListItem';
|
||||||
|
|
||||||
export interface ListProps {
|
export interface ListProps {
|
||||||
schemas: SchemaSubject[];
|
schemas: SchemaSubject[];
|
||||||
|
isReadOnly?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const List: React.FC<ListProps> = ({ schemas }) => {
|
const List: React.FC<ListProps> = ({ schemas, isReadOnly }) => {
|
||||||
const { clusterName } = useParams<{ clusterName: string }>();
|
const { clusterName } = useParams<{ clusterName: string }>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -17,6 +18,7 @@ const List: React.FC<ListProps> = ({ schemas }) => {
|
||||||
<Breadcrumb>Schema Registry</Breadcrumb>
|
<Breadcrumb>Schema Registry</Breadcrumb>
|
||||||
<div className="box">
|
<div className="box">
|
||||||
<div className="level">
|
<div className="level">
|
||||||
|
{!isReadOnly && (
|
||||||
<div className="level-item level-right">
|
<div className="level-item level-right">
|
||||||
<NavLink
|
<NavLink
|
||||||
className="button is-primary"
|
className="button is-primary"
|
||||||
|
@ -25,6 +27,7 @@ const List: React.FC<ListProps> = ({ schemas }) => {
|
||||||
Create Schema
|
Create Schema
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,26 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { RootState } from 'redux/interfaces';
|
import { RootState, ClusterName } 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';
|
||||||
|
|
||||||
const mapStateToProps = (state: RootState) => ({
|
interface RouteProps {
|
||||||
|
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 connect(mapStateToProps)(List);
|
export default withRouter(connect(mapStateToProps)(List));
|
||||||
|
|
|
@ -18,9 +18,10 @@ import SettingsEditButton from './Settings/SettingsEditButton';
|
||||||
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 }) => {
|
const Details: React.FC<Props> = ({ clusterName, topicName, isReadOnly }) => {
|
||||||
return (
|
return (
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<div className="level">
|
<div className="level">
|
||||||
|
@ -33,9 +34,11 @@ const Details: React.FC<Props> = ({ clusterName, topicName }) => {
|
||||||
{topicName}
|
{topicName}
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
</div>
|
</div>
|
||||||
|
{!isReadOnly && (
|
||||||
<SettingsEditButton
|
<SettingsEditButton
|
||||||
to={clusterTopicsTopicEditPath(clusterName, topicName)}
|
to={clusterTopicsTopicEditPath(clusterName, topicName)}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="box">
|
<div className="box">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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';
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ const mapStateToProps = (
|
||||||
) => ({
|
) => ({
|
||||||
clusterName,
|
clusterName,
|
||||||
topicName,
|
topicName,
|
||||||
|
isReadOnly: getClustersReadonlyStatus(clusterName)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withRouter(connect(mapStateToProps)(Details));
|
export default withRouter(connect(mapStateToProps)(Details));
|
||||||
|
|
|
@ -9,9 +9,15 @@ interface Props {
|
||||||
clusterName: ClusterName;
|
clusterName: ClusterName;
|
||||||
topics: TopicWithDetailedInfo[];
|
topics: TopicWithDetailedInfo[];
|
||||||
externalTopics: TopicWithDetailedInfo[];
|
externalTopics: TopicWithDetailedInfo[];
|
||||||
|
isReadOnly?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const List: React.FC<Props> = ({ clusterName, topics, externalTopics }) => {
|
const List: React.FC<Props> = ({
|
||||||
|
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);
|
||||||
|
@ -38,12 +44,14 @@ const List: React.FC<Props> = ({ clusterName, topics, externalTopics }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="level-item level-right">
|
<div className="level-item level-right">
|
||||||
|
{!isReadOnly && (
|
||||||
<NavLink
|
<NavLink
|
||||||
className="button is-primary"
|
className="button is-primary"
|
||||||
to={clusterTopicNewPath(clusterName)}
|
to={clusterTopicNewPath(clusterName)}
|
||||||
>
|
>
|
||||||
Add a Topic
|
Add a Topic
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,6 +4,7 @@ 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';
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@ 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));
|
||||||
|
|
|
@ -24,3 +24,9 @@ export const getOnlineClusters = createSelector(getClusterList, (clusters) =>
|
||||||
export const getOfflineClusters = createSelector(getClusterList, (clusters) =>
|
export const getOfflineClusters = createSelector(getClusterList, (clusters) =>
|
||||||
clusters.filter(({ status }) => status === ServerStatus.OFFLINE)
|
clusters.filter(({ status }) => status === ServerStatus.OFFLINE)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const getClustersReadonlyStatus = (clusterName: string) =>
|
||||||
|
createSelector(
|
||||||
|
getClusterList,
|
||||||
|
(clusters) => clusters.find(({ name }) => name === clusterName)?.readOnly
|
||||||
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue