Skip to content

Commit 365e4f2

Browse files
committed
Tweaker visning av søkeresultat
1 parent 118b21a commit 365e4f2

File tree

5 files changed

+71
-37
lines changed

5 files changed

+71
-37
lines changed

common/contentSearch.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export type ContentSearchHit = Pick<
55
'contentKey' | 'versionKey' | 'displayName' | 'path'
66
> & { score: number };
77

8-
export type ContentSearchStatus = 'loading' | 'error' | 'success';
8+
export type ContentSearchStatus = 'loading' | 'error' | 'success' | 'empty';
99

1010
export type ContentSearchResult = {
1111
total: number;

src/components/left-section/search/search-input/SearchInput.tsx

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useRef } from 'react';
22
import { Search } from '@navikt/ds-react';
3-
import { useApiFetch } from '../../../../fetch/useApiFetch';
43
import { classNames } from '../../../../utils/classNames';
54
import { SearchSettings } from './search-settings/SearchSettings';
65
import { useSearchState } from '../../../../context/search-state/useSearchState';
@@ -12,12 +11,10 @@ type Props = {
1211
};
1312

1413
export const SearchInput = ({ className }: Props) => {
15-
const { setSearchResult, searchParams, setSearchParams } = useSearchState();
14+
const { setSearchResult, searchParams, setSearchParams, runSearch } = useSearchState();
1615

1716
const inputRef = useRef<HTMLInputElement>(null);
1817

19-
const { fetchSearch } = useApiFetch();
20-
2118
return (
2219
<div className={classNames(style.search, className)}>
2320
<SearchSettings />
@@ -37,9 +34,7 @@ export const SearchInput = ({ className }: Props) => {
3734
status: 'loading',
3835
});
3936

40-
fetchSearch(searchParams).then((result) => {
41-
setSearchResult(result);
42-
});
37+
runSearch(searchParams);
4338
}}
4439
>
4540
<Search
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,47 @@
11
import React from 'react';
22
import { classNames } from '../../../../utils/classNames';
3-
import { Button, Heading } from '@navikt/ds-react';
3+
import { Alert, Button, Heading } from '@navikt/ds-react';
44
import { SearchResultHit } from './search-hit/SearchResultHit';
55
import { ContentLoader } from '../../../common/loader/ContentLoader';
66
import { useSearchState } from '../../../../context/search-state/useSearchState';
77

88
import style from './SearchResult.module.css';
99

1010
export const SearchResult = () => {
11-
const { searchResult, setSearchResult } = useSearchState();
11+
const { searchResult, setSearchResultIsOpen } = useSearchState();
12+
const { hits, total, status, params } = searchResult;
1213

1314
return (
1415
<div className={classNames(style.result)}>
15-
{searchResult?.status === 'loading' && (
16+
{status === 'loading' ? (
1617
<ContentLoader size={'3xlarge'} text={'Laster søketreff...'} />
17-
)}
18-
{searchResult && searchResult.status !== 'loading' && (
19-
<div className={style.header}>
20-
<Heading
21-
size={'small'}
22-
level={'2'}
23-
>{`Treff for "${searchResult.params.query}" (${searchResult.total})`}</Heading>
24-
<Button
25-
size={'xsmall'}
26-
variant={'tertiary'}
27-
onClick={() => setSearchResult(null)}
28-
>
29-
{'Lukk'}
30-
</Button>
31-
</div>
32-
)}
33-
{searchResult?.hits.map((hit) => <SearchResultHit hit={hit} key={hit.versionKey} />)}
18+
) : status === 'error' ? (
19+
<Alert variant={'error'}>
20+
{
21+
'Feil: søket kunne ikke utføres. Prøv igjen, eller kontakt brukerstøtte dersom problemet vedvarer.'
22+
}
23+
</Alert>
24+
) : status === 'success' ? (
25+
<>
26+
<div className={style.header}>
27+
<Heading
28+
size={'small'}
29+
level={'2'}
30+
>{`Treff for "${params.query}" (${total})`}</Heading>
31+
<Button
32+
size={'xsmall'}
33+
variant={'tertiary'}
34+
onClick={() => setSearchResultIsOpen(false)}
35+
>
36+
{'Lukk'}
37+
</Button>
38+
</div>
39+
{hits.map((hit) => (
40+
<SearchResultHit hit={hit} key={hit.versionKey} />
41+
))}
42+
)
43+
</>
44+
) : null}
3445
</div>
3546
);
3647
};

