Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
GregoryPotdevin committed Mar 3, 2016
2 parents a6fef63 + c7c1c85 commit 6b31d78
Show file tree
Hide file tree
Showing 17 changed files with 315 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/components/index.ts
Expand Up @@ -14,5 +14,6 @@ export * from "./search/sorting-selector/src/SortingSelector";
export * from "./search/filters/hierarchical-refinement-filter/src/HierarchicalRefinementFilter";
export * from "./search/filters/range-filter/src/RangeFilter";
export * from "./search/filters/filter-item/src/FilterItem";
export * from "./search/filters/facet-filter";
export * from "./display";
export * from "./ui";
38 changes: 38 additions & 0 deletions src/components/search/filters/facet-filter/CheckboxFilter.tsx
@@ -0,0 +1,38 @@
import * as React from "react";

import { FacetAccessor} from '../../../../core'
import { ItemList} from "../../../ui"
import { FacetFilter} from "./FacetFilter"

const defaults = require("lodash/defaults")
const map = require("lodash/map")
const concat = require("lodash/concat")
const assign = require("lodash/assign")

import {FacetFilterProps, FacetFilterPropTypes} from "./FacetFilterProps"

export interface CheckboxFilterProps extends FacetFilterProps{
value:string
}
export class CheckboxFilter extends FacetFilter<CheckboxFilterProps> {

static propTypes = defaults({
value:React.PropTypes.string.isRequired
},FacetFilterPropTypes.propTypes)

static defaultProps = defaults({
size:1,
showMore:false
}, FacetFilter.defaultProps)

getAccessorOptions(){
let options = super.getAccessorOptions()
return assign(options, {include:[this.props.value]})
}

getItems(){
let key = this.props.value
return [this.accessor.getBuckets()[0] || {key, doc_count:0}]
}

}
127 changes: 127 additions & 0 deletions src/components/search/filters/facet-filter/FacetFilter.tsx
@@ -0,0 +1,127 @@
import * as React from "react";

import {FacetFilterProps, FacetFilterPropTypes} from "./FacetFilterProps"

import {
FacetAccessor, SearchkitComponent, ISizeOption,
FastClick
} from "../../../../core"

import {
CheckboxItemList, Panel
} from "../../../ui"

const defaults = require("lodash/defaults")

export class FacetFilter<T extends FacetFilterProps> extends SearchkitComponent<T, any> {
accessor: FacetAccessor

static propTypes = FacetFilterPropTypes

static defaultProps = {
listComponent: CheckboxItemList,
containerComponent: Panel,
size: 50,
collapsable: false,
showCount: true,
showMore: true
}

constructor(props){
super(props)
this.toggleViewMoreOption = this.toggleViewMoreOption.bind(this)
}
getAccessorOptions(){
const {
field, id, operator, title, include, exclude,
size, translations, orderKey, orderDirection
} = this.props
return {
id, operator, title, size, include, exclude,
translations, orderKey, orderDirection
}
}
defineAccessor() {
return new FacetAccessor(
this.props.field, this.getAccessorOptions())
}

defineBEMBlocks() {
var blockName = this.props.mod || "sk-refinement-list"
return {
container: blockName,
option: `${blockName}-option`
}
}

componentDidUpdate(prevProps) {
if (prevProps.operator != this.props.operator) {
this.accessor.options.operator = this.props.operator
this.searchkit.performSearch()
}
}

toggleFilter(key) {
this.accessor.state = this.accessor.state.toggle(key)
this.searchkit.performSearch()
}

setFilters(keys) {
this.accessor.state = this.accessor.state.setValue(keys)
this.searchkit.performSearch()
}

toggleViewMoreOption(option: ISizeOption) {
this.accessor.setViewMoreOption(option);
this.searchkit.performSearch()
}

hasOptions(): boolean {
return this.accessor.getBuckets().length != 0
}

getSelectedItems(){
return this.accessor.state.getValue()
}

getItems(){
return this.accessor.getBuckets()
}

render() {
const { listComponent, containerComponent, showCount, title, id, collapsable } = this.props
return React.createElement(containerComponent, {
title,
className: id ? `filter--${id}` : undefined,
disabled: !this.hasOptions(),
collapsable
}, [
React.createElement(listComponent, {
key:"listComponent",
items: this.getItems(),
selectedItems: this.getSelectedItems(),
toggleItem: this.toggleFilter.bind(this),
setItems: this.setFilters.bind(this),
showCount,
translate:this.translate
}),
this.renderShowMore()
]);
}

renderShowMore() {
const option = this.accessor.getMoreSizeOption()

if (!option || !this.props.showMore) {
return null;
}

return (
<FastClick handler={() => this.toggleViewMoreOption(option) } key="showMore">
<div data-qa="show-more" className={this.bemBlocks.container("view-more-action") }>
{this.translate(option.label) }
</div>
</FastClick>
)
}
}
51 changes: 51 additions & 0 deletions src/components/search/filters/facet-filter/FacetFilterProps.ts
@@ -0,0 +1,51 @@
import * as React from "react";

