UNPKG

3.79 kBTypeScriptView Raw
1import {
2 PaginationData,
3 SearchParams,
4 SolrCore,
5 SolrMoreLikeThis,
6 SolrGet,
7 SolrQuery,
8 SolrTransitions
9} from './DataStore';
10import * as React from 'react';
11import { PropTypes } from 'react';
12import * as _ from 'lodash';
13
14type RenderLambda<T> =
15 (v: T | T[], p?: PaginationData) => JSX.Element;
16
17function databind<T>(
18 event: Function,
19 ds: SolrCore<object>,
20 render: RenderLambda<T>,
21 transition?: (sp: SearchParams) => Boolean
22) {
23 return () => {
24 return (
25 <Bound
26 event={event}
27 dataStore={ds}
28 render={render}
29 transition={transition}
30 />
31 );
32 };
33}
34
35interface DataBoundProps<T> {
36 autoload?: SearchParams;
37 event: Function;
38 dataStore: SolrGet<T> & SolrMoreLikeThis<T> & SolrQuery<T> & SolrTransitions;
39 render: RenderLambda<T>;
40 transition?: (params: SearchParams) => Boolean;
41}
42
43interface DataBoundState<T> {
44 data?: T | T[];
45 paging?: PaginationData;
46}
47
48class Bound extends React.Component<DataBoundProps<object>, DataBoundState<object>> {
49 static childContextTypes = {
50 transition: PropTypes.func,
51 searchState: PropTypes.object
52 };
53
54 static contextTypes = {
55 router: PropTypes.object
56 };
57
58 constructor(props: DataBoundProps<object>) {
59 super(props);
60
61 this.state = {
62 data: undefined,
63 paging: undefined
64 };
65
66 // This needs to happen early
67 // If this isn't bound to a specific event (e.g. a facet) just notify
68 // the control when there are new search results.
69 (props.event || props.dataStore.onQuery).call(
70 props.dataStore,
71 (data: object | object[], paging: PaginationData) => {
72 this.setState( {
73 data: data,
74 paging: paging
75 });
76 }
77 );
78 }
79
80 transition(args: SearchParams) {
81 if (this.props.transition) {
82 if (this.props.transition(args)) {
83 return;
84 }
85 }
86
87 const currentParams = this.props.dataStore.getCurrentParameters();
88 const newParams: SearchParams = _.extend(
89 {},
90 currentParams,
91 args,
92 {
93 type: 'QUERY'
94 }
95 );
96
97 if (args.facets) {
98 newParams.facets = _.extend(
99 {},
100 currentParams.facets,
101 args.facets);
102 }
103
104 // TODO - should handle different classes of route
105 /*const page: number = (
106 newParams.start || 0
107 ) / this.props.dataStore.getCoreConfig().pageSize + 1;*/
108
109 /*let facets = '';
110 if (newParams.facets) {
111 facets = '?' + _.map(
112 newParams.facets,
113 (k, v) => v + '=' + (
114 _.isArray(k) ? k.join(',') : k
115 )
116 ).join('&');
117 }*/
118
119 /*this.context.router.history.push(
120 '/' + this.props.dataStore.getCoreConfig().prefix + '/' + newParams.query + '/' +
121 page + facets
122 );*/
123
124 this.props.dataStore.stateTransition(
125 newParams
126 );
127 }
128
129 componentDidMount() {
130 if (this.props.autoload) {
131 this.transition(this.props.autoload);
132 }
133 }
134
135 getChildContext() {
136 return {
137 searchState: this.props.dataStore.getCurrentParameters(),
138 transition: this.transition.bind(this)
139 };
140 }
141
142 render() {
143 // TODO these need to be named or something
144 return (
145 this.props.render(
146 this.state.data || [],
147 this.state.paging || {
148 numFound: 0,
149 start: 0,
150 pageSize: 10
151 })
152 );
153 }
154}
155
156class DataBind extends React.Component<{}, {}> {
157 render() {
158 return (
159 <div>
160 {this.props.children}
161 </div>
162 );
163 }
164}
165
166export {
167 RenderLambda,
168 DataBoundProps,
169 DataBoundState,
170 DataBind,
171 Bound,
172 databind
173};
\No newline at end of file