1
0
Fork 0

feat(noResults): allow providing URL to report missing results (#1289)

This commit is contained in:
Clément Vannicatte 2022-02-02 10:39:44 +01:00 committed by GitHub
parent e324f4ce51
commit 2c1fe7c77c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 149 additions and 41 deletions

View file

@ -42,6 +42,7 @@ export interface DocSearchProps {
initialQuery?: string;
navigator?: AutocompleteOptions<InternalDocSearchHit>['navigator'];
translations?: DocSearchTranslations;
getMissingResultsUrl?: ({ query: string }) => string;
}
export function DocSearch(props: DocSearchProps) {

View file

@ -50,6 +50,7 @@ export function DocSearchModal({
disableUserPersonalization = false,
initialQuery: initialQueryFromProp = '',
translations = {},
getMissingResultsUrl,
}: DocSearchModalProps) {
const {
footer: footerTranslations,
@ -429,6 +430,7 @@ export function DocSearchModal({
favoriteSearches={favoriteSearches}
inputRef={inputRef}
translations={screenStateTranslations}
getMissingResultsUrl={getMissingResultsUrl}
onItemClick={(item) => {
saveRecentSearch(item);
onClose();

View file

@ -7,8 +7,8 @@ import type { InternalDocSearchHit } from './types';
export type NoResultsScreenTranslations = Partial<{
noResultsText: string;
suggestedQueryText: string;
openIssueText: string;
openIssueLinkText: string;
reportMissingResultsText: string;
reportMissingResultsLinkText: string;
}>;
type NoResultsScreenProps = Omit<
@ -25,8 +25,8 @@ export function NoResultsScreen({
const {
noResultsText = 'No results for',
suggestedQueryText = 'Try searching for',
openIssueText = 'Believe this query should return results?',
openIssueLinkText = 'Let us know',
reportMissingResultsText = 'Believe this query should return results?',
reportMissingResultsLinkText = 'Let us know.',
} = translations;
const searchSuggestions: string[] | undefined = props.state.context
.searchSuggestions as string[];
@ -68,17 +68,18 @@ export function NoResultsScreen({
</div>
)}
<p className="DocSearch-Help">
{`${openIssueText} `}
<a
href={`https://github.com/algolia/docsearch-configs/issues/new?template=Missing_results.md&title=[${props.indexName}]+Missing+results+for+query+"${props.state.query}"`}
target="_blank"
rel="noopener noreferrer"
>
{openIssueLinkText}
</a>
.
</p>
{props.getMissingResultsUrl && (
<p className="DocSearch-Help">
{`${reportMissingResultsText} `}
<a
href={props.getMissingResultsUrl({ query: props.state.query })}
target="_blank"
rel="noopener noreferrer"
>
{reportMissingResultsLinkText}
</a>
</p>
)}
</div>
);
}

View file

@ -39,6 +39,7 @@ export interface ScreenStateProps<TItem extends BaseItem>
disableUserPersonalization: boolean;
resultsFooterComponent: DocSearchProps['resultsFooterComponent'];
translations: ScreenStateTranslations;
getMissingResultsUrl?: DocSearchProps['getMissingResultsUrl'];
}
export const ScreenState = React.memo(

View file

@ -16,6 +16,27 @@ function DocSearch(props: Partial<DocSearchProps>) {
return <DocSearchComponent apiKey="foo" indexName="bar" {...props} />;
}
// mock empty response
function noResultSearch(_queries: any, _requestOptions?: any): Promise<any> {
return new Promise((resolve) => {
resolve({
results: [
{
hits: [],
hitsPerPage: 0,
nbHits: 0,
nbPages: 0,
page: 0,
processingTimeMS: 0,
exhaustiveNbHits: true,
params: '',
query: '',
},
],
});
});
}
describe('api', () => {
beforeEach(() => {
document.body.innerHTML = '';
@ -71,40 +92,23 @@ describe('api', () => {
it('overrides the default DocSearchModal noResultsScreen text', async () => {
render(
<DocSearch
// mock empty response
transformSearchClient={(searchClient) => {
return {
...searchClient,
search: () => {
return new Promise((resolve) => {
resolve({
results: [
{
hits: [],
hitsPerPage: 0,
nbHits: 0,
nbPages: 0,
page: 0,
processingTimeMS: 0,
exhaustiveNbHits: true,
params: '',
query: '',
},
],
});
});
},
search: noResultSearch,
};
}}
translations={{
modal: {
noResultsScreen: {
noResultsText: 'Pas de résultats pour',
openIssueText: 'Ouvrez une issue sur docsearch-configs',
openIssueLinkText: 'Lien du repo',
reportMissingResultsText:
'Ouvrez une issue sur docsearch-configs',
reportMissingResultsLinkText: 'Lien du repo',
},
},
}}
getMissingResultsUrl={() => 'algolia.com'}
/>
);
@ -190,4 +194,68 @@ describe('api', () => {
expect(screen.getByText('Selectionner')).toBeInTheDocument();
});
});
describe('getMissingResultsUrl', () => {
it('does not render the link to the repository by default', async () => {
render(
<DocSearch
transformSearchClient={(searchClient) => {
return {
...searchClient,
search: noResultSearch,
};
}}
/>
);
await act(async () => {
await waitFor(() => {
fireEvent.click(document.querySelector('.DocSearch-Button'));
});
fireEvent.input(document.querySelector('.DocSearch-Input'), {
target: { value: 'q' },
});
});
expect(screen.getByText(/No results for/)).toBeInTheDocument();
expect(
document.querySelector('.DocSearch-Help a')
).not.toBeInTheDocument();
});
it('render the link to the repository', async () => {
render(
<DocSearch
transformSearchClient={(searchClient) => {
return {
...searchClient,
search: noResultSearch,
};
}}
getMissingResultsUrl={({ query }) =>
`https://github.com/algolia/docsearch/issues/new?title=${query}`
}
/>
);
await act(async () => {
await waitFor(() => {
fireEvent.click(document.querySelector('.DocSearch-Button'));
});
fireEvent.input(document.querySelector('.DocSearch-Input'), {
target: { value: 'q' },
});
});
expect(screen.getByText(/No results for/)).toBeInTheDocument();
const link = document.querySelector('.DocSearch-Help a');
expect(link).toBeInTheDocument();
expect(link.getAttribute('href')).toBe(
'https://github.com/algolia/docsearch/issues/new?title=q'
);
});
});
});

View file

@ -4,6 +4,7 @@ title: API Reference
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import useBaseUrl from '@docusaurus/useBaseUrl';
:::info
@ -160,8 +161,8 @@ const translations: DocSearchTranslations = {
noResultsScreen: {
noResultsText: 'No results for',
suggestedQueryText: 'Try searching for',
openIssueText: 'Believe this query should return results?',
openIssueLinkText: 'Let us know',
reportMissingResultsText: 'Believe this query should return results?',
reportMissingResultsLinkText: 'Let us know.',
},
},
};
@ -170,6 +171,23 @@ const translations: DocSearchTranslations = {
</div>
</details>
## `getMissingResultsUrl`
> `type: ({ query: string }) => string` | **optional**
> example: ({ query }) => `https://github.com/algolia/docsearch/issues/new?title=${query}`
Function to return the URL of your documentation repository.
When provided, an informative message wrapped with your link will be displayed on no results searches. The default text can be changed using the [translations](#translations) property.
<div className="uil-ta-center">
<img
src={useBaseUrl('img/assets/noResultsScreen.png')}
alt="No results screen with informative message"
/>
</div>
</TabItem>
<TabItem value="react">
@ -299,8 +317,8 @@ const translations: DocSearchTranslations = {
noResultsScreen: {
noResultsText: 'No results for',
suggestedQueryText: 'Try searching for',
openIssueText: 'Believe this query should return results?',
openIssueLinkText: 'Let us know',
reportMissingResultsText: 'Believe this query should return results?',
reportMissingResultsLinkText: 'Let us know.',
},
},
};
@ -309,6 +327,23 @@ const translations: DocSearchTranslations = {
</div>
</details>
## `getMissingResultsUrl`
> `type: ({ query: string }) => string` | **optional**
> example: ({ query }) => `https://github.com/algolia/docsearch/issues/new?title=${query}`
Function to return the URL of your documentation repository.
When provided, an informative message wrapped with your link will be displayed on no results searches. The default text can be changed using the [translations](#translations) property.
<div className="uil-ta-center">
<img
src={useBaseUrl('img/assets/noResultsScreen.png')}
alt="No results screen with informative message"
/>
</div>
</TabItem>
</Tabs>

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB