"use strict"; import classNames from "classnames"; import CorpusView from "../components/corpusview.jsx"; import LanguageSelector from "../components/languageselector.jsx" import Modal from "../components/modal.jsx"; import Results from "../components/results.jsx"; import QueryInput from "../components/queryinput.jsx"; import ZoomedResult from "../components/zoomedresult.jsx"; import PropTypes from "prop-types"; import createReactClass from "create-react-class"; var PT = PropTypes; window.MyAggregator = window.MyAggregator || {}; var multipleLanguageCode = window.MyAggregator.multipleLanguageCode = "mul"; // see ISO-693-3 var AggregatorPage = createReactClass({ // fixme! - class AggregatorPage extends React.Component { propTypes: { ajax: PT.func.isRequired, error: PT.func.isRequired, embedded: PT.bool.isRequired }, nohits: { results: null, }, anyLanguage: [multipleLanguageCode, "Any Language"], getInitialState: function () { var aggrContext = getQueryVariable('x-aggregation-context'); aggrContext = aggrContext && JSON.parse(aggrContext); return { corpora: new Corpora([], this.updateCorpora), languageMap: {}, weblichtLanguages: [], queryTypeId: getQueryVariable('queryType') || 'cql', cqlQuery: ((getQueryVariable('queryType') || 'cql') === 'cql') && getQueryVariable('query') || '', fcsQuery: ((getQueryVariable('queryType') || 'cql') === 'fcs') && getQueryVariable('query') || '', aggregationContext: aggrContext || null, language: this.anyLanguage, languageFilter: 'byMeta', numberOfResults: 10, searchId: null, timeout: 0, hits: this.nohits, zoomedCorpusHit: null, }; }, componentDidMount: function() { this._isMounted = true; this.props.ajax({ url: 'rest/init', success: function(json, textStatus, jqXHR) { if (this._isMounted) { var corpora = new Corpora(json.corpora, this.updateCorpora); // // for testing aggregation context // json['x-aggregation-context'] = { // 'EKUT': ["http://hdl.handle.net/11858/00-1778-0000-0001-DDAF-D"] // }; var aggregationContext = json['x-aggregation-context'] || this.state.aggregationContext; window.MyAggregator.mode = getQueryVariable('mode') || json.mode; window.MyAggregator.corpora = json.corpora; window.MyAggregator.xAggregationContext = aggregationContext; // Setting visibility, e.g. only corpora // from v2.0 endpoints for fcs v2.0 corpora.setVisibility(this.state.queryTypeId, this.state.language[0]); if (aggregationContext) { const contextCorporaInfo = corpora.setAggregationContext(aggregationContext); const unavailableCorporaHandles = contextCorporaInfo.unavailable; // list of unavailable aggregationContext if (unavailableCorporaHandles.length > 0) { this.props.error("Could not find requested collection handles:\n" + unavailableCorporaHandles.join('\n')); } const actuallySelectedCorpora = corpora.getSelectedIds(); if (contextCorporaInfo.selected.length !== actuallySelectedCorpora.length) { if (actuallySelectedCorpora.length === 0) { this.props.error("This search does not support the required collection(s), will search all collections instead"); // TODO give detailed reason its not supported. corpora.recurse(function(corpus) { corpus.selected = true; }); } else { var err = "Some required context collections are not supported for this search:\n" err = err + contextCorpora.filter((c) => { if (actuallySelectedCorpora.indexOf(c) === -1) { console.warn("Requested corpus but not available for selection", c); return true; } return false; }).map((c) => c.title).join('\n') this.props.error(err); } } } else { // no context set all visibl to selected as default. console.log("no context set, selecting all available"); corpora.recurse(c => {c.visible ? c.selected=true : null}) } this.setState({ corpora : corpora, languageMap: json.languages, weblichtLanguages: json.weblichtLanguages, aggregationContext: aggregationContext, }, this.postInit); } else { console.warn("Got Aggregator init response, but not mounted!"); } }.bind(this), }); }, postInit() { if (window.MyAggregator.mode === 'search') { this.search(); } }, updateCorpora: function(corpora) { this.setState({corpora:corpora}); }, getCurrentQuery() { return this.state.queryTypeId === 'fcs' ? this.state.fcsQuery : this.state.cqlQuery; }, search() { var query = this.getCurrentQuery(); var queryTypeId = this.state.queryTypeId; if (!query || (this.props.embedded && window.MyAggregator.mode !== 'search')) { this.setState({ hits: this.nohits, searchId: null }); return; } var selectedIds = this.state.corpora.getSelectedIds(); if (!selectedIds.length) { this.props.error("Please select a collection to search into"); return; } // console.log("searching in the following corpora:", selectedIds); // console.log("searching with queryType:", queryTypeId); this.props.ajax({ url: 'rest/search', type: "POST", data: { query: query, queryType: queryTypeId, language: this.state.language[0], numberOfResults: this.state.numberOfResults, corporaIds: selectedIds, }, success: function(searchId, textStatus, jqXHR) { // console.log("search ["+query+"] ok: ", searchId, jqXHR); //Piwik.getAsyncTracker().trackSiteSearch(query, queryTypeId); // automatic inclusion of piwik in prod //console.log("location.hostname: " + location.hostname); if (location.hostname !== "localhost") { //console.log("location.host: " + location.host); _paq.push(['trackSiteSearch', query, queryTypeId, false]); } var timeout = 250; setTimeout(this.refreshSearchResults, timeout); this.setState({ searchId: searchId, timeout: timeout }); }.bind(this), }); }, nextResults: function(corpusId) { // console.log("searching next results in corpus:", corpusId); this.props.ajax({ url: 'rest/search/'+this.state.searchId, type: "POST", data: { corpusId: corpusId, numberOfResults: this.state.numberOfResults, }, success: function(searchId, textStatus, jqXHR) { // console.log("search ["+query+"] ok: ", searchId, jqXHR); var timeout = 250; setTimeout(this.refreshSearchResults, timeout); this.setState({ searchId: searchId, timeout: timeout }); }.bind(this), }); }, refreshSearchResults: function() { if (!this.state.searchId || !this._isMounted) { return; } this.props.ajax({ url: 'rest/search/'+this.state.searchId, success: function(json, textStatus, jqXHR) { var timeout = this.state.timeout; if (json.inProgress) { if (timeout < 10000) { timeout = 1.5 * timeout; } setTimeout(this.refreshSearchResults, timeout); // console.log("new search in: " + this.timeout + "ms"); } else { console.log("search ended; hits:", json); } var corpusHit = this.state.zoomedCorpusHit; if (corpusHit) { for (var resi = 0; resi < json.results.length; resi++) { var res = json.results[resi]; if (res.corpus.id === corpusHit.corpus.id) { corpusHit = res; break; } } } this.setState({ hits: json, timeout: timeout, zoomedCorpusHit: corpusHit}); }.bind(this), }); }, getExportParams: function(corpusId, format, filterLanguage) { var params = corpusId ? {corpusId:corpusId}:{}; if (format) params.format = format; if (filterLanguage) { params.filterLanguage = filterLanguage; } else if (this.state.languageFilter === 'byGuess' || this.state.languageFilter === 'byMetaAndGuess') { params.filterLanguage = this.state.language[0]; } return encodeQueryData(params); }, getDownloadLink: function(corpusId, format) { return 'rest/search/'+this.state.searchId+'/download?' + this.getExportParams(corpusId, format); }, getToWeblichtLink: function(corpusId, forceLanguage) { return 'rest/search/'+this.state.searchId+'/toWeblicht?' + this.getExportParams(corpusId, null, forceLanguage); }, setLanguageAndFilter: function(languageObj, languageFilter) { this.state.corpora.setVisibility(this.state.queryTypeId, languageFilter === 'byGuess' ? multipleLanguageCode : languageObj[0]); this.setState({ language: languageObj, languageFilter: languageFilter, corpora: this.state.corpora, // === this.state.corpora.update(); }); }, setQueryType: function(queryTypeId) { this.state.corpora.setVisibility(queryTypeId, this.state.language[0]); setQueryVariable('queryType', queryTypeId); setQueryVariable('query', queryTypeId === 'cql' ? this.state.cqlQuery : this.state.fcsQuery) this.setState({ queryTypeId: queryTypeId, hits: this.nohits, searchId: null, }); }, setNumberOfResults: function(e) { var n = e.target.value; if (n < 10) n = 10; if (n > 250) n = 250; this.setState({numberOfResults: n}); e.preventDefault(); e.stopPropagation(); }, stop: function(e) { e.stopPropagation(); }, filterResults: function() { var noLangFiltering = this.state.languageFilter === 'byMeta'; var langCode = this.state.language[0]; var results = null, inProgress = 0, hits = 0; if (this.state.hits.results) { results = this.state.hits.results.map(function(corpusHit) { return { corpus: corpusHit.corpus, inProgress: corpusHit.inProgress, exception: corpusHit.exception, diagnostics: corpusHit.diagnostics, kwics: noLangFiltering ? corpusHit.kwics : corpusHit.kwics.filter(function(kwic) { return kwic.language === langCode || langCode === multipleLanguageCode || langCode === null; }), advancedLayers: noLangFiltering ? corpusHit.advancedLayers : corpusHit.advancedLayers.filter(function(layer) { return layer.language === langCode || langCode === multipleLanguageCode || langCode === null; }), }; }); for (var i = 0; i < results.length; i++) { var result = results[i]; if (result.inProgress) { inProgress++; } if (result.kwics.length > 0) { hits ++; } } } return { results: results, hits: hits, inProgress: inProgress, }; }, toggleLanguageSelection: function(e) { $(ReactDOM.findDOMNode(this.refs.languageModal)).modal(); e.preventDefault(); e.stopPropagation(); }, toggleCorpusSelection: function(e) { $(ReactDOM.findDOMNode(this.refs.corporaModal)).modal(); e.preventDefault(); e.stopPropagation(); }, toggleResultModal: function(e, corpusHit) { $(ReactDOM.findDOMNode(this.refs.resultModal)).modal(); this.setState({zoomedCorpusHit: corpusHit}); e.preventDefault(); e.stopPropagation(); }, onQueryChange: function(queryStr) { if (this.state.queryTypeId === 'cql') { this.setState({ cqlQuery: queryStr || '', }); } else { this.setState({ fcsQuery: queryStr || '', }); } setQueryVariable('query', queryStr); }, handleKey: function(event) { if (event.keyCode==13) { this.search(); } }, renderZoomedResultTitle: function(corpusHit) { if (!corpusHit) return (); var corpus = corpusHit.corpus; return (
{this.getCurrentQuery()}