ソースを参照

Split thunks on files. Refactoring

Oleg Shuralev 4 年 前
コミット
449bf56f8f

+ 2 - 2
kafka-ui-react-app/src/redux/actions/actions.ts

@@ -1,5 +1,5 @@
 import { createAsyncAction } from 'typesafe-actions';
-import { TopicName, ConsumerGroupID } from 'redux/interfaces';
+import { TopicName, ConsumerGroupID, TopicsState } from 'redux/interfaces';
 
 import {
   Cluster,
@@ -50,7 +50,7 @@ export const fetchTopicsListAction = createAsyncAction(
   'GET_TOPICS__REQUEST',
   'GET_TOPICS__SUCCESS',
   'GET_TOPICS__FAILURE'
-)<undefined, Topic[], undefined>();
+)<undefined, TopicsState, undefined>();
 
 export const fetchTopicMessagesAction = createAsyncAction(
   'GET_TOPIC_MESSAGES__REQUEST',

+ 0 - 318
kafka-ui-react-app/src/redux/actions/thunks.ts

@@ -1,318 +0,0 @@
-import {
-  ClustersApi,
-  BrokersApi,
-  TopicsApi,
-  ConsumerGroupsApi,
-  SchemasApi,
-  MessagesApi,
-  Configuration,
-  Cluster,
-  Topic,
-  TopicFormData,
-  TopicConfig,
-  NewSchemaSubject,
-  SchemaSubject,
-} from 'generated-sources';
-import {
-  ConsumerGroupID,
-  PromiseThunkResult,
-  ClusterName,
-  BrokerId,
-  TopicName,
-  TopicMessageQueryParams,
-  TopicFormFormattedParams,
-  TopicFormDataRaw,
-  SchemaName,
-} from 'redux/interfaces';
-
-import { BASE_PARAMS } from 'lib/constants';
-import * as actions from './actions';
-
-const apiClientConf = new Configuration(BASE_PARAMS);
-export const clustersApiClient = new ClustersApi(apiClientConf);
-export const brokersApiClient = new BrokersApi(apiClientConf);
-export const topicsApiClient = new TopicsApi(apiClientConf);
-export const consumerGroupsApiClient = new ConsumerGroupsApi(apiClientConf);
-export const schemasApiClient = new SchemasApi(apiClientConf);
-export const messagesApiClient = new MessagesApi(apiClientConf);
-
-export const fetchClustersList = (): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchClusterListAction.request());
-  try {
-    const clusters: Cluster[] = await clustersApiClient.getClusters();
-    dispatch(actions.fetchClusterListAction.success(clusters));
-  } catch (e) {
-    dispatch(actions.fetchClusterListAction.failure());
-  }
-};
-
-export const fetchClusterStats = (
-  clusterName: ClusterName
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchClusterStatsAction.request());
-  try {
-    const payload = await clustersApiClient.getClusterStats({ clusterName });
-    dispatch(actions.fetchClusterStatsAction.success(payload));
-  } catch (e) {
-    dispatch(actions.fetchClusterStatsAction.failure());
-  }
-};
-
-export const fetchClusterMetrics = (
-  clusterName: ClusterName
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchClusterMetricsAction.request());
-  try {
-    const payload = await clustersApiClient.getClusterMetrics({ clusterName });
-    dispatch(actions.fetchClusterMetricsAction.success(payload));
-  } catch (e) {
-    dispatch(actions.fetchClusterMetricsAction.failure());
-  }
-};
-
-export const fetchBrokers = (
-  clusterName: ClusterName
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchBrokersAction.request());
-  try {
-    const payload = await brokersApiClient.getBrokers({ clusterName });
-    dispatch(actions.fetchBrokersAction.success(payload));
-  } catch (e) {
-    dispatch(actions.fetchBrokersAction.failure());
-  }
-};
-
-export const fetchBrokerMetrics = (
-  clusterName: ClusterName,
-  brokerId: BrokerId
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchBrokerMetricsAction.request());
-  try {
-    const payload = await brokersApiClient.getBrokersMetrics({
-      clusterName,
-      id: brokerId,
-    });
-    dispatch(actions.fetchBrokerMetricsAction.success(payload));
-  } catch (e) {
-    dispatch(actions.fetchBrokerMetricsAction.failure());
-  }
-};
-
-export const fetchTopicsList = (
-  clusterName: ClusterName
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchTopicsListAction.request());
-  try {
-    const topics = await topicsApiClient.getTopics({ clusterName });
-    dispatch(actions.fetchTopicsListAction.success(topics.topics || []));
-  } catch (e) {
-    dispatch(actions.fetchTopicsListAction.failure());
-  }
-};
-
-export const fetchTopicMessages = (
-  clusterName: ClusterName,
-  topicName: TopicName,
-  queryParams: Partial<TopicMessageQueryParams>
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchTopicMessagesAction.request());
-  try {
-    const messages = await messagesApiClient.getTopicMessages({
-      clusterName,
-      topicName,
-      ...queryParams,
-    });
-    dispatch(actions.fetchTopicMessagesAction.success(messages));
-  } catch (e) {
-    dispatch(actions.fetchTopicMessagesAction.failure());
-  }
-};
-
-export const fetchTopicDetails = (
-  clusterName: ClusterName,
-  topicName: TopicName
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchTopicDetailsAction.request());
-  try {
-    const topicDetails = await topicsApiClient.getTopicDetails({
-      clusterName,
-      topicName,
-    });
-    dispatch(
-      actions.fetchTopicDetailsAction.success({
-        topicName,
-        details: topicDetails,
-      })
-    );
-  } catch (e) {
-    dispatch(actions.fetchTopicDetailsAction.failure());
-  }
-};
-
-export const fetchTopicConfig = (
-  clusterName: ClusterName,
-  topicName: TopicName
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchTopicConfigAction.request());
-  try {
-    const config = await topicsApiClient.getTopicConfigs({
-      clusterName,
-      topicName,
-    });
-    dispatch(actions.fetchTopicConfigAction.success({ topicName, config }));
-  } catch (e) {
-    dispatch(actions.fetchTopicConfigAction.failure());
-  }
-};
-
-const formatTopicFormData = (form: TopicFormDataRaw): TopicFormData => {
-  const {
-    name,
-    partitions,
-    replicationFactor,
-    cleanupPolicy,
-    retentionBytes,
-    retentionMs,
-    maxMessageBytes,
-    minInSyncReplicas,
-    customParams,
-  } = form;
-
-  return {
-    name,
-    partitions,
-    replicationFactor,
-    configs: {
-      'cleanup.policy': cleanupPolicy,
-      'retention.ms': retentionMs,
-      'retention.bytes': retentionBytes,
-      'max.message.bytes': maxMessageBytes,
-      'min.insync.replicas': minInSyncReplicas,
-      ...Object.values(customParams || {}).reduce(
-        (result: TopicFormFormattedParams, customParam: TopicConfig) => {
-          return {
-            ...result,
-            [customParam.name]: customParam.value,
-          };
-        },
-        {}
-      ),
-    },
-  };
-};
-
-export const createTopic = (
-  clusterName: ClusterName,
-  form: TopicFormDataRaw
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.createTopicAction.request());
-  try {
-    const topic: Topic = await topicsApiClient.createTopic({
-      clusterName,
-      topicFormData: formatTopicFormData(form),
-    });
-    dispatch(actions.createTopicAction.success(topic));
-  } catch (e) {
-    dispatch(actions.createTopicAction.failure());
-  }
-};
-
-export const updateTopic = (
-  clusterName: ClusterName,
-  form: TopicFormDataRaw
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.updateTopicAction.request());
-  try {
-    const topic: Topic = await topicsApiClient.updateTopic({
-      clusterName,
-      topicName: form.name,
-      topicFormData: formatTopicFormData(form),
-    });
-    dispatch(actions.updateTopicAction.success(topic));
-  } catch (e) {
-    dispatch(actions.updateTopicAction.failure());
-  }
-};
-
-export const fetchConsumerGroupsList = (
-  clusterName: ClusterName
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchConsumerGroupsAction.request());
-  try {
-    const consumerGroups = await consumerGroupsApiClient.getConsumerGroups({
-      clusterName,
-    });
-    dispatch(actions.fetchConsumerGroupsAction.success(consumerGroups));
-  } catch (e) {
-    dispatch(actions.fetchConsumerGroupsAction.failure());
-  }
-};
-
-export const fetchConsumerGroupDetails = (
-  clusterName: ClusterName,
-  consumerGroupID: ConsumerGroupID
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.fetchConsumerGroupDetailsAction.request());
-  try {
-    const consumerGroupDetails = await consumerGroupsApiClient.getConsumerGroup(
-      {
-        clusterName,
-        id: consumerGroupID,
-      }
-    );
-    dispatch(
-      actions.fetchConsumerGroupDetailsAction.success({
-        consumerGroupID,
-        details: consumerGroupDetails,
-      })
-    );
-  } catch (e) {
-    dispatch(actions.fetchConsumerGroupDetailsAction.failure());
-  }
-};
-
-export const fetchSchemasByClusterName = (
-  clusterName: ClusterName
-): PromiseThunkResult<void> => async (dispatch) => {
-  dispatch(actions.fetchSchemasByClusterNameAction.request());
-  try {
-    const schemas = await schemasApiClient.getSchemas({ clusterName });
-    dispatch(actions.fetchSchemasByClusterNameAction.success(schemas));
-  } catch (e) {
-    dispatch(actions.fetchSchemasByClusterNameAction.failure());
-  }
-};
-
-export const fetchSchemaVersions = (
-  clusterName: ClusterName,
-  subject: SchemaName
-): PromiseThunkResult<void> => async (dispatch) => {
-  if (!subject) return;
-  dispatch(actions.fetchSchemaVersionsAction.request());
-  try {
-    const versions = await schemasApiClient.getAllVersionsBySubject({
-      clusterName,
-      subject,
-    });
-    dispatch(actions.fetchSchemaVersionsAction.success(versions));
-  } catch (e) {
-    dispatch(actions.fetchSchemaVersionsAction.failure());
-  }
-};
-
-export const createSchema = (
-  clusterName: ClusterName,
-  newSchemaSubject: NewSchemaSubject
-): PromiseThunkResult => async (dispatch) => {
-  dispatch(actions.createSchemaAction.request());
-  try {
-    const schema: SchemaSubject = await schemasApiClient.createNewSchema({
-      clusterName,
-      newSchemaSubject,
-    });
-    dispatch(actions.createSchemaAction.success(schema));
-  } catch (e) {
-    dispatch(actions.createSchemaAction.failure());
-    throw e;
-  }
-};

