source: SRUAggregator/trunk/src/main/resources/assets/js/corpora.js @ 5931

Last change on this file since 5931 was 5931, checked in by emanuel.dima@uni-tuebingen.de, 9 years ago
  1. alpha12: better language filtering using detection, collections view improvements
File size: 8.0 KB
Line 
1/** @jsx React.DOM */
2(function() {
3"use strict";
4
5window.MyAggregator = window.MyAggregator || {};
6
7var PT = React.PropTypes;
8var ReactCSSTransitionGroup = window.React.addons.CSSTransitionGroup;
9// own components
10var Panel = window.MyReact.Panel;
11
12
13/////////////////////////////////
14
15var SearchCorpusBox = React.createClass({displayName: 'SearchCorpusBox',
16        propTypes: {
17                search: PT.func.isRequired,
18        },
19
20        getInitialState: function () {
21                return {
22                        query: ""
23                };
24        },
25
26        handleChange: function(event) {
27                this.setState({query: event.target.value});
28                this.props.search(event.target.value);
29                event.stopPropagation();
30        },
31
32        handleKey: function(event) {
33                if (event.keyCode==13) {
34                        this.props.search(event.target.value);
35                }
36        },
37
38        render: function() {
39                return  React.createElement("div", {className: "form-group"}, 
40                                        React.createElement("input", {className: "form-control search search-collection", type: "text", 
41                                                value: this.state.query, placeholder: "Search for collection", 
42                                                onChange: this.handleChange})
43                                );
44        }
45});
46
47var CorpusView = window.MyAggregator.CorpusView = React.createClass({displayName: 'CorpusView',
48        propTypes: {
49                corpora: PT.object.isRequired,
50                languageMap: PT.object.isRequired,
51        },
52
53        toggleSelection: function (corpus) {
54                var s = !corpus.selected;
55                this.props.corpora.recurseCorpus(corpus, function(c) { c.selected = s; });
56                this.props.corpora.update();
57        },
58
59        toggleExpansion: function (corpus) {
60                corpus.expanded = !corpus.expanded;
61                this.props.corpora.update();
62        },
63
64        selectAll: function(value) {
65                this.props.corpora.recurse(function(c) { c.selected = value; });
66                this.props.corpora.update();
67        },
68
69        searchCorpus: function(query) {
70                // sort fn: descending priority, stable sort
71                var sortFn = function(a, b){
72                        if (b.priority === a.priority) {
73                                return b.index - a.index; // stable sort
74                        }
75                        return b.priority - a.priority;
76                };
77
78                this.props.corpora.recurse(function(corpus) { corpus.subCorpora.sort(sortFn); });
79                this.props.corpora.corpora.sort(sortFn);
80
81                query = query.toLowerCase();
82                var querytokens = query.split(" ");
83                if (!query) {
84                        this.props.corpora.recurse(function(corpus) {corpus.priority = 1; });
85                        this.props.corpora.update();
86                        return;
87                }
88
89                // clean up all priorities
90                this.props.corpora.recurse(function(corpus) {
91                        corpus.priority = 0;
92                });
93
94                // find priority for each corpus
95                this.props.corpora.recurse(function(corpus){
96                        var title = corpus.title ? corpus.title : corpus.displayName;
97                        querytokens.forEach(function(qtoken){
98                                if (title && title.toLowerCase().indexOf(qtoken) >= 0) {
99                                        corpus.priority ++;
100                                }
101                                if (corpus.description && corpus.description.toLowerCase().indexOf(qtoken) >= 0) {
102                                        corpus.priority ++;
103                                }
104                                if (corpus.institution && corpus.institution.name && 
105                                                corpus.institution.name.toLowerCase().indexOf(qtoken) >= 0) {
106                                        corpus.priority ++;
107                                }
108                                if (corpus.languages){
109                                        corpus.languages.forEach(function(lang){
110                                                if (lang.toLowerCase().indexOf(qtoken) >= 0){
111                                                        corpus.priority ++;
112                                                }
113                                        });
114                                        corpus.languages.forEach(function(lang){
115                                                if (this.props.languageMap[lang].toLowerCase().indexOf(qtoken) >= 0){
116                                                        corpus.priority ++;
117                                                }
118                                        }.bind(this));
119                                }
120                        }.bind(this));
121                }.bind(this));
122
123                // ensure root corpora have nonnull priority
124                this.props.corpora.recurse(function(corpus){
125                        if (corpus.subCorpora) {
126                                corpus.subCorpora.forEach(function(subcorpus){
127                                        if (subcorpus.priority > 0 && corpus.priority === 0)
128                                                corpus.priority ++;
129                                });
130                        }
131                });
132
133                this.props.corpora.recurse(function(corpus) { corpus.subCorpora.sort(sortFn); });
134                this.props.corpora.corpora.sort(sortFn);
135
136                // display
137                this.props.corpora.update();
138                // console.log("corpus search done", query);
139        },
140
141        getMinMaxPriority: function() {
142                var min = 1, max = 0;
143                this.props.corpora.recurse(function(c) { 
144                        if (c.priority < min) min = c.priority;
145                        if (max < c.priority) max = c.priority;
146                });
147                return [min, max];
148        },
149
150        renderCheckbox: function(corpus) {
151                return  React.createElement("button", {className: "btn btn-default"}, 
152                                         corpus.selected ?
153                                                React.createElement("span", {className: "glyphicon glyphicon-check", 'aria-hidden': "true"}) :
154                                                React.createElement("span", {className: "glyphicon glyphicon-unchecked", 'aria-hidden': "true"})
155                                       
156                                );
157        },
158
159        renderExpansion: function(corpus) {
160                if (!corpus.subCorpora || corpus.subCorpora.length === 0) {
161                        return false;
162                }
163                return  React.createElement("div", {className: "expansion-handle", style: {}}, 
164                                        React.createElement("a", null, 
165                                                corpus.expanded ?
166                                                        React.createElement("span", {className: "glyphicon glyphicon-minus", 'aria-hidden': "true"}):
167                                                        React.createElement("span", {className: "glyphicon glyphicon-plus", 'aria-hidden': "true"}), 
168                                               
169                                                corpus.expanded ? " Collapse ":" Expand ", " ", corpus.subCorpora.length, " subcollections"
170                                        )
171                                );
172        },
173
174        renderLanguages: function(languages) {
175                return languages
176                                .map(function(l) { return this.props.languageMap[l]; }.bind(this))
177                                .sort()
178                                .join(", ");
179        },
180
181        renderCorpus: function(level, minmaxp, corpus) {
182                if (!corpus.visible) {
183                        return false;
184                }
185
186                var indent = {marginLeft:level*50};
187                var corpusContainerClass = "corpus-container "+(corpus.priority>0?"":"dimmed");
188
189                var hue = 80 * corpus.priority / minmaxp[1];
190                if (corpus.priority > 0) { hue += 40; }
191                var color = minmaxp[0] === minmaxp[1] ? 'transparent' : 'hsl('+hue+', 50%, 50%)';
192                var priorityStyle = {paddingBottom: 4, paddingLeft: 2, borderBottom: '2px solid '+color };
193                var expansive = corpus.expanded ? {} 
194                        : {whiteSpace:'nowrap', overflow:'hidden', textOverflow: 'ellipsis'};
195                var title = corpus.title || corpus.displayName;
196                return  React.createElement("div", {className: corpusContainerClass, key: corpus.displayName}, 
197                                        React.createElement("div", {className: "row corpus", onClick: this.toggleExpansion.bind(this, corpus)}, 
198                                                React.createElement("div", {className: "col-sm-1 vcenter"}, 
199                                                                React.createElement("div", {className: "inline", style: priorityStyle, onClick: this.toggleSelection.bind(this,corpus)}, 
200                                                                        this.renderCheckbox(corpus)
201                                                                )
202                                                ), 
203                                                React.createElement("div", {className: "col-sm-8 vcenter"}, 
204                                                        React.createElement("div", {style: indent}, 
205                                                                React.createElement("h3", {style: expansive}, 
206                                                                         corpus.landingPage ? React.createElement("a", {href: corpus.landingPage}, title): title
207                                                                ), 
208
209                                                                React.createElement("p", {style: expansive}, corpus.description)
210                                                        ), 
211                                                        this.renderExpansion(corpus)
212                                                ), 
213                                                React.createElement("div", {className: "col-sm-3 vcenter"}, 
214                                                        React.createElement("p", {style: expansive}, 
215                                                                React.createElement("i", {className: "fa fa-institution"}), " ", corpus.institution.name
216                                                        ), 
217                                                        React.createElement("p", {style: expansive}, 
218                                                                React.createElement("i", {className: "fa fa-language"}), " ", this.renderLanguages(corpus.languages)
219                                                        )
220                                                )
221                                        ), 
222                                        corpus.expanded ? corpus.subCorpora.map(this.renderCorpus.bind(this, level+1, minmaxp)) : false
223                                );
224        },
225
226        render: function() {
227                var minmaxp = this.getMinMaxPriority();
228                return  React.createElement("div", {style: {margin: "0 30px"}}, 
229                                        React.createElement("div", {className: "row"}, 
230                                                React.createElement("div", {className: "float-left inline"}, 
231                                                        React.createElement("h3", {style: {marginTop:10}}, 
232                                                                this.props.corpora.getSelectedMessage()
233                                                        )
234                                                ), 
235                                                React.createElement("div", {className: "float-right inline"}, 
236                                                        React.createElement("div", {className: "inline", style: { marginRight: 20}}, 
237                                                                React.createElement(SearchCorpusBox, {search: this.searchCorpus})
238                                                        ), 
239                                                        React.createElement("button", {className: "btn btn-default", style: { marginRight: 10}, onClick: this.selectAll.bind(this,true)}, 
240                                                                " Select all"), 
241                                                        React.createElement("button", {className: "btn btn-default", style: { marginRight: 20}, onClick: this.selectAll.bind(this,false)}, 
242                                                                " Deselect all")
243                                                )
244                                        ), 
245                                        this.props.corpora.corpora.map(this.renderCorpus.bind(this, 0, minmaxp))
246                                );
247        }
248});
249
250})();
Note: See TracBrowser for help on using the repository browser.