Explorar o código

refactor index page for schema reg

Oleg Shuralev %!s(int64=4) %!d(string=hai) anos
pai
achega
b3b4fcc933

+ 37 - 21
kafka-ui-react-app/src/components/Schemas/List/List.tsx

@@ -2,16 +2,28 @@ import React from 'react';
 import { SchemaSubject } from 'generated-sources';
 import { NavLink, useParams } from 'react-router-dom';
 import { clusterSchemaNewPath } from 'lib/paths';
+import { ClusterName } from 'redux/interfaces';
+import PageLoader from 'components/common/PageLoader/PageLoader';
 import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
 import ListItem from './ListItem';
 
 export interface ListProps {
   schemas: SchemaSubject[];
+  isFetching: boolean;
+  fetchSchemasByClusterName: (clusterName: ClusterName) => void;
 }
 
-const List: React.FC<ListProps> = ({ schemas }) => {
+const List: React.FC<ListProps> = ({
+  schemas,
+  isFetching,
+  fetchSchemasByClusterName,
+}) => {
   const { clusterName } = useParams<{ clusterName: string }>();
 
+  React.useEffect(() => {
+    fetchSchemasByClusterName(clusterName);
+  }, [fetchSchemasByClusterName, clusterName]);
+
   return (
     <div className="section">
       <Breadcrumb>Schema Registry</Breadcrumb>
@@ -28,28 +40,32 @@ const List: React.FC<ListProps> = ({ schemas }) => {
         </div>
       </div>
 
-      <div className="box">
-        <table className="table is-striped is-fullwidth">
-          <thead>
-            <tr>
-              <th>Schema Name</th>
-              <th>Version</th>
-              <th>Compatibility</th>
-            </tr>
-          </thead>
-          <tbody>
-            {schemas.length > 0 ? (
-              schemas.map((subject) => (
-                <ListItem key={subject.id} subject={subject} />
-              ))
-            ) : (
+      {isFetching ? (
+        <PageLoader />
+      ) : (
+        <div className="box">
+          <table className="table is-striped is-fullwidth">
+            <thead>
               <tr>
-                <td colSpan={10}>No schemas found</td>
+                <th>Schema Name</th>
+                <th>Version</th>
+                <th>Compatibility</th>
               </tr>
-            )}
-          </tbody>
-        </table>
-      </div>
+            </thead>
+            <tbody>
+              {schemas.length > 0 ? (
+                schemas.map((subject) => (
+                  <ListItem key={subject.id} subject={subject} />
+                ))
+              ) : (
+                <tr>
+                  <td colSpan={10}>No schemas found</td>
+                </tr>
+              )}
+            </tbody>
+          </table>
+        </div>
+      )}
     </div>
   );
 };

+ 11 - 2
kafka-ui-react-app/src/components/Schemas/List/ListContainer.tsx

@@ -1,10 +1,19 @@
 import { connect } from 'react-redux';
 import { RootState } from 'redux/interfaces';
-import { getSchemaList } from 'redux/reducers/schemas/selectors';
+import { fetchSchemasByClusterName } from 'redux/actions';
+import {
+  getIsSchemaListFetching,
+  getSchemaList,
+} from 'redux/reducers/schemas/selectors';
 import List from './List';
 
 const mapStateToProps = (state: RootState) => ({
+  isFetching: getIsSchemaListFetching(state),
   schemas: getSchemaList(state),
 });
 
-export default connect(mapStateToProps)(List);
+const mapDispatchToProps = {
+  fetchSchemasByClusterName,
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(List);

+ 40 - 3
kafka-ui-react-app/src/components/Schemas/List/__test__/List.spec.tsx

@@ -27,13 +27,50 @@ describe('List', () => {
 
     const setupWrapper = (props: Partial<ListProps> = {}) => (
       <StaticRouter location={{ pathname }} context={{}}>
-        <List schemas={[]} {...props} />
+        <List
+          isFetching
+          fetchSchemasByClusterName={jest.fn()}
+          schemas={[]}
+          {...props}
+        />
       </StaticRouter>
     );
 
+    describe('Initial state', () => {
+      let useEffect: jest.SpyInstance<
+        void,
+        [effect: React.EffectCallback, deps?: React.DependencyList | undefined]
+      >;
+      const mockedFn = jest.fn();
+
+      const mockedUseEffect = () => {
+        useEffect.mockImplementationOnce(mockedFn);
+      };
+
+      beforeEach(() => {
+        useEffect = jest.spyOn(React, 'useEffect');
+        mockedUseEffect();
+      });
+
+      it('should call fetchSchemasByClusterName every render', () => {
+        mount(setupWrapper({ fetchSchemasByClusterName: mockedFn }));
+        expect(mockedFn).toHaveBeenCalled();
+      });
+    });
+
+    describe('when fetching', () => {
+      it('renders PageLoader', () => {
+        const wrapper = mount(setupWrapper({ isFetching: true }));
+        expect(wrapper.exists('Breadcrumb')).toBeTruthy();
+        expect(wrapper.exists('thead')).toBeFalsy();
+        expect(wrapper.exists('ListItem')).toBeFalsy();
+        expect(wrapper.exists('PageLoader')).toBeTruthy();
+      });
+    });
+
     describe('without schemas', () => {
       it('renders table heading without ListItem', () => {
-        const wrapper = mount(setupWrapper());
+        const wrapper = mount(setupWrapper({ isFetching: false }));
         expect(wrapper.exists('Breadcrumb')).toBeTruthy();
         expect(wrapper.exists('thead')).toBeTruthy();
         expect(wrapper.exists('ListItem')).toBeFalsy();
@@ -41,7 +78,7 @@ describe('List', () => {
     });
 
     describe('with schemas', () => {
-      const wrapper = mount(setupWrapper({ schemas }));
+      const wrapper = mount(setupWrapper({ isFetching: false, schemas }));
 
       it('renders table heading with ListItem', () => {
         expect(wrapper.exists('Breadcrumb')).toBeTruthy();

+ 20 - 42
kafka-ui-react-app/src/components/Schemas/Schemas.tsx

@@ -1,49 +1,27 @@
 import React from 'react';
-import { ClusterName } from 'redux/interfaces';
-import { Switch, Route, useParams } from 'react-router-dom';
-import PageLoader from 'components/common/PageLoader/PageLoader';
+import { Switch, Route } from 'react-router-dom';
 import ListContainer from './List/ListContainer';
 import DetailsContainer from './Details/DetailsContainer';
 import NewContainer from './New/NewContainer';
 
-export interface SchemasProps {
-  isFetching: boolean;
-  fetchSchemasByClusterName: (clusterName: ClusterName) => void;
-}
-
-const Schemas: React.FC<SchemasProps> = ({
-  isFetching,
-  fetchSchemasByClusterName,
-}) => {
-  const { clusterName } = useParams<{ clusterName: string }>();
-
-  React.useEffect(() => {
-    fetchSchemasByClusterName(clusterName);
-  }, [fetchSchemasByClusterName, clusterName]);
-
-  if (isFetching) {
-    return <PageLoader />;
-  }
-
-  return (
-    <Switch>
-      <Route
-        exact
-        path="/ui/clusters/:clusterName/schemas"
-        component={ListContainer}
-      />
-      <Route
-        exact
-        path="/ui/clusters/:clusterName/schemas/new"
-        component={NewContainer}
-      />
-      <Route
-        exact
-        path="/ui/clusters/:clusterName/schemas/:subject/latest"
-        component={DetailsContainer}
-      />
-    </Switch>
-  );
-};
+const Schemas: React.FC = () => (
+  <Switch>
+    <Route
+      exact
+      path="/ui/clusters/:clusterName/schemas"
+      component={ListContainer}
+    />
+    <Route
+      exact
+      path="/ui/clusters/:clusterName/schemas/new"
+      component={NewContainer}
+    />
+    <Route
+      exact
+      path="/ui/clusters/:clusterName/schemas/:subject/latest"
+      component={DetailsContainer}
+    />
+  </Switch>
+);
 
 export default Schemas;

+ 0 - 15
kafka-ui-react-app/src/components/Schemas/SchemasContainer.tsx

@@ -1,15 +0,0 @@
-import { connect } from 'react-redux';
-import { RootState } from 'redux/interfaces';
-import { fetchSchemasByClusterName } from 'redux/actions';
-import { getIsSchemaListFetching } from 'redux/reducers/schemas/selectors';
-import Schemas from './Schemas';
-
-const mapStateToProps = (state: RootState) => ({
-  isFetching: getIsSchemaListFetching(state),
-});
-
-const mapDispatchToProps = {
-  fetchSchemasByClusterName,
-};
-
-export default connect(mapStateToProps, mapDispatchToProps)(Schemas);

+ 9 - 62
kafka-ui-react-app/src/components/Schemas/__test__/Schemas.spec.tsx

@@ -1,71 +1,18 @@
 import React from 'react';
-import { Provider } from 'react-redux';
-import { mount } from 'enzyme';
-import configureStore from 'redux/store/configureStore';
+import { shallow } from 'enzyme';
 import { StaticRouter } from 'react-router-dom';
-import Schemas, { SchemasProps } from '../Schemas';
-import SchemasContainer from '../SchemasContainer';
+import Schemas from '../Schemas';
 
 describe('Schemas', () => {
   const pathname = `/ui/clusters/clusterName/schemas`;
 
-  describe('Container', () => {
-    const store = configureStore();
+  it('renders', () => {
+    const wrapper = shallow(
+      <StaticRouter location={{ pathname }} context={{}}>
+        <Schemas />
+      </StaticRouter>
+    );
 
-    it('renders view', () => {
-      const component = mount(
-        <Provider store={store}>
-          <StaticRouter location={{ pathname }} context={{}}>
-            <SchemasContainer />
-          </StaticRouter>
-        </Provider>
-      );
-
-      expect(component.exists()).toBeTruthy();
-    });
-
-    describe('View', () => {
-      const setupWrapper = (props: Partial<SchemasProps> = {}) => (
-        <StaticRouter location={{ pathname }} context={{}}>
-          <Schemas
-            isFetching
-            fetchSchemasByClusterName={jest.fn()}
-            {...props}
-          />
-        </StaticRouter>
-      );
-      describe('Initial state', () => {
-        let useEffect: jest.SpyInstance<
-          void,
-          [
-            effect: React.EffectCallback,
-            deps?: React.DependencyList | undefined
-          ]
-        >;
-        const mockedFn = jest.fn();
-
-        const mockedUseEffect = () => {
-          useEffect.mockImplementationOnce(mockedFn);
-        };
-
-        beforeEach(() => {
-          useEffect = jest.spyOn(React, 'useEffect');
-          mockedUseEffect();
-        });
-
-        it('should call fetchSchemasByClusterName every render', () => {
-          mount(setupWrapper({ fetchSchemasByClusterName: mockedFn }));
-          expect(mockedFn).toHaveBeenCalled();
-        });
-      });
-
-      describe('when page is loading', () => {
-        const wrapper = mount(setupWrapper({ isFetching: true }));
-
-        it('renders PageLoader', () => {
-          expect(wrapper.exists('PageLoader')).toBeTruthy();
-        });
-      });
-    });
+    expect(wrapper.exists('Schemas')).toBeTruthy();
   });
 });