refactor: view based implementation for search in personal workspace

This commit is contained in:
jamesgeorge007
2024-02-22 14:31:27 +05:30
parent 7c52c6b79d
commit af7e6b70cd
4 changed files with 220 additions and 0 deletions

View File

@@ -15,6 +15,7 @@ import { Workspace, WorkspaceCollection, WorkspaceRequest } from "./workspace"
import {
RESTCollectionChildrenView,
RESTCollectionLevelAuthHeadersView,
RESTSearchResultsView,
RootRESTCollectionView,
} from "./view"
import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data"
@@ -687,6 +688,39 @@ export class NewWorkspaceService extends Service {
return E.right(result.right)
}
public async getRESTSearchResultsView(
workspaceHandle: HandleRef<Workspace>,
searchQuery: Ref<string>
): Promise<
E.Either<
WorkspaceError<"INVALID_HANDLE" | "INVALID_PROVIDER">,
HandleRef<RESTSearchResultsView>
>
> {
if (workspaceHandle.value.type === "invalid") {
return E.left({ type: "SERVICE_ERROR", error: "INVALID_HANDLE" })
}
const provider = this.registeredProviders.get(
workspaceHandle.value.data.providerID
)
if (!provider) {
return E.left({ type: "SERVICE_ERROR", error: "INVALID_PROVIDER" })
}
const result = await provider.getRESTSearchResultsView(
workspaceHandle,
searchQuery
)
if (E.isLeft(result)) {
return E.left({ type: "PROVIDER_ERROR", error: result.left })
}
return E.right(result.right)
}
public registerWorkspaceProvider(provider: WorkspaceProvider) {
if (this.registeredProviders.has(provider.providerID)) {
console.warn(

View File

@@ -11,6 +11,7 @@ import {
RESTCollectionLevelAuthHeadersView,
RESTCollectionChildrenView,
RootRESTCollectionView,
RESTSearchResultsView,
} from "./view"
import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data"
@@ -40,6 +41,10 @@ export interface WorkspaceProvider {
getRESTCollectionLevelAuthHeadersView(
collectionHandle: HandleRef<WorkspaceCollection>
): Promise<E.Either<unknown, HandleRef<RESTCollectionLevelAuthHeadersView>>>
getRESTSearchResultsView(
workspaceHandle: HandleRef<Workspace>,
searchQuery: Ref<string>
): Promise<E.Either<unknown, HandleRef<RESTSearchResultsView>>>
createRESTRootCollection(
workspaceHandle: HandleRef<Workspace>,

View File

@@ -37,7 +37,10 @@ import { WorkspaceProvider } from "~/services/new-workspace/provider"
import {
RESTCollectionChildrenView,
RESTCollectionLevelAuthHeadersView,
RESTCollectionViewCollection,
RESTCollectionViewItem,
RESTCollectionViewRequest,
RESTSearchResultsView,
RootRESTCollectionView,
} from "~/services/new-workspace/view"
import {
@@ -766,6 +769,7 @@ export class PersonalWorkspaceProviderService
})
const requests = item.requests.map((req, id) => {
// TODO: Replace `parentCollectionID` with `collectionID`
return <RESTCollectionViewItem>{
type: "request",
value: {
@@ -945,6 +949,174 @@ export class PersonalWorkspaceProviderService
)
}
public getRESTSearchResultsView(
workspaceHandle: HandleRef<Workspace>,
searchQuery: Ref<string>
): Promise<E.Either<never, HandleRef<RESTSearchResultsView>>> {
return Promise.resolve(
E.right(
computed(() => {
if (
workspaceHandle.value.type === "invalid" ||
workspaceHandle.value.data.providerID !== this.providerID ||
workspaceHandle.value.data.workspaceID !== "personal"
) {
return {
type: "invalid" as const,
reason: "INVALID_WORKSPACE_HANDLE" as const,
}
}
if (!searchQuery.value) {
return markRaw({
type: "ok" as const,
data: {
providerID: this.providerID,
workspaceID: workspaceHandle.value.data.workspaceID,
loading: ref(false),
results: computed(() => {
return this.restCollectionState.value.state.map(
(coll, id) => {
return <RESTCollectionViewItem>{
type: "collection",
value: {
collectionID: id.toString(),
isLastItem:
id ===
this.restCollectionState.value.state.length - 1,
name: coll.name,
parentCollectionID: null,
},
}
}
)
}),
},
})
}
return markRaw({
type: "ok" as const,
data: {
providerID: this.providerID,
workspaceID: workspaceHandle.value.data.workspaceID,
loading: ref(false),
results: computed(() => {
const filterText = searchQuery.value.toLowerCase()
const filteredCollections: RESTCollectionViewItem[] = []
const isMatch = (text: string) =>
text.toLowerCase().includes(filterText)
for (const collection of this.restCollectionState.value.state) {
const filteredRequests: Extract<
RESTCollectionViewItem,
{ type: "request" }
>[] = []
const filteredFolders: Extract<
RESTCollectionViewItem,
{ type: "collection" }
>[] = []
collection.requests.forEach((request, requestID) => {
if (isMatch(request.name)) {
filteredRequests.push({
type: "request",
value: {
collectionID: collection.id!,
isLastItem:
collection.requests?.length > 1
? requestID === collection.requests.length - 1
: false,
// TODO: Replace `parentCollectionID` with `collectionID`
parentCollectionID: collection.id!,
requestID: requestID.toString(),
request: request as HoppRESTRequest,
},
})
}
})
collection.folders.forEach(
(childCollection, childCollectionID) => {
if (isMatch(childCollection.name)) {
filteredFolders.push({
type: "collection",
value: {
collectionID: `${collection.id}/${childCollectionID}`,
isLastItem:
collection.folders?.length > 1
? childCollectionID ===
collection.folders.length - 1
: false,
name: childCollection.name,
parentCollectionID: collection.id!,
},
})
}
const filteredFolderRequests: Extract<
RESTCollectionViewItem,
{ type: "request" }
>[] = ([] = [])
childCollection.requests.forEach(
(request: HoppRESTRequest, requestID: number) => {
if (isMatch(request.name))
filteredFolderRequests.push({
type: "request",
value: {
collectionID: childCollection.id!,
isLastItem:
childCollection.requests?.length > 1
? requestID ===
childCollection.requests.length - 1
: false,
// TODO: Replace `parentCollectionID` with `collectionID`
parentCollectionID: childCollection.id!,
requestID: requestID.toString(),
request,
},
})
}
)
if (filteredFolderRequests.length > 0) {
const filteredFolder = Object.assign(
{},
childCollection
)
filteredFolder.requests = filteredFolderRequests
filteredFolders.push(filteredFolder)
}
}
)
if (
filteredRequests.length + filteredFolders.length > 0 ||
isMatch(collection.name)
) {
filteredCollections.push(
...filteredFolders,
...filteredRequests
)
}
}
return filteredCollections
}),
},
})
})
)
)
}
public getWorkspaceHandle(
workspaceID: string
): Promise<E.Either<unknown, HandleRef<Workspace>>> {

View File

@@ -46,3 +46,12 @@ export interface RESTCollectionChildrenView {
content: Ref<RESTCollectionViewItem[]>
}
export interface RESTSearchResultsView {
providerID: string
workspaceID: string
loading: Ref<boolean>
results: Ref<RESTCollectionViewItem[]>
}