+ 36 - 0
kafka-ui-react-app/src/redux/actions/thunks/brokers.ts

@@ -0,0 +1,36 @@
+import { BrokersApi, Configuration } from 'generated-sources';
+import { PromiseThunkResult, ClusterName, BrokerId } from 'redux/interfaces';
+
+import { BASE_PARAMS } from 'lib/constants';
+import * as actions from '../actions';
+
+const apiClientConf = new Configuration(BASE_PARAMS);
+export const brokersApiClient = new BrokersApi(apiClientConf);
+
+export const fetchBrokers = (
+  clusterName: ClusterName
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchBrokersAction.request());
+  try {
+    const payload = await brokersApiClient.getBrokers({ clusterName });
+    dispatch(actions.fetchBrokersAction.success(payload));
+  } catch (e) {
+    dispatch(actions.fetchBrokersAction.failure());
+  }
+};
+
+export const fetchBrokerMetrics = (
+  clusterName: ClusterName,
+  brokerId: BrokerId
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchBrokerMetricsAction.request());
+  try {
+    const payload = await brokersApiClient.getBrokersMetrics({
+      clusterName,
+      id: brokerId,
+    });
+    dispatch(actions.fetchBrokerMetricsAction.success(payload));
+  } catch (e) {
+    dispatch(actions.fetchBrokerMetricsAction.failure());
+  }
+};

+ 42 - 0
kafka-ui-react-app/src/redux/actions/thunks/clusters.ts

@@ -0,0 +1,42 @@
+import { ClustersApi, Configuration, Cluster } from 'generated-sources';
+import { PromiseThunkResult, ClusterName } from 'redux/interfaces';
+
+import { BASE_PARAMS } from 'lib/constants';
+import * as actions from '../actions';
+
+const apiClientConf = new Configuration(BASE_PARAMS);
+export const clustersApiClient = new ClustersApi(apiClientConf);
+
+export const fetchClustersList = (): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchClusterListAction.request());
+  try {
+    const clusters: Cluster[] = await clustersApiClient.getClusters();
+    dispatch(actions.fetchClusterListAction.success(clusters));
+  } catch (e) {
+    dispatch(actions.fetchClusterListAction.failure());
+  }
+};
+
+export const fetchClusterStats = (
+  clusterName: ClusterName
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchClusterStatsAction.request());
+  try {
+    const payload = await clustersApiClient.getClusterStats({ clusterName });
+    dispatch(actions.fetchClusterStatsAction.success(payload));
+  } catch (e) {
+    dispatch(actions.fetchClusterStatsAction.failure());
+  }
+};
+
+export const fetchClusterMetrics = (
+  clusterName: ClusterName
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchClusterMetricsAction.request());
+  try {
+    const payload = await clustersApiClient.getClusterMetrics({ clusterName });
+    dispatch(actions.fetchClusterMetricsAction.success(payload));
+  } catch (e) {
+    dispatch(actions.fetchClusterMetricsAction.failure());
+  }
+};

