Repository: provectus/kafka-ui
Issue: Message search offset is not being set unless rendered first
Labels: type/bug
scope/frontend
status/accepted
status/confirmed
type/regression

**Describe the bug**
<!--(A clear and concise description of what the bug is.)-->
Message search offset is not being set until a few actions are performed.


**Set up**
<!--
(How do you run the app? 
Which version of the app are you running? Provide either docker image version or check commit hash at the top left corner. We won't be able to help you without this information.)
-->
master version


**Steps to Reproduce**
Steps to reproduce the behavior:
1. Go to Topic->Messages
2. Set "1" in filter offset, `seekTo` in request will be `0::0`.  This is not a valid behavior.
3. Change "offset" to "timestamp" and back, set offset to "1" and submit a request again. This time the `seekTo` param will be `0::1` as it should.

Issue comments:

Pull request review comments:
shouldn't offset be in the dependency array otherwise it will get some outdated variable ?
No. Offset is an input value state. If I added offset to the dependencies, the form would be submitted every time the input changed. That's the reason why offset wasn't given as a dependency of useCallback (of handleFiltersSubmit).

Patch that resolved the issue:
diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/Filters.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/Filters.tsx
index a38e5e8a27a..b6e6cf3e653 100644
--- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/Filters.tsx
+++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/Filters.tsx
@@ -182,48 +182,37 @@ const Filters: React.FC<FiltersProps> = ({
     );
   };
 
-  const handleFiltersSubmit = React.useCallback(() => {
-    setAttempt(attempt + 1);
-
-    if (isSeekTypeControlVisible) {
-      props.seekType = isLive ? SeekType.LATEST : currentSeekType;
-      props.seekTo = selectedPartitions.map(({ value }) => {
-        let seekToOffset;
-
-        if (currentSeekType === SeekType.OFFSET) {
-          if (offset) {
-            seekToOffset = offset;
-          } else {
-            seekToOffset =
-              seekDirection === SeekDirection.FORWARD
-                ? partitionMap[value].offsetMin
-                : partitionMap[value].offsetMax;
-          }
-        } else if (timestamp) {
-          seekToOffset = timestamp.getTime();
-        }
-
-        return `${value}::${seekToOffset || '0'}`;
+  const handleFiltersSubmit = React.useCallback(
+    (currentOffset: string) => {
+      setAttempt(attempt + 1);
+
+      if (isSeekTypeControlVisible) {
+        props.seekType = isLive ? SeekType.LATEST : currentSeekType;
+        props.seekTo = selectedPartitions.map(({ value }) => {
+          const offsetProperty =
+            seekDirection === SeekDirection.FORWARD ? 'offsetMin' : 'offsetMax';
+          const offsetBasedSeekTo =
+            currentOffset || partitionMap[value][offsetProperty];
+          const seekToOffset =
+            currentSeekType === SeekType.OFFSET
+              ? offsetBasedSeekTo
+              : timestamp?.getTime();
+
+          return `${value}::${seekToOffset || '0'}`;
+        });
+      }
+
+      const newProps = omitBy(props, (v) => v === undefined || v === '');
+      const qs = Object.keys(newProps)
+        .map((key) => `${key}=${newProps[key]}`)
+        .join('&');
+
+      history.push({
+        search: `?${qs}`,
       });
-    }
-
-    const newProps = omitBy(props, (v) => v === undefined || v === '');
-    const qs = Object.keys(newProps)
-      .map((key) => `${key}=${newProps[key]}`)
-      .join('&');
-
-    history.push({
-      search: `?${qs}`,
-    });
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [
-    seekDirection,
-    queryType,
-    activeFilter,
-    currentSeekType,
-    timestamp,
-    query,
-  ]);
+    },
+    [seekDirection, queryType, activeFilter, currentSeekType, timestamp, query]
+  );
 
   const handleSSECancel = () => {
     if (!source.current) return;
@@ -313,7 +302,10 @@ const Filters: React.FC<FiltersProps> = ({
             }
             break;
           case TopicMessageEventTypeEnum.PHASE:
-            if (phase?.name) updatePhase(phase.name);
+            if (phase?.name) {
+              updatePhase(phase.name);
+              setIsFetching(false);
+            }
             break;
           case TopicMessageEventTypeEnum.CONSUMING:
             if (consuming) updateMeta(consuming);
@@ -345,11 +337,11 @@ const Filters: React.FC<FiltersProps> = ({
   ]);
   React.useEffect(() => {
     if (location.search?.length === 0) {
-      handleFiltersSubmit();
+      handleFiltersSubmit(offset);
     }
   }, [handleFiltersSubmit, location]);
   React.useEffect(() => {
-    handleFiltersSubmit();
+    handleFiltersSubmit(offset);
   }, [handleFiltersSubmit, seekDirection]);
 
   return (
@@ -429,7 +421,7 @@ const Filters: React.FC<FiltersProps> = ({
               buttonType="secondary"
               buttonSize="M"
               disabled={isSubmitDisabled}
-              onClick={handleFiltersSubmit}
+              onClick={() => handleFiltersSubmit(offset)}
               style={{ fontWeight: 500 }}
             >
               Submit


Test patch: