import { PaginationData, SearchParams, SolrCore, SolrMoreLikeThis, SolrGet, SolrQuery, SolrTransitions } from './DataStore'; import * as React from 'react'; import { PropTypes } from 'react'; import * as _ from 'lodash'; type RenderLambda = (v: T | T[], p?: PaginationData) => JSX.Element; function databind( event: Function, ds: SolrCore, render: RenderLambda, transition?: (sp: SearchParams) => Boolean ) { return () => { return ( ); }; } interface DataBoundProps { autoload?: SearchParams; event: Function; dataStore: SolrGet & SolrMoreLikeThis & SolrQuery & SolrTransitions; render: RenderLambda; transition?: (params: SearchParams) => Boolean; } interface DataBoundState { data?: T | T[]; paging?: PaginationData; } class Bound extends React.Component, DataBoundState> { static childContextTypes = { transition: PropTypes.func, searchState: PropTypes.object }; static contextTypes = { router: PropTypes.object }; constructor(props: DataBoundProps) { super(props); this.state = { data: undefined, paging: undefined }; // This needs to happen early // If this isn't bound to a specific event (e.g. a facet) just notify // the control when there are new search results. (props.event || props.dataStore.onQuery).call( props.dataStore, (data: object | object[], paging: PaginationData) => { this.setState( { data: data, paging: paging }); } ); } transition(args: SearchParams) { if (this.props.transition) { if (this.props.transition(args)) { return; } } const currentParams = this.props.dataStore.getCurrentParameters(); const newParams: SearchParams = _.extend( {}, currentParams, args, { type: 'QUERY' } ); if (args.facets) { newParams.facets = _.extend( {}, currentParams.facets, args.facets); } // TODO - should handle different classes of route /*const page: number = ( newParams.start || 0 ) / this.props.dataStore.getCoreConfig().pageSize + 1;*/ /*let facets = ''; if (newParams.facets) { facets = '?' + _.map( newParams.facets, (k, v) => v + '=' + ( _.isArray(k) ? k.join(',') : k ) ).join('&'); }*/ /*this.context.router.history.push( '/' + this.props.dataStore.getCoreConfig().prefix + '/' + newParams.query + '/' + page + facets );*/ this.props.dataStore.stateTransition( newParams ); } componentDidMount() { if (this.props.autoload) { this.transition(this.props.autoload); } } getChildContext() { return { searchState: this.props.dataStore.getCurrentParameters(), transition: this.transition.bind(this) }; } render() { // TODO these need to be named or something return ( this.props.render( this.state.data || [], this.state.paging || { numFound: 0, start: 0, pageSize: 10 }) ); } } class DataBind extends React.Component<{}, {}> { render() { return (
{this.props.children}
); } } export { RenderLambda, DataBoundProps, DataBoundState, DataBind, Bound, databind };