Change filter links to buttons

This commit is contained in:
Hannu Lyytikainen 2018-01-05 12:40:12 +02:00
parent 6188f3b826
commit 8f1f19a5d6
3 changed files with 45 additions and 25 deletions

View file

@ -1,9 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import { omit } from 'lodash';
import { SelectSingleCustomAttribute } from '../../components';
import routeConfiguration from '../../routeConfiguration';
import { createResourceLocatorString } from '../../util/routes';
import css from './SearchFilters.css';
const SearchFiltersComponent = props => {
@ -15,7 +19,7 @@ const SearchFiltersComponent = props => {
resultsCount,
searchInProgress,
onMapIconClick,
intl,
history,
} = props;
const loadingResults = <FormattedMessage id="SearchFilters.loadingResults" />;
@ -34,13 +38,26 @@ const SearchFiltersComponent = props => {
const classes = classNames(rootClassName || css.root, className);
const onSelectSingle = (customAttribute, option) => {
// name of the corresponding query parameter
const caParam = `ca_${customAttribute}`;
// query parameters after selecting the option
// if no option is passed, clear the selection for the filter
const queryParams = option
? { ...urlQueryParams, [caParam]: option }
: omit(urlQueryParams, caParam);
history.push(createResourceLocatorString('SearchPage', routeConfiguration(), {}, queryParams));
};
return (
<div className={classes}>
<div className={css.filters}>
<SelectSingleCustomAttribute
customAttribute="category"
urlQueryParams={urlQueryParams}
intl={intl}
onSelect={onSelectSingle}
/>
</div>
@ -64,7 +81,7 @@ const SearchFiltersComponent = props => {
);
};
const { object, string, bool, number, func } = PropTypes;
const { object, string, bool, number, func, shape } = PropTypes;
SearchFiltersComponent.defaultProps = {
rootClassName: null,
@ -82,10 +99,12 @@ SearchFiltersComponent.propTypes = {
searchingInProgress: bool,
onMapIconClick: func.isRequired,
// from injectIntl
intl: intlShape.isRequired,
// from withRouter
history: shape({
push: func.isRequired,
}).isRequired,
};
const SearchFilters = injectIntl(SearchFiltersComponent);
const SearchFilters = withRouter(SearchFiltersComponent);
export default SearchFilters;

View file

@ -2,11 +2,9 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import classNames from 'classnames';
import { omit } from 'lodash';
import config from '../../config';
import { stringify } from '../../util/urlHelpers';
import { Menu, MenuContent, MenuItem, MenuLabel, NamedLink } from '../../components';
import { Menu, MenuContent, MenuItem, MenuLabel } from '../../components';
import css from './SelectSingleCustomAttribute.css';
class SelectSingleCustomAttributeComponent extends Component {
@ -15,25 +13,27 @@ class SelectSingleCustomAttributeComponent extends Component {
this.state = { isOpen: false };
this.onToggleActive = this.onToggleActive.bind(this);
this.selectOption = this.selectOption.bind(this);
}
onToggleActive(isOpen) {
this.setState({ isOpen: isOpen });
}
selectOption(customAttribute, option) {
this.setState({ isOpen: false });
this.props.onSelect(customAttribute, option);
}
render() {
const { rootClassName, className, customAttribute, urlQueryParams, intl } = this.props;
// custom attribute content
const ca = customAttribute && config.customAttributes[customAttribute];
// name of the corresponding query parameter
const caParam = `ca_${customAttribute}`;
// current value of this custom attribute filter
const currentValue = urlQueryParams[caParam];
// query params where this custom attribute is cleared
const clearUrlQueryParams = omit(urlQueryParams, caParam);
// query string for clearing this custom attribute
const clearQueryString = stringify(clearUrlQueryParams);
// resolve menu label text and class
const menuLabel = currentValue
@ -56,28 +56,28 @@ class SelectSingleCustomAttributeComponent extends Component {
{ca.values.map(v => {
// check if this option is selected
const selected = currentValue === v;
// search query string with this option added
const queryString = stringify({ ...urlQueryParams, [caParam]: v });
// menu item border class
const menuItemBorderClass = selected ? css.menuItemBorderSelected : css.menuItemBorder;
return (
<MenuItem key={v}>
<NamedLink className={css.menuItem} name="SearchPage" to={{ search: queryString }}>
<button
className={css.menuItem}
onClick={() => this.selectOption(customAttribute, v)}
>
<span className={menuItemBorderClass} />
<FormattedMessage id={`SelectSingleCustomAttribute.category.option.${v}`} />
</NamedLink>
</button>
</MenuItem>
);
})}
<MenuItem key={'clearLink'}>
<NamedLink
<button
className={css.clearMenuItem}
name="SearchPage"
to={{ search: clearQueryString }}
onClick={() => this.selectOption(customAttribute, null)}
>
<FormattedMessage id={'SelectSingleCustomAttribute.clear'} />
</NamedLink>
</button>
</MenuItem>
</MenuContent>
</Menu>
@ -85,7 +85,7 @@ class SelectSingleCustomAttributeComponent extends Component {
}
}
const { object, string } = PropTypes;
const { object, string, func } = PropTypes;
SelectSingleCustomAttributeComponent.defaultProps = {
rootClassName: null,
@ -97,6 +97,7 @@ SelectSingleCustomAttributeComponent.propTypes = {
className: string,
customAttribute: string.isRequired,
urlQueryParams: object.isRequired,
onSelect: func.isRequired,
// from injectIntl
intl: intlShape.isRequired,

View file

@ -20,7 +20,7 @@ exports[`SearchPageComponent matches snapshot 1`] = `
<withRouter(Connect(TopbarContainerComponent)) />
<div>
<div>
<InjectIntl(SearchFiltersComponent)
<withRouter(SearchFiltersComponent)
listingsAreLoaded={true}
onMapIconClick={[Function]}
resultsCount={22}