Skip to content
This repository was archived by the owner on Nov 1, 2024. It is now read-only.

WIP: Refactor/art04 search #296

Merged
merged 3 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions components/lib/MoveModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ import {
Heading,
Select,
} from '@navikt/ds-react'
import {
SearchType,
useSearchContentWithOptionsQuery,
} from '../../lib/schema/graphql'
import LoaderSpinner from './spinner'
import { useState } from 'react'
import ErrorMessage from './error'
import { useSearch } from '../../lib/rest/search'

interface MoveModalProps {
open: boolean
Expand All @@ -31,15 +28,10 @@ export const MoveModal = ({
undefined
)
const [error, setError] = useState<string | undefined>(undefined)
const search = useSearchContentWithOptionsQuery({
variables: {
options: { types: ['dataproduct'] as SearchType[], groups: [group] },
},
fetchPolicy: 'network-only',
})
const search = useSearch({ types: ['dataproduct'], groups: [group] })

if (search.error) return <ErrorMessage error={search.error} />
if (search.loading || !search.data?.search) return <LoaderSpinner />
if (search.loading || !search.data?.results) return <LoaderSpinner />

return (
<Modal open={open} onClose={onCancel} header={{heading: "Flytt datasett"}}>
Expand All @@ -56,7 +48,7 @@ export const MoveModal = ({
onChange={(event) => setDataproductID(event.target.value)}
>
<option value="">Velg dataprodukt</option>
{search.data?.search?.map(
{search.data?.results?.map(
(dp) =>
currentDataproductID !== dp.result.id && (
<option value={dp.result.id} key={dp.result.id}>
Expand Down
46 changes: 12 additions & 34 deletions components/search/resultList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import { QueryResult } from '@apollo/client'
import {
Exact,
SearchContentWithOptionsQuery,
SearchOptions,
useDeleteStoryMutation,
} from '../../lib/schema/graphql'
import ErrorMessage from '../lib/error'
import LoaderSpinner from '../lib/spinner'
import SearchResultLink from './searchResultLink'
Expand All @@ -15,16 +9,15 @@ import { USER_INFO } from '../../lib/queries/userInfo/userInfo'
import { UserState } from '../../lib/context'
import { useSearchTeamKatalogen } from '../../lib/rest/teamkatalogen'
import { useGetProductAreas } from '../../lib/rest/productAreas'
import { SearchResult } from '../../lib/rest/search'
import { useDeleteStoryMutation } from '../../lib/schema/graphql'

const Results = ({ children }: { children: React.ReactNode }) => (
<div className="results">{children}</div>
)

type ResultListInterface = {
search?: QueryResult<
SearchContentWithOptionsQuery,
Exact<{ options: SearchOptions }>
>
search?: {data: SearchResult|undefined, loading: boolean, error: any}
dataproducts?: {
__typename?: 'Dataproduct' | undefined
id: string
Expand Down Expand Up @@ -64,23 +57,6 @@ const ResultList = ({
searchParam,
updateQuery,
}: ResultListInterface) => {
useEffect(() => {
if (!!searchParam) {
if (
search?.data?.search.filter(
(d) => d.result.__typename === 'Dataproduct'
).length == 0
) {
updateQuery?.({ ...searchParam, preferredType: 'story' })
} else if (
search?.data?.search.filter((d) => d.result.__typename === 'Story')
.length == 0
) {
updateQuery?.({ ...searchParam, preferredType: 'dataproduct' })
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [search])
const [deleteStoryQuery] = useDeleteStoryMutation()
const userInfo = useContext(UserState)
const { searchResult: teamkatalogen } = useSearchTeamKatalogen()
Expand All @@ -96,6 +72,8 @@ const ResultList = ({
]
})

const isDataProduct = (item: any) => !!item.datasets

const getTeamKatalogenInfo = (item: any) => {
const getTeamID = (url: string) => {
var urlComponents = url?.split("/")
Expand All @@ -115,11 +93,11 @@ const ResultList = ({

if (error) return <ErrorMessage error={error} />
if (loading || !data) return <LoaderSpinner />
const dataproducts = data.search.filter(
(d) => d.result.__typename === 'Dataproduct'
const dataproducts = data.results.filter(
(d) => isDataProduct(d.result)
)
const datastories = data.search.filter(
(d) => d.result.__typename === 'Story'
const datastories = data.results.filter(
(d) => !isDataProduct(d.result)
)

//dataproducts.forEach((d) => console.log(getTeamKatalogenInfo(d.result)?.teamkatalogenTeam))
Expand Down Expand Up @@ -147,7 +125,7 @@ const ResultList = ({
{datastories.map(
(it, idx) =>
(
it.result.__typename === 'Story' && (
!isDataProduct(it.result) && (
<SearchResultLink
key={idx}
name={it.result.name}
Expand All @@ -169,7 +147,7 @@ const ResultList = ({
<Tabs.Panel className="flex flex-col gap-4" value="dataproduct">
{dataproducts.map(
(d, idx) =>
d.result.__typename === 'Dataproduct' && (
isDataProduct(d.result) && (
<SearchResultLink
key={idx}
group={d.result.owner}
Expand All @@ -184,7 +162,7 @@ const ResultList = ({
)}
</Tabs.Panel>
</Tabs>
{data.search.length == 0 && 'ingen resultater'}
{data.results.length == 0 && 'ingen resultater'}
</Results>
)
}
Expand Down
6 changes: 2 additions & 4 deletions components/search/searchResultLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ export interface SearchResultProps {
description?: string
datasets?: {
name: string
datasource: {
lastModified: string,
}
dataSourceLastModified: string
}[]
teamkatalogenTeam?: string,
productArea?: string,
Expand Down Expand Up @@ -140,7 +138,7 @@ export const SearchResultLink = ({
{datasets.map((ds, index) => (
<div key={index}>
<p dangerouslySetInnerHTML={{ __html: ds.name.replaceAll("_", "_<wbr>") }} />
<Detail className="text-text-subtle">Sist oppdatert: {humanizeDate(ds.datasource.lastModified)}</Detail>
<Detail className="text-text-subtle">Sist oppdatert: {humanizeDate(ds.dataSourceLastModified)}</Detail>
</div>
))}
</div>
Expand Down
10 changes: 0 additions & 10 deletions lib/queries/search/resultCount.tsx

This file was deleted.

35 changes: 0 additions & 35 deletions lib/queries/search/searchResult.ts

This file was deleted.

48 changes: 0 additions & 48 deletions lib/queries/search/searchResultWithOptions.ts

This file was deleted.

40 changes: 33 additions & 7 deletions lib/rest/restApi.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,47 @@
import { SearchOptions } from "./search"

const isServer = typeof window === 'undefined'

export const apiUrl = () => {
if (process.env.NEXT_PUBLIC_ENV === 'development') {
return 'http://localhost:8080/api'
}
return isServer ? 'http://nada-backend/api' : '/api'
if (process.env.NEXT_PUBLIC_ENV === 'development') {
return 'http://localhost:8080/api'
}
return isServer ? 'http://nada-backend/api' : '/api'
}

export const getDataproductUrl = (id: string) => `${apiUrl()}/dataproducts/${id}`
export const getDatasetUrl = (id: string) => `${apiUrl()}/datasets/${id}`
export const getProductAreasUrl = () => `${apiUrl()}/productareas`
export const getProductAreaUrl = (id: string) => `${apiUrl()}/productareas/${id}`
export const searchTeamKatalogenUrl = (gcpGroups?: string[]) =>
{
const parameters = gcpGroups?.length ? gcpGroups.map(group => `gcpGroups=${encodeURIComponent(group)}`).join('&'): ''
export const searchTeamKatalogenUrl = (gcpGroups?: string[]) => {
const parameters = gcpGroups?.length ? gcpGroups.map(group => `gcpGroups=${encodeURIComponent(group)}`).join('&') : ''
const query = parameters ? `?${parameters}` : ''
return `${apiUrl()}/teamkatalogen${query}`
}

export const searchUrl = (options: SearchOptions) => {
let queryParams: string[] = [];

// Helper function to add array-based options
const addArrayOptions = (optionArray: string[] | undefined, paramName: string) => {
if (optionArray && optionArray.length) {
queryParams.push(`${paramName}=${optionArray.reduce((s, p) => `${s ? `${s},` : ""}${encodeURIComponent(p)}`)}`)
}
};

// Adding array-based options
addArrayOptions(options.keywords, 'keywords');
addArrayOptions(options.groups, 'groups');
addArrayOptions(options.teamIDs, 'teamIDs');
addArrayOptions(options.services, 'services');
addArrayOptions(options.types, 'types');

// Adding single-value options
if (options.text) queryParams.push(`text=${encodeURIComponent(options.text)}`);
if (options.limit !== undefined) queryParams.push(`limit=${options.limit}`);
if (options.offset !== undefined) queryParams.push(`offset=${options.offset}`);

const query = queryParams.length ? `?${queryParams.join('&')}` : '';
return `${apiUrl()}/search${query}`;
};

59 changes: 59 additions & 0 deletions lib/rest/search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useEffect, useState } from "react"
import { searchUrl } from "./restApi"

export interface SearchOptions {
// Freetext search
text?: string
// Filter on keyword
keywords?: string[]
// Filter on group
groups?: string[]
//Filter on team_id
teamIDs?: string[]
// Filter on enabled services
services?: string[]
// Filter on types
types?: string[]

limit?: number
offset?: number
}

export interface SearchResult{
results: any[]
}

const search = async (o: SearchOptions)=>{
const url = searchUrl(o);
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
}
return fetch(url, options)
}

export const useSearch = (o: SearchOptions)=>{
const [data, setData] = useState<SearchResult|undefined>(undefined)
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)


useEffect(()=>{
search(o).then((res)=> res.json())
.then((data)=>
{
setError(null)
setData(data)
})
.catch((err)=>{
setError(err)
setData(undefined)
}).finally(()=>{
setLoading(false)
})
}, [o?JSON.stringify(o):""])

return {data, loading, error}
}
Loading