Changeset 5954 for SRUAggregator
- Timestamp:
- 01/26/15 15:12:46 (9 years ago)
- Location:
- SRUAggregator/trunk
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
SRUAggregator/trunk/aggregator_development.yml
r5919 r5954 4 4 5 5 AGGREGATOR_FILE_PATH: /Users/edima/fcsAggregatorCorpora.json 6 SCAN_MAX_DEPTH: 37 SCAN_TASK_INITIAL_DELAY: 128 SCAN_TASK_INTERVAL: 246 SCAN_MAX_DEPTH: 2 7 SCAN_TASK_INITIAL_DELAY: 6 8 SCAN_TASK_INTERVAL: 12 9 9 SCAN_TASK_TIME_UNIT: HOURS 10 10 … … 13 13 14 14 15 ENDPOINTS_SCAN_TIMEOUT_MS: 1000015 ENDPOINTS_SCAN_TIMEOUT_MS: 60000 16 16 ENDPOINTS_SEARCH_TIMEOUT_MS: 10000 17 17 EXECUTOR_SHUTDOWN_TIMEOUT_MS: 100 -
SRUAggregator/trunk/pom.xml
r5931 r5954 8 8 <groupId>eu.clarin.sru.fcs</groupId> 9 9 <artifactId>Aggregator2</artifactId> 10 <version>2.0.0-alpha-1 2</version>10 <version>2.0.0-alpha-14</version> 11 11 <name>FCS Aggregator</name> 12 12 -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/Aggregator.java
r5931 r5954 86 86 * @author edima 87 87 * 88 * TODO: fix ordering of corpora in corpora view 89 * 90 * TODO: corpora search should not indicate the ones that don't match 88 * TODO: support new spec-compatible centres, see Oliver's mail 89 * (use SRUClient's extraResponseData POJOs) 90 * 91 * TODO: version page: credits, open source, see vcr/version page 92 * 93 * TODO: statistics page linked from version page 94 * 95 * TODO: add diagnostics messages to statistics page 96 * 97 * TODO: disable popups easily 98 * 99 * TODO: Fix activeSearch memory leak (gc searches older than...) 100 * 101 * TODO: Use weblicht with results 102 * 103 * TODO: Export to personal workspace as csv, excel, tcf, plain text 104 * 105 * TODO: Download to personal workspace as csv, excel, tcf, plain text 106 * 107 * TODO: websockets 108 * 109 * TODO: atomic replace of cached corpora (file) 110 * 111 * TODO: show multiple hits on the same result in multiple rows, linked visually 112 * 113 * TODO: zoom into the results from a corpus, allow functionality only for 114 * the view (search for next set of results) 115 * 116 * TODO: optimise page load 117 * 118 * TODO: test it in IE, other browsers 91 119 * 92 120 * TODO: tri-state for parent collections; search + message implications 93 *94 * TODO: version page: credits, open source, see vcr/version page95 *96 * TODO: statistics page liked from version page97 *98 * TODO: 1. support new spec-compatible centres, see Oliver's mail99 * (use SRUClient's extraResponseData POJOs)100 *101 * TODO: 2. zoom into the results from a corpus, allow functionality only for102 * the view (search for next set of results)103 *104 * TODO: disable popups easily105 *106 * TODO: Fix activeSearch memory leak (gc searches older than...)107 *108 * TODO: Use weblicht with results109 *110 * TODO: Export to personal workspace as csv, excel, tcf, plain text111 *112 * TODO: Download to personal workspace as csv, excel, tcf, plain text113 *114 * TODO: websockets115 *116 * TODO: atomic replace of cached corpora (file)117 *118 * TODO: show multiple hits on the same result in multiple rows, linked visually119 *120 * TODO: optimise page load121 121 * 122 122 * TODO: improve help page text -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/rest/RestService.java
r5931 r5954 107 107 } 108 108 109 @GET110 @Path("diagnostics")111 public Response getDiagnostics() throws IOException {112 Map<String, Diagnostic> diagnostics = Aggregator.getInstance().getCorpora().getEndpointDiagnostics();113 return Response.ok(toJson(diagnostics)).build();114 }115 116 109 @POST 117 110 @Path("search") -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/Corpora.java
r5900 r5954 4 4 import java.util.ArrayList; 5 5 import java.util.Collections; 6 import java.util.HashMap;7 6 import java.util.HashSet; 8 7 import java.util.List; 9 import java.util.Map;10 8 import java.util.Set; 11 9 import org.slf4j.LoggerFactory; … … 23 21 24 22 @JsonProperty 25 private Map<String, Diagnostic> endpointDiagnostics = Collections.synchronizedMap(new HashMap<String, Diagnostic>());26 @JsonProperty27 23 private List<Institution> institutions = Collections.synchronizedList(new ArrayList<Institution>()); 28 24 @JsonProperty … … 35 31 public List<Corpus> getCorpora() { 36 32 return Collections.unmodifiableList(corpora); 37 }38 39 public Map<String, Diagnostic> getEndpointDiagnostics() {40 return Collections.unmodifiableMap(endpointDiagnostics);41 33 } 42 34 … … 55 47 } 56 48 return true; 57 }58 59 public void addEndpointDiagnostic(String endpoint, Diagnostic diagnostic) {60 endpointDiagnostics.put(endpoint, diagnostic);61 49 } 62 50 -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/Diagnostic.java
r5900 r5954 6 6 public class Diagnostic { 7 7 8 private String uri; 9 private String context; 10 private String message; 11 private String diagnostic; 8 private String reqEndpointUrl, reqContext; 9 private String dgnUri, dgnMessage, dgnDiagnostic; 12 10 13 public Diagnostic(String uri, String context, String message, String diagnostic) { 14 this.uri = uri; 15 this.context = context; 16 this.message = message; 17 this.diagnostic = diagnostic; 11 public Diagnostic(String reqEndpointUrl, String reqContext, String dgnUri, String dgnMessage, String dgnDiagnostic) { 12 this.reqEndpointUrl = reqEndpointUrl; 13 this.reqContext = reqContext; 14 this.dgnUri = dgnUri; 15 this.dgnMessage = dgnMessage; 16 this.dgnDiagnostic = dgnDiagnostic; 18 17 } 19 18 … … 21 20 } 22 21 23 public String get Uri() {24 return uri;22 public String getDgnDiagnostic() { 23 return dgnDiagnostic; 25 24 } 26 25 27 public String get Context() {28 return context;26 public String getDgnMessage() { 27 return dgnMessage; 29 28 } 30 29 31 public String get Message() {32 return message;30 public String getDgnUri() { 31 return dgnUri; 33 32 } 34 33 35 public String get Diagnostic() {36 return diagnostic;34 public String getReqContext() { 35 return reqContext; 37 36 } 38 37 39 public void setUri(String uri) {40 this.uri = uri;38 public String getReqEndpointUrl() { 39 return reqEndpointUrl; 41 40 } 42 41 43 public void set Message(String message) {44 this. message = message;42 public void setDgnDiagnostic(String dgnDiagnostic) { 43 this.dgnDiagnostic = dgnDiagnostic; 45 44 } 46 45 47 public void set Context(String context) {48 this. context = context;46 public void setDgnMessage(String dgnMessage) { 47 this.dgnMessage = dgnMessage; 49 48 } 50 49 51 public void setDiagnostic(String diagnostic) { 52 this.diagnostic = diagnostic; 50 public void setDgnUri(String dgnUri) { 51 this.dgnUri = dgnUri; 52 } 53 54 public void setReqContext(String reqContext) { 55 this.reqContext = reqContext; 56 } 57 58 public void setReqEndpointUrl(String reqEndpointUrl) { 59 this.reqEndpointUrl = reqEndpointUrl; 53 60 } 54 61 … … 56 63 public int hashCode() { 57 64 https://primes.utm.edu/lists/small/1000.txt 58 return uri.hashCode() * 967 + context.hashCode() * 797 59 + message.hashCode() * 1669 + diagnostic.hashCode(); 65 return reqEndpointUrl.hashCode() * 967 + reqContext.hashCode() * 797 66 + dgnUri.hashCode() * 1669 + dgnMessage.hashCode() * 31 67 + dgnDiagnostic.hashCode(); 60 68 } 61 69 … … 66 74 } 67 75 Diagnostic d = (Diagnostic) obj; 68 return uri.equals(d.uri) && message.equals(d.message) 69 && context.equals(d.context) && diagnostic.equals(d.diagnostic); 76 return reqEndpointUrl.equals(d.reqEndpointUrl) 77 && reqContext.equals(d.reqContext) 78 && dgnUri.equals(d.dgnUri) 79 && dgnMessage.equals(d.dgnMessage) 80 && dgnDiagnostic.equals(d.dgnDiagnostic); 70 81 } 71 82 } -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/ScanCrawler.java
r5901 r5954 7 7 import eu.clarin.sru.client.SRUScanResponse; 8 8 import eu.clarin.sru.client.SRUTerm; 9 import eu.clarin.sru.client.SRUVersion;10 import eu.clarin.sru.fcs.aggregator.app.Aggregator;11 9 import eu.clarin.sru.fcs.aggregator.client.ThrottledClient; 12 10 import eu.clarin.sru.fcs.aggregator.util.SRUCQL; … … 137 135 if (response != null && response.hasDiagnostics()) { 138 136 for (SRUDiagnostic d : response.getDiagnostics()) { 139 String context = SRUCQL.SCAN_RESOURCE_PARAMETER + "=" + normalizeHandle(parentCorpus); 140 Diagnostic diag = new Diagnostic(d.getURI(), context, d.getMessage(), d.getDetails()); 141 corpora.addEndpointDiagnostic(endpointUrl, diag); 142 log.info("Diagnostic: {}: {}: {}", d.getURI(), context, d.getMessage(), d.getDetails()); 137 SRUScanRequest request = response.getRequest(); 138 139 String handle = SRUCQL.SCAN_RESOURCE_PARAMETER + "=" + normalizeHandle(parentCorpus); 140 Diagnostic diag = new Diagnostic(request.getBaseURI().toString(), handle, 141 d.getURI(), d.getMessage(), d.getDetails()); 142 statistics.addEndpointDiagnostic(institution, endpointUrl, diag); 143 log.info("Diagnostic: {} {}: {} {} {}", diag.getReqEndpointUrl(), diag.getReqContext(), 144 diag.getDgnUri(), diag.getDgnMessage(), diag.getDgnDiagnostic()); 143 145 } 144 146 } -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/Statistics.java
r5894 r5954 19 19 List<Long> executionTimes = Collections.synchronizedList(new ArrayList<Long>()); 20 20 21 @JsonProperty 22 List<Diagnostic> diagnostics = Collections.synchronizedList(new ArrayList<Diagnostic>()); 21 23 @JsonProperty 22 24 Map<String, Integer> errors = Collections.synchronizedMap(new HashMap<String, Integer>()); … … 78 80 } 79 81 82 public void addEndpointDiagnostic(Institution institution, String endpoint, Diagnostic diag) { 83 EndpointStats stats = getEndpointStats(institution, endpoint); 84 stats.diagnostics.add(diag); 85 } 86 80 87 public void addErrorDatapoint(Institution institution, String endpoint, SRUClientException error) { 81 88 EndpointStats stats = getEndpointStats(institution, endpoint); -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/search/Result.java
r5931 r5954 2 2 3 3 import eu.clarin.sru.client.SRUClientException; 4 import eu.clarin.sru.client.SRUDiagnostic; 4 5 import eu.clarin.sru.client.SRURecord; 6 import eu.clarin.sru.client.SRUSearchRetrieveRequest; 5 7 import eu.clarin.sru.fcs.aggregator.scan.Corpus; 6 8 import eu.clarin.sru.client.SRUSearchRetrieveResponse; … … 12 14 import eu.clarin.sru.client.fcs.DataViewHits; 13 15 import eu.clarin.sru.client.fcs.Resource; 16 import eu.clarin.sru.fcs.aggregator.scan.Diagnostic; 14 17 import java.util.ArrayList; 18 import java.util.Collections; 15 19 import java.util.List; 16 20 import org.w3c.dom.Node; … … 32 36 private List<Kwic> kwics = new ArrayList<Kwic>(); 33 37 private SRUClientException exception; 38 private List<Diagnostic> diagnostics = new ArrayList<Diagnostic>(); 34 39 35 40 public List<Kwic> getKwics() { … … 44 49 setResponse(response); 45 50 } 51 if (response != null && response.hasDiagnostics()) { 52 setDiagnostics(response); 53 } 46 54 } 47 55 48 publicvoid setResponse(SRUSearchRetrieveResponse response) {56 void setResponse(SRUSearchRetrieveResponse response) { 49 57 for (SRURecord record : response.getRecords()) { 50 58 if (record.isRecordSchema(ClarinFCSRecordData.RECORD_SCHEMA)) { … … 61 69 log.info("Unsupported schema: {0}", record.getRecordSchema()); 62 70 } 71 } 72 } 73 74 void setDiagnostics(SRUSearchRetrieveResponse response) { 75 for (SRUDiagnostic d : response.getDiagnostics()) { 76 SRUSearchRetrieveRequest srurequest = response.getRequest(); 77 diagnostics.add(new Diagnostic(srurequest.getBaseURI().toString(), 78 srurequest.getQuery(), 79 d.getURI(), d.getMessage(), d.getDetails())); 63 80 } 64 81 } … … 111 128 } 112 129 130 public List<Diagnostic> getDiagnostics() { 131 return Collections.unmodifiableList(diagnostics); 132 } 133 113 134 public int getStartRecord() { 114 135 return request.getStartRecord(); … … 126 147 return request.getSearchString(); 127 148 } 128 129 149 } -
SRUAggregator/trunk/src/main/resources/assets/index.html
r5931 r5954 46 46 <a title="about" id="aboutlink" href="about"> 47 47 <span class="glyphicon glyphicon-info-sign"></span> 48 <span>VERSION 2.0.0.α1 2</span>48 <span>VERSION 2.0.0.α14</span> 49 49 </a> 50 50 </div> … … 70 70 <script src="lib/jquery.min.js"></script> 71 71 <script src="lib/react-with-addons.js"></script> 72 <script src="lib/react-router.min.js"></script> 72 73 <script src="lib/bootstrap.min.js"></script> 73 74 <script src="js/components.js"></script> -
SRUAggregator/trunk/src/main/resources/assets/js/corpora.js
r5931 r5954 25 25 26 26 handleChange: function(event) { 27 this.setState({query: event.target.value}); 28 this.props.search(event.target.value); 27 var query = event.target.value; 28 this.setState({query: query}); 29 30 if (query.length === 0 || 2 <= query.length) { 31 this.props.search(query); 32 } 29 33 event.stopPropagation(); 30 34 }, … … 51 55 }, 52 56 53 toggleSelection: function (corpus ) {57 toggleSelection: function (corpus, e) { 54 58 var s = !corpus.selected; 55 59 this.props.corpora.recurseCorpus(corpus, function(c) { c.selected = s; }); 56 60 this.props.corpora.update(); 61 this.stop(e); 57 62 }, 58 63 … … 76 81 }; 77 82 78 this.props.corpora.recurse(function(corpus) { corpus.subCorpora.sort(sortFn); });79 this.props.corpora.corpora.sort(sortFn);80 81 83 query = query.toLowerCase(); 82 var querytokens = query.split(" ");83 84 if (!query) { 84 85 this.props.corpora.recurse(function(corpus) {corpus.priority = 1; }); … … 93 94 94 95 // find priority for each corpus 96 var querytokens = query.split(" ").filter(function(x){ return x.length > 0; }); 95 97 this.props.corpora.recurse(function(corpus){ 96 98 var title = corpus.title ? corpus.title : corpus.displayName; … … 121 123 }.bind(this)); 122 124 123 // ensure root corpora have nonnull priority124 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 } );125 // ensure parents of visible corpora are also visible; maximum depth = 3 126 var isVisibleFn = function(corpus){ return corpus.priority > 0; }; 127 var parentBooster = function(corpus){ 128 if (corpus.priority <= 0 && corpus.subCorpora) { 129 if (corpus.subCorpora.some(isVisibleFn)) { 130 corpus.priority = 0.5; 131 } 130 132 } 131 }); 133 }; 134 for (var i = 3; i > 0; i --) { 135 this.props.corpora.recurse(parentBooster); 136 } 132 137 133 138 this.props.corpora.recurse(function(corpus) { corpus.subCorpora.sort(sortFn); }); … … 136 141 // display 137 142 this.props.corpora.update(); 138 // console.log("corpus search done", query); 143 }, 144 145 stop: function(e) { 146 e.stopPropagation(); 139 147 }, 140 148 … … 167 175 React.createElement("span", {className: "glyphicon glyphicon-plus", 'aria-hidden': "true"}), 168 176 169 corpus.expanded ? " Collapse ":" Expand ", " ", corpus.subCorpora.length, " subcollections"177 corpus.expanded ? " Collapse ":" Expand ", " (", corpus.subCorpora.length, " subcollections)" 170 178 ) 171 179 ); … … 179 187 }, 180 188 189 renderFilteredMessage: function() { 190 var total = 0; 191 var visible = 0; 192 this.props.corpora.recurse(function(corpus){ 193 if (corpus.visible) { 194 total ++; 195 if (corpus.priority > 0) { 196 visible++; 197 } 198 } 199 }); 200 if (visible === total) { 201 return false; 202 } 203 return React.createElement("div", null, " Showing ", visible, " out of ", total, " (sub)collections. "); 204 }, 205 181 206 renderCorpus: function(level, minmaxp, corpus) { 182 if (!corpus.visible ) {207 if (!corpus.visible || corpus.priority <= 0) { 183 208 return false; 184 209 } … … 187 212 var corpusContainerClass = "corpus-container "+(corpus.priority>0?"":"dimmed"); 188 213 189 var hue = 80 * corpus.priority / minmaxp[1]; 190 if (corpus.priority > 0) { hue += 40; } 214 var hue = 120 * corpus.priority / minmaxp[1]; 191 215 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 ? { }216 var priorityStyle = {paddingBottom: 4, paddingLeft: 2, borderBottom: '3px solid '+color }; 217 var expansive = corpus.expanded ? {overflow:'hidden'} 194 218 : {whiteSpace:'nowrap', overflow:'hidden', textOverflow: 'ellipsis'}; 195 219 var title = corpus.title || corpus.displayName; … … 204 228 React.createElement("div", {style: indent}, 205 229 React.createElement("h3", {style: expansive}, 206 corpus.landingPage ? React.createElement("a", {href: corpus.landingPage}, title): title 230 title, 231 corpus.landingPage ? 232 React.createElement("a", {href: corpus.landingPage, onClick: this.stop}, 233 React.createElement("span", {style: {fontSize:12}}, " â Homepage "), React.createElement("i", {className: "fa fa-home"}) 234 ): false 207 235 ), 208 236 209 React.createElement("p", {style: expansive}, corpus.description) 210 ), 211 this.renderExpansion(corpus) 237 238 React.createElement("p", {style: expansive}, corpus.description), 239 this.renderExpansion(corpus) 240 ) 212 241 ), 213 242 React.createElement("div", {className: "col-sm-3 vcenter"}, … … 234 263 ), 235 264 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 265 React.createElement("button", {className: "btn btn-default", style: { marginRight: 10}, onClick: this.selectAll.bind(this,true)}, 240 266 " Select all"), 241 267 React.createElement("button", {className: "btn btn-default", style: { marginRight: 20}, onClick: this.selectAll.bind(this,false)}, 242 268 " Deselect all") 269 ), 270 React.createElement("div", {className: "float-right inline"}, 271 React.createElement("div", {className: "inline", style: { marginRight: 20}}, 272 React.createElement(SearchCorpusBox, {search: this.searchCorpus}), 273 this.renderFilteredMessage() 274 ) 243 275 ) 244 276 ), 277 245 278 this.props.corpora.corpora.map(this.renderCorpus.bind(this, 0, minmaxp)) 246 279 ); -
SRUAggregator/trunk/src/main/resources/assets/js/corpora.jsx
r5931 r5954 25 25 26 26 handleChange: function(event) { 27 this.setState({query: event.target.value}); 28 this.props.search(event.target.value); 27 var query = event.target.value; 28 this.setState({query: query}); 29 30 if (query.length === 0 || 2 <= query.length) { 31 this.props.search(query); 32 } 29 33 event.stopPropagation(); 30 34 }, … … 51 55 }, 52 56 53 toggleSelection: function (corpus ) {57 toggleSelection: function (corpus, e) { 54 58 var s = !corpus.selected; 55 59 this.props.corpora.recurseCorpus(corpus, function(c) { c.selected = s; }); 56 60 this.props.corpora.update(); 61 this.stop(e); 57 62 }, 58 63 … … 76 81 }; 77 82 78 this.props.corpora.recurse(function(corpus) { corpus.subCorpora.sort(sortFn); });79 this.props.corpora.corpora.sort(sortFn);80 81 83 query = query.toLowerCase(); 82 var querytokens = query.split(" ");83 84 if (!query) { 84 85 this.props.corpora.recurse(function(corpus) {corpus.priority = 1; }); … … 93 94 94 95 // find priority for each corpus 96 var querytokens = query.split(" ").filter(function(x){ return x.length > 0; }); 95 97 this.props.corpora.recurse(function(corpus){ 96 98 var title = corpus.title ? corpus.title : corpus.displayName; … … 121 123 }.bind(this)); 122 124 123 // ensure root corpora have nonnull priority124 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 } );125 // ensure parents of visible corpora are also visible; maximum depth = 3 126 var isVisibleFn = function(corpus){ return corpus.priority > 0; }; 127 var parentBooster = function(corpus){ 128 if (corpus.priority <= 0 && corpus.subCorpora) { 129 if (corpus.subCorpora.some(isVisibleFn)) { 130 corpus.priority = 0.5; 131 } 130 132 } 131 }); 133 }; 134 for (var i = 3; i > 0; i --) { 135 this.props.corpora.recurse(parentBooster); 136 } 132 137 133 138 this.props.corpora.recurse(function(corpus) { corpus.subCorpora.sort(sortFn); }); … … 136 141 // display 137 142 this.props.corpora.update(); 138 // console.log("corpus search done", query); 143 }, 144 145 stop: function(e) { 146 e.stopPropagation(); 139 147 }, 140 148 … … 167 175 <span className="glyphicon glyphicon-plus" aria-hidden="true"/> 168 176 } 169 {corpus.expanded ? " Collapse ":" Expand "} {corpus.subCorpora.length} subcollections177 {corpus.expanded ? " Collapse ":" Expand "} ({corpus.subCorpora.length} subcollections) 170 178 </a> 171 179 </div>; … … 179 187 }, 180 188 189 renderFilteredMessage: function() { 190 var total = 0; 191 var visible = 0; 192 this.props.corpora.recurse(function(corpus){ 193 if (corpus.visible) { 194 total ++; 195 if (corpus.priority > 0) { 196 visible++; 197 } 198 } 199 }); 200 if (visible === total) { 201 return false; 202 } 203 return <div> Showing {visible} out of {total} (sub)collections. </div>; 204 }, 205 181 206 renderCorpus: function(level, minmaxp, corpus) { 182 if (!corpus.visible ) {207 if (!corpus.visible || corpus.priority <= 0) { 183 208 return false; 184 209 } … … 187 212 var corpusContainerClass = "corpus-container "+(corpus.priority>0?"":"dimmed"); 188 213 189 var hue = 80 * corpus.priority / minmaxp[1]; 190 if (corpus.priority > 0) { hue += 40; } 214 var hue = 120 * corpus.priority / minmaxp[1]; 191 215 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 ? { }216 var priorityStyle = {paddingBottom: 4, paddingLeft: 2, borderBottom: '3px solid '+color }; 217 var expansive = corpus.expanded ? {overflow:'hidden'} 194 218 : {whiteSpace:'nowrap', overflow:'hidden', textOverflow: 'ellipsis'}; 195 219 var title = corpus.title || corpus.displayName; … … 203 227 <div className="col-sm-8 vcenter"> 204 228 <div style={indent}> 205 <h3 style={expansive}> 206 { corpus.landingPage ? <a href={corpus.landingPage}>{title}</a>: title } 229 <h3 style={expansive}> 230 {title} 231 { corpus.landingPage ? 232 <a href={corpus.landingPage} onClick={this.stop}> 233 <span style={{fontSize:12}}> â Homepage </span><i className="fa fa-home"/> 234 </a>: false} 207 235 </h3> 208 236 237 209 238 <p style={expansive}>{corpus.description}</p> 239 {this.renderExpansion(corpus)} 210 240 </div> 211 {this.renderExpansion(corpus)}212 241 </div> 213 242 <div className="col-sm-3 vcenter"> … … 234 263 </div> 235 264 <div className="float-right inline"> 236 <div className="inline" style={{ marginRight: 20 }} >237 <SearchCorpusBox search={this.searchCorpus}/>238 </div>239 265 <button className="btn btn-default" style={{ marginRight: 10 }} onClick={this.selectAll.bind(this,true)}> 240 266 {" Select all"}</button> … … 242 268 {" Deselect all"}</button> 243 269 </div> 270 <div className="float-right inline"> 271 <div className="inline" style={{ marginRight: 20 }} > 272 <SearchCorpusBox search={this.searchCorpus}/> 273 {this.renderFilteredMessage()} 274 </div> 275 </div> 244 276 </div> 277 245 278 {this.props.corpora.corpora.map(this.renderCorpus.bind(this, 0, minmaxp))} 246 279 </div>; -
SRUAggregator/trunk/src/main/resources/assets/js/main.js
r5919 r5954 105 105 React.createElement("div", {className: "container"}, 106 106 React.createElement("div", {className: "beta-tag"}, 107 React.createElement("span", null, " BETA")107 React.createElement("span", null, "ALPHA") 108 108 ) 109 109 ), … … 270 270 271 271 React.render(React.createElement(Main, null), document.getElementById('reactMain') ); 272 272 273 })(); -
SRUAggregator/trunk/src/main/resources/assets/js/main.jsx
r5919 r5954 105 105 <div className="container"> 106 106 <div className="beta-tag"> 107 <span> BETA</span>107 <span>ALPHA</span> 108 108 </div> 109 109 </div> … … 270 270 271 271 React.render(<Main />, document.getElementById('reactMain') ); 272 272 273 })(); -
SRUAggregator/trunk/src/main/resources/assets/js/search.js
r5931 r5954 65 65 corpus.expanded = false; // not expanded in the corpus view 66 66 corpus.priority = 1; // priority in corpus view 67 corpus.index = index; 67 corpus.index = index; // original order, used for stable sort 68 68 }); 69 69 } … … 79 79 Corpora.prototype.recurseCorpora = function(corpora, fn) { 80 80 var recfn = function(corpus, index){ 81 if (false === fn(corpus )) {81 if (false === fn(corpus, index)) { 82 82 // no recursion 83 83 } else { … … 284 284 285 285 stop: function(e) { 286 e.preventDefault();287 286 e.stopPropagation(); 288 287 }, … … 296 295 endRecord: corpusHit.endRecord, 297 296 exception: corpusHit.exception, 297 diagnostics: corpusHit.diagnostics, 298 298 searchString: corpusHit.searchString, 299 299 kwics: corpusHit.kwics.filter(function(kwic){ … … 379 379 React.createElement("span", {className: "input-group-addon nobkg"}, "and show up to"), 380 380 React.createElement("div", {className: "input-group-btn"}, 381 React.createElement("input", {type: "number", className: "form-control input", min: "10", max: "250", step: "5",382 style: {width: 54},381 React.createElement("input", {type: "number", className: "form-control input", min: "10", max: "250", 382 style: {width:60}, 383 383 onChange: this.setNumberOfResults, value: this.state.numberOfResults, 384 384 onKeyPress: this.stop}) … … 556 556 557 557 renderRowLanguage: function(hit) { 558 return React.createElement("span", {style: {fontFace:"Courier",color:"black"}}, hit.language, " ");558 return false; //<span style={{fontFace:"Courier",color:"black"}}>{hit.language} </span> ; 559 559 }, 560 560 … … 619 619 }, 620 620 621 renderDiagnostics: function(corpusHit) { 622 if (!corpusHit.diagnostics || corpusHit.diagnostics.length === 0) { 623 return false; 624 } 625 626 return corpusHit.diagnostics.map(function(d) { 627 return React.createElement("div", {className: "alert alert-danger", role: "alert"}, 628 d.dgnMessage, ": ", d.dgnDiagnostic 629 ); 630 }); 631 }, 632 621 633 renderPanelBody: function(corpusHit) { 622 var fulllength = {width:"100%"}; 634 var fulllength = {width:"100%"}; 623 635 if (this.state.displayKwic) { 624 return React.createElement("table", {className: "table table-condensed table-hover", style: fulllength}, 625 React.createElement("tbody", null, corpusHit.kwics.map(this.renderRowsAsKwic)) 636 return React.createElement("div", null, 637 this.renderDiagnostics(corpusHit), 638 React.createElement("table", {className: "table table-condensed table-hover", style: fulllength}, 639 React.createElement("tbody", null, corpusHit.kwics.map(this.renderRowsAsKwic)) 640 ) 626 641 ); 627 642 } else { 628 return React.createElement("div", null, corpusHit.kwics.map(this.renderRowsAsHits)); 643 return React.createElement("div", null, 644 this.renderDiagnostics(corpusHit), 645 corpusHit.kwics.map(this.renderRowsAsHits) 646 ); 629 647 } 630 648 }, 631 649 632 650 renderResultPanels: function(corpusHit) { 633 if (corpusHit.kwics.length === 0) { 651 if (corpusHit.kwics.length === 0 && 652 corpusHit.diagnostics.length === 0) { 634 653 return false; 635 654 } -
SRUAggregator/trunk/src/main/resources/assets/js/search.jsx
r5931 r5954 65 65 corpus.expanded = false; // not expanded in the corpus view 66 66 corpus.priority = 1; // priority in corpus view 67 corpus.index = index; 67 corpus.index = index; // original order, used for stable sort 68 68 }); 69 69 } … … 79 79 Corpora.prototype.recurseCorpora = function(corpora, fn) { 80 80 var recfn = function(corpus, index){ 81 if (false === fn(corpus )) {81 if (false === fn(corpus, index)) { 82 82 // no recursion 83 83 } else { … … 284 284 285 285 stop: function(e) { 286 e.preventDefault();287 286 e.stopPropagation(); 288 287 }, … … 296 295 endRecord: corpusHit.endRecord, 297 296 exception: corpusHit.exception, 297 diagnostics: corpusHit.diagnostics, 298 298 searchString: corpusHit.searchString, 299 299 kwics: corpusHit.kwics.filter(function(kwic){ … … 379 379 <span className="input-group-addon nobkg">and show up to</span> 380 380 <div className="input-group-btn"> 381 <input type="number" className="form-control input" min="10" max="250" step="5"382 style={{width: 54}}381 <input type="number" className="form-control input" min="10" max="250" 382 style={{width:60}} 383 383 onChange={this.setNumberOfResults} value={this.state.numberOfResults} 384 384 onKeyPress={this.stop}/> … … 556 556 557 557 renderRowLanguage: function(hit) { 558 return <span style={{fontFace:"Courier",color:"black"}}>{hit.language} </span> ;558 return false; //<span style={{fontFace:"Courier",color:"black"}}>{hit.language} </span> ; 559 559 }, 560 560 … … 619 619 }, 620 620 621 renderDiagnostics: function(corpusHit) { 622 if (!corpusHit.diagnostics || corpusHit.diagnostics.length === 0) { 623 return false; 624 } 625 626 return corpusHit.diagnostics.map(function(d) { 627 return <div className="alert alert-danger" role="alert"> 628 {d.dgnMessage}{": "}{d.dgnDiagnostic} 629 </div>; 630 }); 631 }, 632 621 633 renderPanelBody: function(corpusHit) { 622 var fulllength = {width:"100%"}; 634 var fulllength = {width:"100%"}; 623 635 if (this.state.displayKwic) { 624 return <table className="table table-condensed table-hover" style={fulllength}> 625 <tbody>{corpusHit.kwics.map(this.renderRowsAsKwic)}</tbody> 626 </table>; 636 return <div> 637 {this.renderDiagnostics(corpusHit)} 638 <table className="table table-condensed table-hover" style={fulllength}> 639 <tbody>{corpusHit.kwics.map(this.renderRowsAsKwic)}</tbody> 640 </table> 641 </div>; 627 642 } else { 628 return <div>{corpusHit.kwics.map(this.renderRowsAsHits)}</div>; 643 return <div> 644 {this.renderDiagnostics(corpusHit)} 645 {corpusHit.kwics.map(this.renderRowsAsHits)} 646 </div>; 629 647 } 630 648 }, 631 649 632 650 renderResultPanels: function(corpusHit) { 633 if (corpusHit.kwics.length === 0) { 651 if (corpusHit.kwics.length === 0 && 652 corpusHit.diagnostics.length === 0) { 634 653 return false; 635 654 }
Note: See TracChangeset
for help on using the changeset viewer.