Browse Source

refactor: session based search results view implementation

jamesgeorge007 1 year ago
parent
commit
3700c2b639

+ 45 - 40
packages/hoppscotch-common/src/components/new-collections/rest/index.vue

@@ -351,22 +351,21 @@
 </template>
 
 <script setup lang="ts">
-import * as E from "fp-ts/lib/Either"
-
-import { useService } from "dioc/vue"
-import { markRaw, nextTick, ref, watch } from "vue"
-
 import { HoppCollection, HoppRESTAuth, HoppRESTRequest } from "@hoppscotch/data"
+import { useService } from "dioc/vue"
+import * as E from "fp-ts/lib/Either"
 import { cloneDeep, isEqual } from "lodash-es"
+import { computed, markRaw, nextTick, ref, watch } from "vue"
+
 import { useI18n } from "~/composables/i18n"
 import { useReadonlyStream } from "~/composables/stream"
 import { useToast } from "~/composables/toast"
 import { invokeAction } from "~/helpers/actions"
+import { WorkspaceRESTSearchCollectionTreeAdapter } from "~/helpers/adapters/WorkspaceRESTCollectionSearchTreeAdapter"
 import { WorkspaceRESTCollectionTreeAdapter } from "~/helpers/adapters/WorkspaceRESTCollectionTreeAdapter"
 import { TeamCollection } from "~/helpers/backend/graphql"
 import {
   getFoldersByPath,
-  resolveSaveContextOnCollectionReorder,
   updateInheritedPropertiesForAffectedRequests,
 } from "~/helpers/collection/collection"
 import { getRequestsByPath } from "~/helpers/collection/request"
@@ -387,7 +386,6 @@ import { RESTTabService } from "~/services/tab/rest"
 import IconImport from "~icons/lucide/folder-down"
 import IconHelpCircle from "~icons/lucide/help-circle"
 import IconPlus from "~icons/lucide/plus"
-import { WorkspaceRESTSearchCollectionTreeAdapter } from "~/helpers/adapters/WorkspaceRESTCollectionSearchTreeAdapter"
 
 const t = useI18n()
 const toast = useToast()
@@ -414,11 +412,9 @@ const currentReorderingStatus = useReadonlyStream(currentReorderingStatus$, {
   parentID: "",
 })
 