src/context/search-state/SearchStateContext.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import { createContext } from 'react';
22
import { ContentSearchParams, ContentSearchResult } from '../../../common/contentSearch';
33

44
export type SearchState = {
5-
searchResult: ContentSearchResult | null;
6-
setSearchResult: (result: ContentSearchResult | null) => void;
5+
searchResult: ContentSearchResult;
6+
setSearchResult: (result: ContentSearchResult) => void;
77
searchResultIsOpen: boolean;
88
setSearchResultIsOpen: (isOpen: boolean) => void;
99
searchParams: ContentSearchParams;
1010
setSearchParams: (params: ContentSearchParams) => void;
1111
updateSearchParams: (params: Partial<ContentSearchParams>) => void;
1212
resetSearchSettings: () => void;
13+
runSearch: (params: ContentSearchParams) => void;
1314
};
1415

1516
export const initialSearchParams: ContentSearchParams = {
@@ -18,13 +19,21 @@ export const initialSearchParams: ContentSearchParams = {
1819
withChildCategories: true,
1920
} as const;
2021

22+
export const emptySearchResult: ContentSearchResult = {
23+
total: 0,
24+
hits: [],
25+
status: 'empty',
26+
params: initialSearchParams,
27+
} as const;
28+
2129
export const SearchStateContext = createContext<SearchState>({
22-
searchResult: null,
30+
searchResult: emptySearchResult,
2331
setSearchResult: () => ({}),
2432
searchResultIsOpen: false,
2533
setSearchResultIsOpen: () => ({}),
2634
searchParams: initialSearchParams,
2735
setSearchParams: () => ({}),
2836
updateSearchParams: () => ({}),
2937
resetSearchSettings: () => ({}),
38+
runSearch: () => ({}),
3039
});

src/context/search-state/SearchStateProvider.tsx

+25-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
import React, { useEffect, useState } from 'react';
2-
import { initialSearchParams, SearchState, SearchStateContext } from './SearchStateContext';
3-
import { ContentSearchParams } from '../../../common/contentSearch';
2+
import { emptySearchResult, initialSearchParams, SearchStateContext } from './SearchStateContext';
3+
import { ContentSearchParams, ContentSearchResult } from '../../../common/contentSearch';
44
import { getInitialSearchParams, persistSearchParams } from './search-settings-cookies';
55
import { useAppState } from '../app-state/useAppState';
6+
import { useApiFetch } from '../../fetch/useApiFetch';
67

7-
export const SearchStateProvider = ({ children }: { children: React.ReactNode }) => {
8+
type Props = {
9+
children: React.ReactNode;
10+
};
11+
12+
export const SearchStateProvider = ({ children }: Props) => {
813
const { appContext } = useAppState();
914
const { basePath } = appContext;
15+
const { fetchSearch } = useApiFetch();
1016

11-
const [searchResult, setSearchResult] = useState<SearchState['searchResult']>(null);
12-
const [searchParams, setSearchParams] = useState<SearchState['searchParams']>(
17+
const [searchResult, setSearchResult] = useState<ContentSearchResult>(emptySearchResult);
18+
const [searchParams, setSearchParams] = useState<ContentSearchParams>(
1319
getInitialSearchParams(basePath)
1420
);
1521
const [searchResultIsOpen, setSearchResultIsOpen] = useState(false);
@@ -23,8 +29,20 @@ export const SearchStateProvider = ({ children }: { children: React.ReactNode })
2329
const resetSearchSettings = () =>
2430
setSearchParams({ ...initialSearchParams, query: searchParams.query });
2531

32+
const runSearch = (params: ContentSearchParams) =>
33+
fetchSearch(params).then((result) => {
34+
setSearchResult(
35+
result || {
36+
total: 0,
37+
hits: [],
38+
status: 'error',
39+
params: params,
40+
}
41+
);
42+
});
43+
2644
useEffect(() => {
27-
setSearchResultIsOpen(!!searchResult);
45+
setSearchResultIsOpen(searchResult.status !== 'empty');
2846
}, [searchResult]);
2947

3048
return (
@@ -38,6 +56,7 @@ export const SearchStateProvider = ({ children }: { children: React.ReactNode })
3856
setSearchResultIsOpen,
3957
updateSearchParams,
4058
resetSearchSettings,
59+
runSearch,
4160
}}
4261
>
4362
{children}

0 commit comments

Comments
 (0)