Skip to content

Commit

Permalink
Merge pull request #295 from performant-software/feature/basira290_fa…
Browse files Browse the repository at this point in the history
…cet_tooltip

BASIRA #290 - Facet tooltip
  • Loading branch information
dleadbetter authored Dec 24, 2024
2 parents ae17f51 + ef8c109 commit 10498ee
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 74 deletions.
3 changes: 3 additions & 0 deletions app/controllers/api/value_lists_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class Api::ValueListsController < Api::BaseController
# Preloads
preloads :qualifications, only: [:index, :show]

# Actions
skip_before_action :authenticate_user!, only: :index

def objects_list
objects_list = ValueList
.all
Expand Down
4 changes: 2 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"dependencies": {
"@babel/eslint-parser": "^7.21.3",
"@babel/runtime": "^7.22.3",
"@performant-software/semantic-components": "^2.2.18",
"@performant-software/shared-components": "^2.2.18",
"@performant-software/semantic-components": "^2.2.20",
"@performant-software/shared-components": "^2.2.20",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
Expand Down
15 changes: 15 additions & 0 deletions client/src/components/SearchFacet.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.search-facet.facet-list .facet-label {
display: flex;
justify-content: space-between;
padding-right: 0.5em;
width: 100%;
}

.search-facet.facet-list .facet-label > .label {
padding-right: 1em;
}

.search-facet.facet-list .facet-label .info-button {
margin-left: 0.5em;
padding: 0.5em;
}
126 changes: 126 additions & 0 deletions client/src/components/SearchFacet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// @flow

import { FacetList } from '@performant-software/semantic-components';
import React, {
forwardRef,
useCallback,
useMemo,
useState
} from 'react';
import { useRefinementList } from 'react-instantsearch-hooks-web';
import { Button, Popup } from 'semantic-ui-react';
import _ from 'underscore';
import ValueLists from '../services/ValueLists';
import './SearchFacet.css';

const MAX_SHOW_MORE_LIMIT = 1000;

type Props = {
attribute: string,
defaultActive?: boolean,
group: string,
object: string,
showMore?: boolean,
title?: string,
toggleable: boolean
};

const SearchFacet = forwardRef((props: Props, ref: HTMLElement) => {
const [loaded, setLoaded] = useState(false);
const [valueLists, setValueLists] = useState([]);

/**
* Groups the facets by the name value for lookup.
*/
const groupedValueLists = useMemo(() => _.indexBy(valueLists, 'human_name'), [valueLists]);

/**
* Returns the "comment" attribute for the value list with the passed name.
*
* @type {function(*): *}
*/
const getDescription = useCallback((item) => {
let description;

const valueList = groupedValueLists[item.value];
if (valueList) {
description = valueList.comment;
}

return description;
}, [groupedValueLists]);

/**
* Fetches the value lists for the object/group when the facet becomes active.
*
* @type {(function(): void)|*}
*/
const onActive = useCallback(() => {
if (loaded) {
return;
}

ValueLists
.fetchAll({ object_filter: props.object, group_filter: props.group, per_page: 0})
.then(({ data }) => setValueLists(data.value_lists))
.finally(() => setLoaded(true));
}, [loaded, props.group, props.object]);

/**
* Renders the label for the passed item.
*
* @type {unknown}
*/
const renderLabel = useCallback((item) => {
const description = getDescription(item);

return (
<div
className='facet-label'
>
<div
className='label'
>
{ item.label }
{ description && (
<Popup
content={description}
hideOnScroll
mouseEnterDelay={500}
mouseLeaveDelay={500}
on='hover'
trigger={(
<Button
basic
className='info-button'
circular
size='mini'
icon='info'
/>
)}
/>
)}
</div>
<span>{ item.count }</span>
</div>
);
}, [getDescription]);

return (
<FacetList
attribute={props.attribute}
className='search-facet'
defaultActive={props.defaultActive}
onActive={onActive}
ref={ref}
renderLabel={renderLabel}
showMore={props.showMore}
showMoreLimit={MAX_SHOW_MORE_LIMIT}
title={props.title}
toggleable={props.toggleable}
useRefinementList={useRefinementList}
/>
);
});

export default SearchFacet;
Loading

0 comments on commit 10498ee

Please sign in to comment.