Jelajahi Sumber

Implement readonly flag logic

GneyHabub 4 tahun lalu
induk
melakukan
93d471f408

+ 4 - 0
kafka-ui-react-app/src/components/Dashboard/ClustersWidget/ClusterWidget.tsx

@@ -17,6 +17,7 @@ const ClusterWidget: React.FC<ClusterWidgetProps> = ({
     bytesInPerSec,
     bytesOutPerSec,
     onlinePartitionCount,
+    readOnly,
   },
 }) => (
   <div className="column is-full-modile is-6">
@@ -29,6 +30,9 @@ const ClusterWidget: React.FC<ClusterWidgetProps> = ({
         >
           {status}
         </div>
+        {readOnly && (
+          <div className="tag has-margin-right is-info is-light">readonly</div>
+        )}
         {name}
       </div>
 

+ 22 - 18
kafka-ui-react-app/src/components/Schemas/Details/Details.tsx

@@ -12,6 +12,7 @@ export interface DetailsProps {
   clusterName: ClusterName;
   versions: SchemaSubject[];
   isFetched: boolean;
+  isReadOnly?: boolean | undefined;
   fetchSchemaVersions: (
     clusterName: ClusterName,
     schemaName: SchemaName
@@ -24,6 +25,7 @@ const Details: React.FC<DetailsProps> = ({
   fetchSchemaVersions,
   versions,
   isFetched,
+  isReadOnly,
 }) => {
   React.useEffect(() => {
     fetchSchemaVersions(clusterName, schema.subject as SchemaName);
@@ -54,24 +56,26 @@ const Details: React.FC<DetailsProps> = ({
               </div>
             </div>
           </div>
-          <div className="level-right">
-            <button
-              className="button is-warning is-small level-item"
-              type="button"
-              title="in development"
-              disabled
-            >
-              Update Schema
-            </button>
-            <button
-              className="button is-danger is-small level-item"
-              type="button"
-              title="in development"
-              disabled
-            >
-              Delete
-            </button>
-          </div>
+          {!isReadOnly && (
+            <div className="level-right">
+              <button
+                className="button is-warning is-small level-item"
+                type="button"
+                title="in development"
+                disabled
+              >
+                Update Schema
+              </button>
+              <button
+                className="button is-danger is-small level-item"
+                type="button"
+                title="in development"
+                disabled
+              >
+                Delete
+              </button>
+            </div>
+          )}
         </div>
         <LatestVersionItem schema={schema} />
       </div>

+ 2 - 0
kafka-ui-react-app/src/components/Schemas/Details/DetailsContainer.ts

@@ -6,6 +6,7 @@ import {
   getSchema,
   getSortedSchemaVersions,
 } from 'redux/reducers/schemas/selectors';
+import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
 import { fetchSchemaVersions } from 'redux/actions';
 import Details from './Details';
 
@@ -28,6 +29,7 @@ const mapStateToProps = (
   versions: getSortedSchemaVersions(state),
   isFetched: getIsSchemaVersionFetched(state),
   clusterName,
+  isReadOnly: getClustersReadonlyStatus(clusterName)(state),
 });
 
 const mapDispatchToProps = {

+ 12 - 9
kafka-ui-react-app/src/components/Schemas/List/List.tsx

@@ -7,9 +7,10 @@ import ListItem from './ListItem';
 
 export interface ListProps {
   schemas: SchemaSubject[];
+  isReadOnly?: boolean | undefined;
 }
 
-const List: React.FC<ListProps> = ({ schemas }) => {
+const List: React.FC<ListProps> = ({ schemas, isReadOnly }) => {
   const { clusterName } = useParams<{ clusterName: string }>();
 
   return (
@@ -17,14 +18,16 @@ const List: React.FC<ListProps> = ({ schemas }) => {
       <Breadcrumb>Schema Registry</Breadcrumb>
       <div className="box">
         <div className="level">
-          <div className="level-item level-right">
-            <NavLink
-              className="button is-primary"
-              to={clusterSchemaNewPath(clusterName)}
-            >
-              Create Schema
-            </NavLink>
-          </div>
+          {!isReadOnly && (
+            <div className="level-item level-right">
+              <NavLink
+                className="button is-primary"
+                to={clusterSchemaNewPath(clusterName)}
+              >
+                Create Schema
+              </NavLink>
+            </div>
+          )}
         </div>
       </div>
 

+ 19 - 3
kafka-ui-react-app/src/components/Schemas/List/ListContainer.tsx

@@ -1,10 +1,26 @@
 import { connect } from 'react-redux';
-import { RootState } from 'redux/interfaces';
+import { RootState, ClusterName } from 'redux/interfaces';
 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';
 
-const mapStateToProps = (state: RootState) => ({
+interface RouteProps {
+  clusterName: ClusterName;
+}
+
+type OwnProps = RouteComponentProps<RouteProps>;
+
+const mapStateToProps = (
+  state: RootState,
+  {
+    match: {
+      params: { clusterName },
+    },
+  }: OwnProps
+) => ({
   schemas: getSchemaList(state),
+  isReadOnly: getClustersReadonlyStatus(clusterName)(state),
 });
 
-export default connect(mapStateToProps)(List);
+export default withRouter(connect(mapStateToProps)(List));

+ 7 - 4
kafka-ui-react-app/src/components/Topics/Details/Details.tsx

@@ -18,9 +18,10 @@ import SettingsEditButton from './Settings/SettingsEditButton';
 interface Props extends Topic, TopicDetails {
   clusterName: ClusterName;
   topicName: TopicName;
+  isReadOnly: boolean | undefined;
 }
 
-const Details: React.FC<Props> = ({ clusterName, topicName }) => {
+const Details: React.FC<Props> = ({ clusterName, topicName, isReadOnly }) => {
   return (
     <div className="section">
       <div className="level">
@@ -33,9 +34,11 @@ const Details: React.FC<Props> = ({ clusterName, topicName }) => {
             {topicName}
           </Breadcrumb>
         </div>
-        <SettingsEditButton
-          to={clusterTopicsTopicEditPath(clusterName, topicName)}
-        />
+        {!isReadOnly && (
+          <SettingsEditButton
+            to={clusterTopicsTopicEditPath(clusterName, topicName)}
+          />
+        )}
       </div>
 
       <div className="box">

+ 2 - 0
kafka-ui-react-app/src/components/Topics/Details/DetailsContainer.ts

@@ -1,5 +1,6 @@
 import { connect } from 'react-redux';
 import { ClusterName, RootState, TopicName } from 'redux/interfaces';
+import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
 import { withRouter, RouteComponentProps } from 'react-router-dom';
 import Details from './Details';
 
@@ -20,6 +21,7 @@ const mapStateToProps = (
 ) => ({
   clusterName,
   topicName,
+  isReadOnly: getClustersReadonlyStatus(clusterName)(state),
 });
 
 export default withRouter(connect(mapStateToProps)(Details));

+ 15 - 7
kafka-ui-react-app/src/components/Topics/List/List.tsx

@@ -9,9 +9,15 @@ interface Props {
   clusterName: ClusterName;
   topics: 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 handleSwitch = () => setShowInternal(!showInternal);
@@ -38,12 +44,14 @@ const List: React.FC<Props> = ({ clusterName, topics, externalTopics }) => {
             </div>
           </div>
           <div className="level-item level-right">
-            <NavLink
-              className="button is-primary"
-              to={clusterTopicNewPath(clusterName)}
-            >
-              Add a Topic
-            </NavLink>
+            {!isReadOnly && (
+              <NavLink
+                className="button is-primary"
+                to={clusterTopicNewPath(clusterName)}
+              >
+                Add a Topic
+              </NavLink>
+            )}
           </div>
         </div>
       </div>

+ 2 - 0
kafka-ui-react-app/src/components/Topics/List/ListContainer.ts

@@ -4,6 +4,7 @@ import {
   getTopicList,
   getExternalTopicList,
 } from 'redux/reducers/topics/selectors';
+import { getClustersReadonlyStatus } from 'redux/reducers/clusters/selectors';
 import { withRouter, RouteComponentProps } from 'react-router-dom';
 import List from './List';
 
@@ -24,6 +25,7 @@ const mapStateToProps = (
   clusterName,
   topics: getTopicList(state),
   externalTopics: getExternalTopicList(state),
+  isReadOnly: getClustersReadonlyStatus(clusterName)(state),
 });
 
 export default withRouter(connect(mapStateToProps)(List));

+ 6 - 0
kafka-ui-react-app/src/redux/reducers/clusters/selectors.ts

@@ -24,3 +24,9 @@ export const getOnlineClusters = createSelector(getClusterList, (clusters) =>
 export const getOfflineClusters = createSelector(getClusterList, (clusters) =>
   clusters.filter(({ status }) => status === ServerStatus.OFFLINE)
 );
+
+export const getClustersReadonlyStatus = (clusterName: string) =>
+  createSelector(
+    getClusterList,
+    (clusters) => clusters.find(({ name }) => name === clusterName)?.readOnly
+  );