Skip to content

Commit 2b26780

Browse files
Merge pull request #1703 from ral-facilities/feature/add-examples-section-advanced-search-help
Add examples section to advanced help dialogue
2 parents bae84ca + dcb2e1d commit 2b26780

File tree

3 files changed

+117
-4
lines changed

3 files changed

+117
-4
lines changed

packages/datagateway-search/public/res/default.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,20 @@
303303
"close_button_arialabel": "Close",
304304
"title": "Advanced Search Tips",
305305
"description": "Searching the metadata catalogue using one or more words should be intuitive, with the most relevant matches appearing first. However, there is a powerful syntax that supports more advanced use cases, which are described below.",
306+
"examples": {
307+
"title": "Examples",
308+
"description": "Below are a few examples of common searches and how they can be crafted to execute efficiently for those with access to large volumes of data:",
309+
"examples": [
310+
{
311+
"name": "To search for a visit and partial location",
312+
"value": "+visitId:\"nt20-8\" +location:\"jpegs/pg1/\""
313+
},
314+
{
315+
"name": "To search for a visit, partial location and filename ext",
316+
"value": "+visitId:\"nt20-8\" +location:\" jpegs/pg1/\" +(location:jpeg location:*.jpeg)"
317+
}
318+
]
319+
},
306320
"terms": {
307321
"title": "Terms",
308322
"description": "By default, all words in the search text are treated as separate <strong>terms</strong>. Results must contain at least one <strong>term</strong> to be returned, and they can occur in any order in the result. When using the default relevancy based sorting, results containing the most <strong>terms</strong> will appear first. For example, <10>neutron scattering</10> will return results containing both <strong>terms</strong> first, then results containing only one or the other.",

packages/datagateway-search/src/search/advancedHelpDialogue.component.test.tsx

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { initialState as dgSearchInitialState } from '../state/reducers/dgsearch.reducer';
1616
import { StateType } from '../state/app.types';
1717
import userEvent from '@testing-library/user-event';
18+
import reactI18Next from 'react-i18next';
1819

1920
jest.mock('react-redux', () => ({
2021
...jest.requireActual('react-redux'),
@@ -37,6 +38,8 @@ function renderComponent({
3738

3839
describe('Advanced help dialogue', () => {
3940
let state: StateType;
41+
const tSpy = jest.fn((str) => str);
42+
let originalUseTranslation: typeof reactI18Next.useTranslation;
4043

4144
beforeEach(() => {
4245
state = JSON.parse(
@@ -45,6 +48,13 @@ describe('Advanced help dialogue', () => {
4548
dgsearch: dgSearchInitialState,
4649
})
4750
);
51+
52+
originalUseTranslation = reactI18Next.useTranslation;
53+
reactI18Next.useTranslation = jest.fn().mockReturnValue([tSpy]);
54+
});
55+
56+
afterEach(() => {
57+
reactI18Next.useTranslation = originalUseTranslation;
4858
});
4959

5060
it('is hidden initially', () => {
@@ -66,7 +76,7 @@ describe('Advanced help dialogue', () => {
6676
);
6777

6878
expect(
69-
screen.getByRole('dialog', { name: 'Advanced Search Tips' })
79+
screen.getByRole('dialog', { name: 'advanced_search_help.title' })
7080
).toBeInTheDocument();
7181

7282
await user.click(
@@ -75,11 +85,42 @@ describe('Advanced help dialogue', () => {
7585
})
7686
);
7787

88+
// advanced_search_help.examples.examples is not an array so example section is not rendered
89+
expect(
90+
screen.queryByText('advanced_search_help.examples.title')
91+
).not.toBeInTheDocument();
92+
7893
await waitForElementToBeRemoved(
79-
screen.getByRole('dialog', { name: 'Advanced Search Tips' })
94+
screen.getByRole('dialog', { name: 'advanced_search_help.title' })
8095
);
8196
expect(
82-
screen.queryByRole('dialog', { name: 'Advanced Search Tips' })
97+
screen.queryByRole('dialog', { name: 'advanced_search_help.title' })
8398
).toBeNull();
8499
});
100+
101+
it('renders examples section when an example is given', async () => {
102+
tSpy.mockImplementation((key) => {
103+
if (key === 'advanced_search_help.examples.examples') {
104+
return [{ name: 'example 1', value: 'example 1' }];
105+
} else return key;
106+
});
107+
const user = userEvent.setup();
108+
109+
renderComponent({ initialState: state });
110+
111+
await user.click(
112+
screen.getByRole('button', {
113+
name: 'advanced_search_help.search_options_arialabel',
114+
})
115+
);
116+
117+
expect(
118+
screen.getByRole('dialog', { name: 'advanced_search_help.title' })
119+
).toBeInTheDocument();
120+
121+
// advanced_search_help.examples.examples is an array with items in it so we should render example section
122+
expect(
123+
screen.getByText('advanced_search_help.examples.title')
124+
).toBeInTheDocument();
125+
});
85126
});

packages/datagateway-search/src/search/advancedHelpDialogue.component.tsx

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ import {
66
IconButton,
77
Link,
88
styled,
9+
Table,
10+
TableBody,
11+
TableRow,
12+
TableCell,
913
Theme,
1014
Typography,
15+
TableContainer,
16+
Paper,
1117
} from '@mui/material';
1218
import CloseIcon from '@mui/icons-material/Close';
1319
import { Trans, useTranslation } from 'react-i18next';
@@ -80,7 +86,7 @@ const AdvancedHelpDialogue = (): React.ReactElement => {
8086
}}
8187
>
8288
<DialogTitle id="advanced-search-dialog-title">
83-
Advanced Search Tips
89+
{t('advanced_search_help.title')}
8490
<IconButton
8591
aria-label={t('advanced_search_help.close_button_arialabel')}
8692
sx={{
@@ -99,6 +105,58 @@ const AdvancedHelpDialogue = (): React.ReactElement => {
99105
<Typography gutterBottom>
100106
{t('advanced_search_help.description')}
101107
</Typography>
108+
{Array.isArray(
109+
t('advanced_search_help.examples.examples', {
110+
returnObjects: true,
111+
})
112+
) &&
113+
(
114+
t('advanced_search_help.examples.examples', {
115+
returnObjects: true,
116+
}) as { name: string; value: string }[]
117+
).length > 0 && (
118+
<Section>
119+
<SectionTitle>
120+
{t('advanced_search_help.examples.title')}
121+
</SectionTitle>
122+
<SectionText>
123+
<Trans
124+
t={t}
125+
i18nKey="advanced_search_help.examples.description"
126+
>
127+
Below are a few examples of common searches and how they can
128+
be crafted to execute efficiently for those with access to
129+
large volumes of data:
130+
</Trans>
131+
</SectionText>
132+
133+
<TableContainer component={Paper}>
134+
<Table size="small">
135+
<TableBody>
136+
{(
137+
t('advanced_search_help.examples.examples', {
138+
returnObjects: true,
139+
}) as { name: string; value: string }[]
140+
).map(({ name, value }, index) => (
141+
<TableRow key={index}>
142+
<TableCell>{name}</TableCell>
143+
<TableCell>
144+
<Link
145+
component={RouterLink}
146+
to={`?searchText=${value}`}
147+
onClick={handleClose}
148+
>
149+
{value}
150+
</Link>
151+
</TableCell>
152+
</TableRow>
153+
))}
154+
</TableBody>
155+
</Table>
156+
</TableContainer>
157+
</Section>
158+
)}
159+
102160
<Section>
103161
<SectionTitle>{t('advanced_search_help.terms.title')}</SectionTitle>
104162
<SectionText>

0 commit comments

Comments
 (0)