Repository: provectus/kafka-ui
Issue: Direct link access to the topic does not work
Labels: type/bug

**Describe the bug**

Сurrently, during opening the created topic by direct link will be opened list with topics, not the topic view page

**Set up**

`./mvnw clean install -Pprod `
`docker-compose -f ./docker/kafka-ui.yaml up`

**Steps to Reproduce**
Steps to reproduce the behavior:

1. Create the topic1 
2. Open topic view by direct access `ui/clusters/secondLocal/topics/topic1`

**Expected behavior**
Opening the topic1 view page with tabs and functions to delete topic etc

**Screenshots**

https://user-images.githubusercontent.com/44370201/131344570-2fadae50-108e-48c7-bda9-491f79879fc5.mov


Issue comments:

Pull request review comments:

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.tsx
index 611d1327881..d898805254a 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Details.tsx
@@ -13,6 +13,8 @@ import {
 } from 'lib/paths';
 import ClusterContext from 'components/contexts/ClusterContext';
 import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
+import { useDispatch } from 'react-redux';
+import { deleteTopicAction } from 'redux/actions';
 
 import OverviewContainer from './Overview/OverviewContainer';
 import TopicConsumerGroupsContainer from './ConsumerGroups/TopicConsumerGroupsContainer';
@@ -37,6 +39,7 @@ const Details: React.FC<Props> = ({
   clearTopicMessages,
 }) => {
   const history = useHistory();
+  const dispatch = useDispatch();
   const { isReadOnly, isTopicDeletionAllowed } =
     React.useContext(ClusterContext);
   const [isDeleteTopicConfirmationVisible, setDeleteTopicConfirmationVisible] =
@@ -44,8 +47,10 @@ const Details: React.FC<Props> = ({
   const deleteTopicHandler = React.useCallback(() => {
     deleteTopic(clusterName, topicName);
   }, [clusterName, topicName]);
+
   React.useEffect(() => {
     if (isDeleted) {
+      dispatch(deleteTopicAction.cancel());
       history.push(clusterTopicsPath(clusterName));
     }
   }, [isDeleted]);
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/DetailsContainer.ts b/kafka-ui-react-app/src/components/Topics/Topic/Details/DetailsContainer.ts
index f4607dcc117..81c3b036c6b 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Details/DetailsContainer.ts
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/DetailsContainer.ts
@@ -3,8 +3,8 @@ import { ClusterName, RootState, TopicName } from 'redux/interfaces';
 import { withRouter, RouteComponentProps } from 'react-router-dom';
 import { deleteTopic, clearTopicMessages } from 'redux/actions';
 import {
+  getIsTopicDeleted,
   getIsTopicInternal,
-  getTopicList,
 } from 'redux/reducers/topics/selectors';
 
 import Details from './Details';
@@ -27,7 +27,7 @@ const mapStateToProps = (
   clusterName,
   topicName,
   isInternal: getIsTopicInternal(state, topicName),
-  isDeleted: !getTopicList(state).find((topic) => topic.name === topicName),
+  isDeleted: getIsTopicDeleted(state),
 });
 
 const mapDispatchToProps = {
diff --git a/kafka-ui-react-app/src/redux/actions/actions.ts b/kafka-ui-react-app/src/redux/actions/actions.ts
index 27f9126f113..f79d6c60f27 100644
--- a/kafka-ui-react-app/src/redux/actions/actions.ts
+++ b/kafka-ui-react-app/src/redux/actions/actions.ts
@@ -97,8 +97,9 @@ export const updateTopicAction = createAsyncAction(
 export const deleteTopicAction = createAsyncAction(
   'DELETE_TOPIC__REQUEST',
   'DELETE_TOPIC__SUCCESS',
-  'DELETE_TOPIC__FAILURE'
-)<undefined, TopicName, undefined>();
+  'DELETE_TOPIC__FAILURE',
+  'DELETE_TOPIC__CANCEL'
+)<undefined, TopicName, undefined, undefined>();
 
 export const fetchConsumerGroupsAction = createAsyncAction(
   'GET_CONSUMER_GROUPS__REQUEST',
diff --git a/kafka-ui-react-app/src/redux/reducers/loader/reducer.ts b/kafka-ui-react-app/src/redux/reducers/loader/reducer.ts
index 37892542fae..18197eb2f41 100644
--- a/kafka-ui-react-app/src/redux/reducers/loader/reducer.ts
+++ b/kafka-ui-react-app/src/redux/reducers/loader/reducer.ts
@@ -4,9 +4,9 @@ export const initialState: LoaderState = {};
 
 const reducer = (state = initialState, action: Action): LoaderState => {
   const { type } = action;
-  const matches = /(.*)__(REQUEST|SUCCESS|FAILURE)$/.exec(type);
+  const matches = /(.*)__(REQUEST|SUCCESS|FAILURE|CANCEL)$/.exec(type);
 
-  // not a *__REQUEST / *__SUCCESS /  *__FAILURE actions, so we ignore them
+  // not a *__REQUEST / *__SUCCESS /  *__FAILURE /  *__CANCEL actions, so we ignore them
   if (!matches) return state;
 
   const [, requestName, requestState] = matches;
@@ -27,6 +27,11 @@ const reducer = (state = initialState, action: Action): LoaderState => {
         ...state,
         [requestName]: 'errorFetching',
       };
+    case 'CANCEL':
+      return {
+        ...state,
+        [requestName]: 'notFetched',
+      };
     default:
       return state;
   }
diff --git a/kafka-ui-react-app/src/redux/reducers/topics/selectors.ts b/kafka-ui-react-app/src/redux/reducers/topics/selectors.ts
index fe0f5eaf5c0..ad388253827 100644
--- a/kafka-ui-react-app/src/redux/reducers/topics/selectors.ts
+++ b/kafka-ui-react-app/src/redux/reducers/topics/selectors.ts
@@ -31,6 +31,12 @@ const getPartitionsCountIncreaseStatus =
 const getReplicationFactorUpdateStatus = createFetchingSelector(
   'UPDATE_REPLICATION_FACTOR'
 );
+const getTopicDeletingStatus = createFetchingSelector('DELETE_TOPIC');
+
+export const getIsTopicDeleted = createSelector(
+  getTopicDeletingStatus,
+  (status) => status === 'fetched'
+);
 
 export const getAreTopicsFetching = createSelector(
   getTopicListFetchingStatus,


Test patch: