Merge pull request #13 from acid-info/add-block-search

fix
This commit is contained in:
amir houieh 2023-05-11 12:37:51 +02:00 committed by GitHub
commit d079ec5115
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 59 additions and 40 deletions

View File

@ -5,24 +5,27 @@ import {
} from '@/lib/unbody/unbody.types' } from '@/lib/unbody/unbody.types'
import searchApi from '@/services/search.service' import searchApi from '@/services/search.service'
import { import {
PostTypes,
SearchHook, SearchHook,
SearchHookDataPayload, SearchHookDataPayload,
SearchResultItem, SearchResultItem,
SearchResults,
} from '@/types/data.types' } from '@/types/data.types'
import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
import { useState } from 'react' import { useState } from 'react'
export const useSearchGeneric = <T>( export const useSearchGeneric = <T>(
initialData: SearchResultItem<T>[], initialData: SearchResultItem<T>[],
postType: PostTypes,
): SearchHook<T> => { ): SearchHook<T> => {
const [data, setData] = useState<SearchResultItem<T>[]>(initialData) const [data, setData] = useState<SearchResultItem<T>[]>(initialData)
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null) const [error, setError] = useState<string | null>(null)
const search = async (query: string, tags: string[]) => { const search = async (query: string, tags: string[]) => {
if (loading) return null if (loading) return Promise.resolve([])
setLoading(true) setLoading(true)
const result = await searchApi.searchArticles(query, tags) const result = await searchApi.serach(query, tags, postType)
setData(result.data) setData(result.data)
setLoading(false) setLoading(false)
return result.data return result.data
@ -35,28 +38,3 @@ export const useSearchGeneric = <T>(
} }
return { data, loading, error, search, reset } return { data, loading, error, search, reset }
} }
export const useSearch = (
initialData: SearchHookDataPayload,
): SearchResults => {
const articles = useSearchGeneric<UnbodyGoogleDoc>(
initialData?.articles ?? null,
)
const blocks = useSearchGeneric<UnbodyImageBlock | UnbodyTextBlock>(
initialData?.blocks ?? null,
)
const search = async (query: string, tags: string[]) => {
const [articlesResult, blocksResult] = await Promise.all([
articles.loading ? () => {} : articles.search(query, tags),
blocks.loading ? () => {} : blocks.search(query, tags),
])
}
const reset = (initialData: SearchHookDataPayload) => {
articles.reset(initialData?.articles)
blocks.reset(initialData?.blocks)
}
return { search, reset, blocks, articles }
}

View File

@ -1,4 +1,5 @@
import api from '@/services/unbody.service' import api from '@/services/unbody.service'
import { PostTypes } from '@/types/data.types'
import type { NextApiRequest, NextApiResponse } from 'next' import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler( export default async function handler(
@ -6,8 +7,12 @@ export default async function handler(
res: NextApiResponse<any>, res: NextApiResponse<any>,
) { ) {
const { const {
query: { q = '', tags: tagsString = '' }, query: { q = '', tags: tagsString = '', postType },
} = req } = req
if (!Object.values(PostTypes).includes(postType as PostTypes)) {
return res.status(400).json({ error: 'Invalid postType' })
}
const tags = const tags =
typeof tagsString === 'string' typeof tagsString === 'string'
? tagsString ? tagsString
@ -15,6 +20,10 @@ export default async function handler(
.map((tag: string) => tag.trim()) .map((tag: string) => tag.trim())
.filter((t) => t.length > 0) .filter((t) => t.length > 0)
: undefined : undefined
const response = await api.searchArticles(q as string, tags) const response =
postType === PostTypes.Article
? await api.searchArticles(q as string, tags)
: await api.serachBlocks(q as string, tags)
res.status(200).json(response) res.status(200).json(response)
} }

View File

@ -1,4 +1,4 @@
import { useSearch, useSearchGeneric } from '@/hooks/useSearch' import { useSearchGeneric } from '@/hooks/useSearch'
import { import {
UnbodyGoogleDoc, UnbodyGoogleDoc,
UnbodyImageBlock, UnbodyImageBlock,
@ -10,6 +10,7 @@ import Image from 'next/image'
import unbodyApi from '@/services/unbody.service' import unbodyApi from '@/services/unbody.service'
import { import {
PostTypes,
SearchHook, SearchHook,
SearchHookDataPayload, SearchHookDataPayload,
SearchResultItem, SearchResultItem,
@ -43,11 +44,19 @@ export default function SearchPage({
query: { query = '', topics = [] }, query: { query = '', topics = [] },
} = router } = router
const articles = useSearchGeneric<UnbodyGoogleDoc>(initialArticles) const articles = useSearchGeneric<UnbodyGoogleDoc>(
initialArticles,
PostTypes.Article,
)
const blocks = useSearchGeneric<UnbodyTextBlock | UnbodyImageBlock>( const blocks = useSearchGeneric<UnbodyTextBlock | UnbodyImageBlock>(
initialBlocks, initialBlocks,
PostTypes.Block,
) )
// console.log('articles', articles)
// console.log('blocks', blocks)
const [mounted, setMounted] = useState(false) const [mounted, setMounted] = useState(false)
useEffect(() => { useEffect(() => {

View File

@ -19,9 +19,13 @@ export const getSearchBlocksQuery = (args: UnbodyGetFilters = defaultArgs) =>
...on GoogleDoc{ ...on GoogleDoc{
title title
remoteId remoteId
slug
__typename __typename
} }
} }
_additional{
certainty
}
`), `),
GetImageBlockQuery(args)(` GetImageBlockQuery(args)(`
__typename __typename
@ -33,9 +37,13 @@ export const getSearchBlocksQuery = (args: UnbodyGetFilters = defaultArgs) =>
...on GoogleDoc{ ...on GoogleDoc{
title title
remoteId remoteId
slug
__typename __typename
} }
} }
_additional{
certainty
}
`), `),
].join(' '), ].join(' '),
) )

View File

@ -1,8 +1,9 @@
import { PostTypes } from '@/types/data.types'
class SearchService { class SearchService {
constructor() {} constructor() {}
serach = (query: string, tags: string[], postType: PostTypes) => {
searchArticles = (query: string, tags: string[]) => { return fetch(`/api/search/${postType}?q=${query}&tags=${tags.join(',')}`)
return fetch(`/api/search?q=${query}&tags=${tags.join(',')}`)
.then((res) => res.json()) .then((res) => res.json())
.catch((e) => { .catch((e) => {
console.error(e) console.error(e)

View File

@ -57,10 +57,10 @@ const OperandFactory = (
}) })
export const Operands: Record<string, (...a: any) => WhereOperandsInpObj> = { export const Operands: Record<string, (...a: any) => WhereOperandsInpObj> = {
WHERE_PUBLISHED: () => WHERE_PUBLISHED: (subPath: string[] = ['pathString']) =>
OperandFactory( OperandFactory(
UnbodyGraphQl.Filters.WhereOperatorEnum.Like, UnbodyGraphQl.Filters.WhereOperatorEnum.Like,
'pathString', [...subPath],
'*/published/*', '*/published/*',
'valueString', 'valueString',
), ),
@ -178,16 +178,21 @@ class UnbodyService extends UnbodyClient {
? { ? {
nearText: { nearText: {
concepts: [q, ...tags], concepts: [q, ...tags],
certainty: 0.75, certainty: 0.85,
}, },
...(published ...(published
? { ? {
where: Operands.WHERE_PUBLISHED(), where: Operands.WHERE_PUBLISHED([
'document',
'GoogleDoc',
'pathString',
]),
} }
: {}), : {}),
} }
: {}), : {}),
}) })
return this.request<UnbodyGraphQlResponseBlocks>(query) return this.request<UnbodyGraphQlResponseBlocks>(query)
.then(({ data }) => { .then(({ data }) => {
if (!data || !(data.Get.ImageBlock || data.Get.TextBlock)) if (!data || !(data.Get.ImageBlock || data.Get.TextBlock))

View File

@ -5,6 +5,11 @@ import {
} from '@/lib/unbody/unbody.types' } from '@/lib/unbody/unbody.types'
import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types' import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
export enum PostTypes {
Article = 'article',
Block = 'block',
}
export interface ArticlePostData extends UnbodyGoogleDoc { export interface ArticlePostData extends UnbodyGoogleDoc {
toc: Array<UnbodyGraphQl.Fragments.TocItem> toc: Array<UnbodyGraphQl.Fragments.TocItem>
} }
@ -32,7 +37,11 @@ export type SearchHookDataPayload = {
export type SearchResults = { export type SearchResults = {
articles: SearchHook<UnbodyGoogleDoc> articles: SearchHook<UnbodyGoogleDoc>
blocks: SearchHook<UnbodyImageBlock | UnbodyTextBlock> blocks: SearchHook<UnbodyImageBlock | UnbodyTextBlock>
search: (query: string, tags: string[]) => Promise<void> search: (
query: string,
tags: string[],
docType: UnbodyGraphQl.UnbodyDocumentTypeNames,
) => Promise<void>
reset: (initialData: SearchHookDataPayload) => void reset: (initialData: SearchHookDataPayload) => void
} }