+ 49 - 0
kafka-ui-react-app/src/redux/actions/thunks/consumerGroups.ts

@@ -0,0 +1,49 @@
+import { ConsumerGroupsApi, Configuration } from 'generated-sources';
+import {
+  ConsumerGroupID,
+  PromiseThunkResult,
+  ClusterName,
+} from 'redux/interfaces';
+
+import { BASE_PARAMS } from 'lib/constants';
+import * as actions from '../actions';
+
+const apiClientConf = new Configuration(BASE_PARAMS);
+export const consumerGroupsApiClient = new ConsumerGroupsApi(apiClientConf);
+
+export const fetchConsumerGroupsList = (
+  clusterName: ClusterName
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchConsumerGroupsAction.request());
+  try {
+    const consumerGroups = await consumerGroupsApiClient.getConsumerGroups({
+      clusterName,
+    });
+    dispatch(actions.fetchConsumerGroupsAction.success(consumerGroups));
+  } catch (e) {
+    dispatch(actions.fetchConsumerGroupsAction.failure());
+  }
+};
+
+export const fetchConsumerGroupDetails = (
+  clusterName: ClusterName,
+  consumerGroupID: ConsumerGroupID
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchConsumerGroupDetailsAction.request());
+  try {
+    const consumerGroupDetails = await consumerGroupsApiClient.getConsumerGroup(
+      {
+        clusterName,
+        id: consumerGroupID,
+      }
+    );
+    dispatch(
+      actions.fetchConsumerGroupDetailsAction.success({
+        consumerGroupID,
+        details: consumerGroupDetails,
+      })
+    );
+  } catch (e) {
+    dispatch(actions.fetchConsumerGroupDetailsAction.failure());
+  }
+};

+ 5 - 0
kafka-ui-react-app/src/redux/actions/thunks/index.ts

@@ -0,0 +1,5 @@
+export * from './brokers';
+export * from './clusters';
+export * from './consumerGroups';
+export * from './schemas';
+export * from './topics';

+ 59 - 0
kafka-ui-react-app/src/redux/actions/thunks/schemas.ts