-const treeAdapter = markRaw(
-  new WorkspaceRESTCollectionTreeAdapter(
-    props.workspaceHandle,
-    workspaceService
-  )
+const currentUser = useReadonlyStream(
+  platform.auth.getCurrentUserStream(),
+  platform.auth.getCurrentUser()
 )
 
 const draggingToRoot = ref(false)
@@ -442,11 +438,9 @@ const editingChildCollectionName = ref<string>("")
 const editingRequestName = ref<string>("")
 const editingRequestIndexPath = ref<string>("")
 
-const filteredCollections = ref<HoppCollection[]>([])
+const onSessionEnd = ref<() => void>()
 
-const searchTreeAdapter = new WorkspaceRESTSearchCollectionTreeAdapter(
-  filteredCollections
-)
+const filteredCollections = ref<HoppCollection[]>([])
 
 const editingProperties = ref<{
   collection: Omit<HoppCollection, "v"> | TeamCollection | null
@@ -462,35 +456,46 @@ const editingProperties = ref<{
 
 const confirmModalTitle = ref<string | null>(null)
 
-const currentUser = useReadonlyStream(
-  platform.auth.getCurrentUserStream(),
-  platform.auth.getCurrentUser()
-)
+const isActiveSearchSession = computed(() => !!searchText.value)
 
-watch(
-  () => searchText.value,
-  async (newSearchText: string) => {
-    const searchResultsHandleResult =
-      await workspaceService.getRESTSearchResultsView(
-        props.workspaceHandle,
-        newSearchText
-      )
+watch(isActiveSearchSession, async (newState) => {
+  if (!newState) {
+    filteredCollections.value = []
+    onSessionEnd.value?.()
+    return
+  }
 
-    if (E.isLeft(searchResultsHandleResult)) {
-      filteredCollections.value = []
-      return
-    }
+  const searchResultsHandleResult =
+    await workspaceService.getRESTSearchResultsView(
+      props.workspaceHandle,
+      ref(searchText)
+    )
 
-    const searchResultsHandle = searchResultsHandleResult.right
+  if (E.isLeft(searchResultsHandleResult)) {
+    filteredCollections.value = []
+    return
+  }
 
-    if (searchResultsHandle.value.type === "invalid") {
-      filteredCollections.value = []
-      return
-    }
+  const searchResultsHandle = searchResultsHandleResult.right
 
-    filteredCollections.value = searchResultsHandle.value.data.results.value
-  },
-  { immediate: true }
+  if (searchResultsHandle.value.type === "invalid") {
+    filteredCollections.value = []
+    return
+  }
+
+  filteredCollections.value = searchResultsHandle.value.data.results.value
+  onSessionEnd.value = searchResultsHandle.value.data.onSessionEnd
+})
+
+const treeAdapter = markRaw(
+  new WorkspaceRESTCollectionTreeAdapter(
+    props.workspaceHandle,
+    workspaceService
+  )
+)
+
+const searchTreeAdapter = new WorkspaceRESTSearchCollectionTreeAdapter(
+  filteredCollections
 )
 
 const isSelected = ({

+ 1 - 1
packages/hoppscotch-common/src/services/new-workspace/index.ts

@@ -690,7 +690,7 @@ export class NewWorkspaceService extends Service {
 
   public async getRESTSearchResultsView(
     workspaceHandle: HandleRef<Workspace>,
-    searchQuery: string
+    searchQuery: Ref<string>
   ): Promise<
     E.Either<
       WorkspaceError<"INVALID_HANDLE" | "INVALID_PROVIDER">,

+ 1 - 1
packages/hoppscotch-common/src/services/new-workspace/provider.ts

@@ -44,7 +44,7 @@ export interface WorkspaceProvider {
   ): Promise<E.Either<unknown, HandleRef<RESTCollectionLevelAuthHeadersView>>>
   getRESTSearchResultsView(
     workspaceHandle: HandleRef<Workspace>,
-    searchQuery: string
+    searchQuery: Ref<string>
   ): Promise<E.Either<unknown, HandleRef<RESTSearchResultsView>>>
 
   createRESTRootCollection(

+ 74 - 58
packages/hoppscotch-common/src/services/new-workspace/providers/personal.workspace.ts

@@ -7,7 +7,16 @@ import {
 } from "@hoppscotch/data"
 import { Service } from "dioc"
 import * as E from "fp-ts/Either"
-import { Ref, computed, markRaw, ref, shallowRef } from "vue"
+import {
+  Ref,
+  computed,
+  effect,
+  effectScope,
+  markRaw,
+  ref,
+  shallowRef,
+  watch,
+} from "vue"
 
 import PersonalWorkspaceSelector from "~/components/workspace/PersonalWorkspaceSelector.vue"
 import { useStreamStatic } from "~/composables/stream"
@@ -951,8 +960,67 @@ export class PersonalWorkspaceProviderService
 
   public getRESTSearchResultsView(
     workspaceHandle: HandleRef<Workspace>,
-    searchQuery: string
+    searchQuery: Ref<string>
   ): Promise<E.Either<never, HandleRef<RESTSearchResultsView>>> {
+    const results = ref<HoppCollection[]>([])
+
+    const scopeHandle = effectScope()
+
+    scopeHandle.run(() => {
+      watch(
+        searchQuery,
+        (newSearchQuery) => {
+          if (!newSearchQuery) {
+            results.value = this.restCollectionState.value.state
+            return
+          }
+
+          const filterText = newSearchQuery.toLowerCase()
+          const filteredCollections = []
+
+          const isMatch = (text: string) =>
+            text.toLowerCase().includes(filterText)
+
+          for (const collection of this.restCollectionState.value.state) {
+            const filteredRequests = []
+            const filteredFolders = []
+            for (const request of collection.requests) {
+              if (isMatch(request.name)) filteredRequests.push(request)
+            }
+            for (const folder of collection.folders) {
+              if (isMatch(folder.name)) filteredFolders.push(folder)
+              const filteredFolderRequests = []
+              for (const request of folder.requests) {
+                if (isMatch(request.name)) filteredFolderRequests.push(request)
+              }
+              if (filteredFolderRequests.length > 0) {
+                const filteredFolder = Object.assign({}, folder)
+                filteredFolder.requests = filteredFolderRequests
+                filteredFolders.push(filteredFolder)
+              }
+            }
+
+            if (
+              filteredRequests.length + filteredFolders.length > 0 ||
+              isMatch(collection.name)
+            ) {
+              const filteredCollection = Object.assign({}, collection)
+              filteredCollection.requests = filteredRequests
+              filteredCollection.folders = filteredFolders
+              filteredCollections.push(filteredCollection)
+            }
+
+            results.value = filteredCollections
+          }
+        },
+        { immediate: true }
+      )
+    })
+
+    const onSessionEnd = () => {
+      scopeHandle.stop()
+    }
+
     return Promise.resolve(
       E.right(
         computed(() => {
@@ -967,21 +1035,7 @@ export class PersonalWorkspaceProviderService
             }
           }
 
-          if (!searchQuery) {
-            return {
-              type: "ok" as const,
-              data: {
-                providerID: this.providerID,
-                workspaceID: workspaceHandle.value.data.workspaceID,
-
-                loading: ref(false),
-
-                results: ref(this.restCollectionState.value.state),
-              },
-            }
-          }
-
-          return markRaw({
+          return {
             type: "ok" as const,
             data: {
               providerID: this.providerID,
@@ -989,48 +1043,10 @@ export class PersonalWorkspaceProviderService
 
               loading: ref(false),
 
-              results: computed(() => {
-                const filterText = searchQuery.toLowerCase()
-                const filteredCollections = []
-
-                const isMatch = (text: string) =>
-                  text.toLowerCase().includes(filterText)
-
-                for (const collection of this.restCollectionState.value.state) {
-                  const filteredRequests = []
-                  const filteredFolders = []
-                  for (const request of collection.requests) {
-                    if (isMatch(request.name)) filteredRequests.push(request)
-                  }
-                  for (const folder of collection.folders) {
-                    if (isMatch(folder.name)) filteredFolders.push(folder)
-                    const filteredFolderRequests = []
-                    for (const request of folder.requests) {
-                      if (isMatch(request.name))
-                        filteredFolderRequests.push(request)
-                    }
-                    if (filteredFolderRequests.length > 0) {
-                      const filteredFolder = Object.assign({}, folder)
-                      filteredFolder.requests = filteredFolderRequests
-                      filteredFolders.push(filteredFolder)
-                    }
-                  }
-
-                  if (
-                    filteredRequests.length + filteredFolders.length > 0 ||
-                    isMatch(collection.name)
-                  ) {
-                    const filteredCollection = Object.assign({}, collection)
-                    filteredCollection.requests = filteredRequests
-                    filteredCollection.folders = filteredFolders
-                    filteredCollections.push(filteredCollection)
-                  }
-                }
-
-                return filteredCollections
-              }),
+              results,
+              onSessionEnd,
             },
-          })
+          }
         })
       )
     )

+ 1 - 0
packages/hoppscotch-common/src/services/new-workspace/view.ts

@@ -54,4 +54,5 @@ export interface RESTSearchResultsView {
   loading: Ref<boolean>
 
   results: Ref<HoppCollection[]>
+  onSessionEnd: () => void
 }