Skip to content

Commit

Permalink
[Enterprise Search] Engines Search Preview - "Sort By" (elastic#152253)
Browse files Browse the repository at this point in the history
## Summary


https://user-images.githubusercontent.com/1699281/222561456-55666a32-0508-4c49-b721-4bd71afb0d72.mov

### Checklist

Delete any items that are not applicable to this PR.

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
  • Loading branch information
Sloane Perrault authored and bmorelli25 committed Mar 10, 2023
1 parent 5685803 commit 7a1592b
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
ResultView,
ResultsPerPageView,
ResultsView,
Sorting,
} from './search_ui_components';

class InternalEngineTransporter implements Transporter {
Expand Down Expand Up @@ -85,7 +86,7 @@ export const EngineSearchPreview: React.FC = () => {
const [showAPICallFlyout, setShowAPICallFlyout] = useState<boolean>(false);
const [lastAPICall, setLastAPICall] = useState<null | APICallData>(null);
const { engineName, isLoadingEngine } = useValues(EngineViewLogic);
const { resultFields, searchableFields } = useValues(EngineSearchPreviewLogic);
const { resultFields, searchableFields, sortableFields } = useValues(EngineSearchPreviewLogic);
const { engineData } = useValues(EngineIndicesLogic);

const config: SearchDriverOptions = useMemo(() => {
Expand Down Expand Up @@ -141,6 +142,8 @@ export const EngineSearchPreview: React.FC = () => {
<EuiFlexItem grow={false} css={{ minWidth: '240px' }}>
<ResultsPerPage view={ResultsPerPageView} options={RESULTS_PER_PAGE_OPTIONS} />
<EuiSpacer size="m" />
<Sorting sortableFields={sortableFields} />
<EuiSpacer size="m" />
<EuiLink href={docLinks.enterpriseSearchEngines} target="_blank">
<FormattedMessage
id="xpack.enterpriseSearch.content.engine.searchPreview.improveResultsLink"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface EngineSearchPreviewValues {
engineName: typeof EngineNameLogic.values.engineName;
resultFields: Record<string, FieldConfiguration>;
searchableFields: Record<string, SearchFieldConfiguration>;
sortableFields: string[];
}

export const EngineSearchPreviewLogic = kea<
Expand Down Expand Up @@ -86,5 +87,21 @@ export const EngineSearchPreviewLogic = kea<
return searchableFields;
},
],
sortableFields: [
() => [selectors.engineFieldCapabilitiesData],
(data: EngineSearchPreviewValues['engineFieldCapabilitiesData']) => {
if (!data) return [];

return Object.entries(data.field_capabilities.fields)
.filter(([, mappings]) =>
Object.entries(mappings).some(
([, { metadata_field: isMeta, aggregatable }]) =>
// Aggregatable are also _sortable_
aggregatable && !isMeta
)
)
.map(([field]) => field);
},
],
}),
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,27 @@ import {
EuiBasicTable,
EuiBasicTableColumn,
EuiButton,
EuiComboBox,
EuiFieldSearch,
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
EuiPanel,
EuiSelect,
EuiSpacer,
EuiText,
EuiTextColor,
EuiTitle,
} from '@elastic/eui';
import { withSearch } from '@elastic/react-search-ui';
import type {
InputViewProps,
PagingInfoViewProps,
ResultViewProps,
ResultsPerPageViewProps,
ResultsViewProps,
} from '@elastic/react-search-ui-views';
import type { SearchContextState } from '@elastic/search-ui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage, FormattedHTMLMessage } from '@kbn/i18n-react';

Expand Down Expand Up @@ -224,3 +228,85 @@ export const ResultsPerPageView: React.FC<ResultsPerPageViewProps> = ({
</EuiFlexGroup>
</EuiFlexItem>
);

export const Sorting = withSearch<
{ sortableFields: string[] },
Pick<SearchContextState, 'setSort' | 'sortList'>
>(({ setSort, sortList }) => ({ setSort, sortList }))(({ sortableFields, sortList, setSort }) => {
const [{ direction, field }] = !sortList?.length ? [{ direction: '', field: '' }] : sortList;
const relevance = i18n.translate(
'xpack.enterpriseSearch.content.engine.searchPreivew.sortingView.relevanceLabel',
{ defaultMessage: 'Relevance' }
);

return (
<EuiFlexItem grow={false}>
<EuiFlexGroup direction="column" gutterSize="s">
<EuiTitle size="xxxs">
<label htmlFor="sorting-field">
<FormattedMessage
id="xpack.enterpriseSearch.content.engine.searchPreview.sortingView.fieldLabel"
defaultMessage="Sort By"
/>
</label>
</EuiTitle>
<EuiComboBox
id="sorting-field"
isClearable={false}
singleSelection={{ asPlainText: true }}
options={[
{ label: relevance, value: '' },
...sortableFields.map((f: string) => ({ label: f, value: f })),
]}
selectedOptions={[{ label: !!field ? field : relevance, value: field }]}
onChange={([{ value }]) =>
setSort(value === '' ? [] : [{ direction: 'asc', field: value }], 'asc')
}
/>
</EuiFlexGroup>
{field !== '' && (
<>
<EuiSpacer size="m" />
<EuiFlexGroup direction="column" gutterSize="s">
<EuiTitle size="xxxs">
<label htmlFor="sorting-direction">
<FormattedMessage
id="xpack.enterpriseSearch.content.engine.searchPreview.sortingView.directionLabel"
defaultMessage="Order By"
/>
</label>
</EuiTitle>
<EuiSelect
id="sorting-direction"
onChange={(evt) => {
switch (evt.target.value) {
case 'asc':
return setSort([{ direction: 'asc', field }], 'asc');
case 'desc':
return setSort([{ direction: 'desc', field }], 'desc');
}
}}
value={direction}
options={[
{
text: i18n.translate(
'xpack.enterpriseSearch.content.engine.searchPreview.sortingView.ascLabel',
{ defaultMessage: 'Ascending' }
),
value: 'asc',
},
{
text: i18n.translate(
'xpack.enterpriseSearch.content.engine.searchPreview.sortingView.descLabel',
{ defaultMessage: 'Descending' }
),
value: 'desc',
},
]}
/>
</EuiFlexGroup>
</>
)}
</EuiFlexItem>
);
});

0 comments on commit 7a1592b

Please sign in to comment.