@@ -0,0 +1,59 @@
+import {
+  SchemasApi,
+  Configuration,
+  NewSchemaSubject,
+  SchemaSubject,
+} from 'generated-sources';
+import { PromiseThunkResult, ClusterName, SchemaName } from 'redux/interfaces';
+
+import { BASE_PARAMS } from 'lib/constants';
+import * as actions from '../actions';
+
+const apiClientConf = new Configuration(BASE_PARAMS);
+export const schemasApiClient = new SchemasApi(apiClientConf);
+
+export const fetchSchemasByClusterName = (
+  clusterName: ClusterName
+): PromiseThunkResult<void> => async (dispatch) => {
+  dispatch(actions.fetchSchemasByClusterNameAction.request());
+  try {
+    const schemas = await schemasApiClient.getSchemas({ clusterName });
+    dispatch(actions.fetchSchemasByClusterNameAction.success(schemas));
+  } catch (e) {
+    dispatch(actions.fetchSchemasByClusterNameAction.failure());
+  }
+};
+
+export const fetchSchemaVersions = (
+  clusterName: ClusterName,
+  subject: SchemaName
+): PromiseThunkResult<void> => async (dispatch) => {
+  if (!subject) return;
+  dispatch(actions.fetchSchemaVersionsAction.request());
+  try {
+    const versions = await schemasApiClient.getAllVersionsBySubject({
+      clusterName,
+      subject,
+    });
+    dispatch(actions.fetchSchemaVersionsAction.success(versions));
+  } catch (e) {
+    dispatch(actions.fetchSchemaVersionsAction.failure());
+  }
+};
+
+export const createSchema = (
+  clusterName: ClusterName,
+  newSchemaSubject: NewSchemaSubject
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.createSchemaAction.request());
+  try {
+    const schema: SchemaSubject = await schemasApiClient.createNewSchema({
+      clusterName,
+      newSchemaSubject,
+    });
+    dispatch(actions.createSchemaAction.success(schema));
+  } catch (e) {
+    dispatch(actions.createSchemaAction.failure());
+    throw e;
+  }
+};

+ 196 - 0
kafka-ui-react-app/src/redux/actions/thunks/topics.ts

@@ -0,0 +1,196 @@
+import { v4 } from 'uuid';
+import {
+  TopicsApi,
+  MessagesApi,
+  Configuration,
+  Topic,
+  TopicFormData,
+  TopicConfig,
+} from 'generated-sources';
+import {
+  PromiseThunkResult,
+  ClusterName,
+  TopicName,
+  TopicMessageQueryParams,
+  TopicFormFormattedParams,
+  TopicFormDataRaw,
+  TopicsState,
+} from 'redux/interfaces';
+
+import { BASE_PARAMS } from 'lib/constants';
+import * as actions from '../actions';
+
+const apiClientConf = new Configuration(BASE_PARAMS);
+export const topicsApiClient = new TopicsApi(apiClientConf);
+export const messagesApiClient = new MessagesApi(apiClientConf);
+
+export interface FetchTopicsListParams {
+  clusterName: ClusterName;
+  page?: number;
+  perPage?: number;
+}
+
+export const fetchTopicsList = ({
+  clusterName,
+  page,
+  perPage,
+}: FetchTopicsListParams): PromiseThunkResult => async (dispatch, getState) => {
+  dispatch(actions.fetchTopicsListAction.request());
+  try {
+    const { topics, pageCount } = await topicsApiClient.getTopics({
+      clusterName,
+      page,
+      perPage,
+    });
+
+    const initialMemo: TopicsState = {
+      ...getState().topics,
+      allNames: [],
+      totalPages: pageCount || 1,
+    };
+
+    const state = (topics || []).reduce(
+      (memo: TopicsState, topic) => ({
+        ...memo,
+        byName: {
+          ...memo.byName,
+          [topic.name]: {
+            ...memo.byName[topic.name],
+            ...topic,
+            id: v4(),
+          },
+        },
+        allNames: [...memo.allNames, topic.name],
+      }),
+      initialMemo
+    );
+
+    dispatch(actions.fetchTopicsListAction.success(state));
+  } catch (e) {
+    dispatch(actions.fetchTopicsListAction.failure());
+  }
+};
+
+export const fetchTopicMessages = (
+  clusterName: ClusterName,
+  topicName: TopicName,
+  queryParams: Partial<TopicMessageQueryParams>
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchTopicMessagesAction.request());
+  try {
+    const messages = await messagesApiClient.getTopicMessages({
+      clusterName,
+      topicName,
+      ...queryParams,
+    });
+    dispatch(actions.fetchTopicMessagesAction.success(messages));
+  } catch (e) {
+    dispatch(actions.fetchTopicMessagesAction.failure());
+  }
+};
+
+export const fetchTopicDetails = (
+  clusterName: ClusterName,
+  topicName: TopicName
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchTopicDetailsAction.request());
+  try {
+    const topicDetails = await topicsApiClient.getTopicDetails({
+      clusterName,
+      topicName,
+    });
+    dispatch(
+      actions.fetchTopicDetailsAction.success({
+        topicName,
+        details: topicDetails,
+      })
+    );
+  } catch (e) {
+    dispatch(actions.fetchTopicDetailsAction.failure());
+  }
+};
+
+export const fetchTopicConfig = (
+  clusterName: ClusterName,
+  topicName: TopicName
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.fetchTopicConfigAction.request());
+  try {
+    const config = await topicsApiClient.getTopicConfigs({
+      clusterName,
+      topicName,
+    });
+    dispatch(actions.fetchTopicConfigAction.success({ topicName, config }));
+  } catch (e) {
+    dispatch(actions.fetchTopicConfigAction.failure());
+  }
+};
+
+const formatTopicFormData = (form: TopicFormDataRaw): TopicFormData => {
+  const {
+    name,
+    partitions,
+    replicationFactor,
+    cleanupPolicy,
+    retentionBytes,
+    retentionMs,
+    maxMessageBytes,
+    minInSyncReplicas,
+    customParams,
+  } = form;
+
+  return {
+    name,
+    partitions,
+    replicationFactor,
+    configs: {
+      'cleanup.policy': cleanupPolicy,
+      'retention.ms': retentionMs,
+      'retention.bytes': retentionBytes,
+      'max.message.bytes': maxMessageBytes,
+      'min.insync.replicas': minInSyncReplicas,
+      ...Object.values(customParams || {}).reduce(
+        (result: TopicFormFormattedParams, customParam: TopicConfig) => {
+          return {
+            ...result,
+            [customParam.name]: customParam.value,
+          };
+        },
+        {}
+      ),
+    },
+  };
+};
+
+export const createTopic = (
+  clusterName: ClusterName,
+  form: TopicFormDataRaw
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.createTopicAction.request());
+  try {
+    const topic: Topic = await topicsApiClient.createTopic({
+      clusterName,
+      topicFormData: formatTopicFormData(form),
+    });
+    dispatch(actions.createTopicAction.success(topic));
+  } catch (e) {
+    dispatch(actions.createTopicAction.failure());
+  }
+};
+
+export const updateTopic = (
+  clusterName: ClusterName,
+  form: TopicFormDataRaw
+): PromiseThunkResult => async (dispatch) => {
+  dispatch(actions.updateTopicAction.request());
+  try {
+    const topic: Topic = await topicsApiClient.updateTopic({
+      clusterName,
+      topicName: form.name,
+      topicFormData: formatTopicFormData(form),
+    });
+    dispatch(actions.updateTopicAction.success(topic));
+  } catch (e) {
+    dispatch(actions.updateTopicAction.failure());
+  }
+};