import {
ReactComponentType, SearchkitComponentProps,
SearchkitComponent, FacetAccessor
} from "../../../../core"

import {
ItemProps, ListProps
} from "../../../"

const defaults = require("lodash/defaults")
export interface FacetFilterProps extends SearchkitComponentProps {
field: string
operator?: string
size?: number
title: string
id: string
containerComponent?: ReactComponentType<any>
itemComponent?: ReactComponentType<ItemProps>
listComponent?: ReactComponentType<ListProps>
orderKey?: string
orderDirection?: string
include?: Array<string> | string
exclude?: Array<string> | string
collapsable?: boolean
showCount?: boolean
showMore?:boolean
}

export const FacetFilterPropTypes = defaults({
field: React.PropTypes.string.isRequired,
operator: React.PropTypes.oneOf(["AND", "OR"]),
size: React.PropTypes.number,
title: React.PropTypes.string.isRequired,
id: React.PropTypes.string.isRequired,
translations: SearchkitComponent.translationsPropType(
FacetAccessor.translations
),
orderKey: React.PropTypes.string,
orderDirection: React.PropTypes.oneOf(["asc", "desc"]),
include: React.PropTypes.oneOfType([
React.PropTypes.string, React.PropTypes.array
]),
exclude: React.PropTypes.oneOfType([
React.PropTypes.string, React.PropTypes.array
]),
collapsable: React.PropTypes.bool,
showCount: React.PropTypes.bool,
showMore: React.PropTypes.bool
},SearchkitComponent.propTypes)
48 changes: 48 additions & 0 deletions src/components/search/filters/facet-filter/MenuFilter.tsx
@@ -0,0 +1,48 @@
import * as React from "react";

import { ItemList } from '../../../../'
import { FacetFilter} from "./FacetFilter"

const defaults = require("lodash/defaults")
const map = require("lodash/map")
const concat = require("lodash/concat")

import {FacetFilterProps, FacetFilterPropTypes} from "./FacetFilterProps"

export class MenuFilter2 extends FacetFilter<FacetFilterProps> {

static propTypes = defaults({
},FacetFilterPropTypes.propTypes)

static defaultProps = defaults({
listComponent: ItemList,
operator:"OR"
}, FacetFilter.defaultProps)

static AllItem = {
key:"All"
}

toggleFilter(option) {
if (option === MenuFilter2.AllItem.key || this.accessor.state.contains(option)){
this.accessor.state = this.accessor.state.clear()
} else {
this.accessor.state = this.accessor.state.setValue([option]);
}
this.searchkit.performSearch()
}

setFilters(options){
this.toggleFilter(options[0])
}

getSelectedItems() {
return [this.accessor.state.getValue()[0] || MenuFilter2.AllItem.key]
}

getItems(){
return concat(this.accessor.getBuckets(), MenuFilter2.AllItem)
}


}
@@ -0,0 +1,6 @@
import {FacetFilter} from "./FacetFilter"
import {FacetFilterProps, FacetFilterPropTypes} from "./FacetFilterProps"

export class RefinementListFilter2 extends FacetFilter<FacetFilterProps> {

}
3 changes: 3 additions & 0 deletions src/components/search/filters/facet-filter/index.ts
@@ -0,0 +1,3 @@
export * from "./CheckboxFilter"
export * from "./MenuFilter"
export * from "./RefinementListFilter"
2 changes: 1 addition & 1 deletion src/components/search/hits/test/NoHitsSpec.tsx
Expand Up @@ -142,7 +142,7 @@ describe("NoHits component", () => {
it("render error", () => {
this.createWrapper()
this.searchkit.query = this.searchkit.query.addFilter({}).setQueryString("matrix")
this.searchkit.setError("rubbish")
this.searchkit.setError("simulated error")
this.wrapper.update()
expect(this.wrapper.html()).toEqual(jsxToHTML(
<div data-qa="no-hits" className="sk-no-hits">
Expand Down
6 changes: 1 addition & 5 deletions src/components/ui/list/Select.tsx
Expand Up @@ -9,10 +9,6 @@ const filter = require("lodash/filter")
const transform = require("lodash/transform")
const find = require("lodash/find")

function filterSelectItems(items){
return filter(items, ({ hideInSelect = false }) => !hideInSelect)
}

export class Select extends React.Component<ListProps, any> {

static defaultProps: any = {
Expand Down Expand Up @@ -47,7 +43,7 @@ export class Select extends React.Component<ListProps, any> {
return (
<div className={bemBlocks.container().mix(className).state({ disabled }) }>
<select onChange={this.onChange} value={this.getSelectedValue() }>
{map(filterSelectItems(items), ({key, label, title, disabled, doc_count}, idx) => {
{map(items, ({key, label, title, disabled, doc_count}, idx) => {
var text = translate(label || title || key)
if (showCount && doc_count !== undefined) text += ` (${doc_count})`
return <option key={key} value={key} disabled={disabled}>{text}</option>
Expand Down
28 changes: 4 additions & 24 deletions src/components/ui/list/Select.unit.tsx
Expand Up @@ -2,35 +2,15 @@ import * as React from "react";
import {mount} from "enzyme";

import { Select } from "./Select"
import { MockList} from "./MockList"

import {fastClick, hasClass, jsxToHTML, printPrettyHtml} from "../../__test__/TestHelpers"

describe("Select", ()=> {

beforeEach(()=> {
this.items = [
{key:"a", label:"A", doc_count:10},
{key:"b", label:"B", doc_count:11},
{key:"c", title:"C", doc_count:12},
{key:"c2", title: "C - invisible", doc_count: 12, hideInSelect: true},
{key:"d", doc_count:15},
]

this.selectedItems = ["a"]
this.toggleItem = jasmine.createSpy("toggleItem")
this.setItems = jasmine.createSpy("setItems")

this.translate = (key)=> {
return key + " translated"
}

let props = {
items: this.items, selectedItems: this.selectedItems,
toggleItem: this.toggleItem, setItems: this.setItems,
translate: this.translate
}
this.wrapper = mount(
<Select {...props}/>
<MockList listComponent={Select}/>
)
})

Expand All @@ -40,7 +20,7 @@ describe("Select", ()=> {
<div className="sk-select">
<select defaultValue="a">
<option value="a">A translated (10)</option>
<option value="b">B translated (11)</option>
<option value="b" disabled={true}>B translated (11)</option>
<option value="c">C translated (12)</option>
<option value="d">d translated (15)</option>
</select>
Expand All @@ -49,7 +29,7 @@ describe("Select", ()=> {

const optionC = this.wrapper.find("select").children().at(2)
optionC.simulate("change")
expect(this.setItems).toHaveBeenCalledWith(["c"])
expect(this.wrapper.node.state.setItems).toHaveBeenCalledWith(["c"])

this.wrapper.setProps({disabled:true})
expect(this.wrapper.find(".sk-select").hasClass("is-disabled")).toBe(true)
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/range/MockRange.tsx
Expand Up @@ -22,7 +22,7 @@ export class MockRange extends React.Component<any, any> {
min: 0, max: 10,
minValue: 2, maxValue: 5,
onChange: jasmine.createSpy("onChange"),
onFinished: jasmine.createSpy("onFinished"),
onFinished: jasmine.createSpy("onFinished")
}
}

Expand Down
4 changes: 1 addition & 3 deletions test/e2e/server/apps/ui-app/MockRange.tsx
Expand Up @@ -3,8 +3,6 @@ const {
Panel
} = require("../../../../../src")

const _ = require("lodash")

export class MockRange extends React.Component<any, any>{

constructor(props) {
Expand Down Expand Up @@ -44,7 +42,7 @@ export class MockRange extends React.Component<any, any>{
return (
<Panel title={this.props.title}>
{React.createElement(this.props.rangeComponent, this.state) }
</Panel>
</Panel>
)
}

Expand Down

0 comments on commit 6b31d78

Please sign in to comment.