+ 1 - 0
kafka-ui-react-app/src/redux/interfaces/topic.ts

@@ -56,6 +56,7 @@ export interface TopicWithDetailedInfo extends Topic, TopicDetails {
 export interface TopicsState {
   byName: { [topicName: string]: TopicWithDetailedInfo };
   allNames: TopicName[];
+  totalPages: number;
   messages: TopicMessage[];
 }
 

+ 2 - 24
kafka-ui-react-app/src/redux/reducers/topics/reducer.ts

@@ -7,32 +7,10 @@ import * as actions from 'redux/actions';
 export const initialState: TopicsState = {
   byName: {},
   allNames: [],
+  totalPages: 1,
   messages: [],
 };
 
-const updateTopicList = (state: TopicsState, payload: Topic[]): TopicsState => {
-  const initialMemo: TopicsState = {
-    ...state,
-    allNames: [],
-  };
-
-  return payload.reduce(
-    (memo: TopicsState, topic) => ({
-      ...memo,
-      byName: {
-        ...memo.byName,
-        [topic.name]: {
-          ...memo.byName[topic.name],
-          ...topic,
-          id: v4(),
-        },
-      },
-      allNames: [...memo.allNames, topic.name],
-    }),
-    initialMemo
-  );
-};
-
 const addToTopicList = (state: TopicsState, payload: Topic): TopicsState => {
   const newState: TopicsState = {
     ...state,
@@ -70,7 +48,7 @@ const transformTopicMessages = (
 const reducer = (state = initialState, action: Action): TopicsState => {
   switch (action.type) {
     case getType(actions.fetchTopicsListAction.success):
-      return updateTopicList(state, action.payload);
+      return action.payload;
     case getType(actions.fetchTopicDetailsAction.success):
       return {
         ...state,