diff --git a/src/client/actions/index.js b/src/client/actions/index.js index e29519fd9540304257b16bb38b6d794a13eaef6d..14e610fe39364a64a32e30d0955b749339477311 100644 --- a/src/client/actions/index.js +++ b/src/client/actions/index.js @@ -8,11 +8,22 @@ export const FETCH_SUGGESTIONS = 'FETCH_SUGGESTIONS'; export const FETCH_SUGGESTIONS_FAILED = 'FETCH_SUGGESTIONS_FAILED'; export const UPDATE_SUGGESTIONS = 'UPDATE_SUGGESTIONS'; export const CLEAR_SUGGESTIONS = 'CLEAR_SUGGESTIONS'; + export const FETCH_RESULTS = 'FETCH_RESULTS'; -export const FETCH_ALL_RESULTS = 'FETCH_ALL_RESULTS'; -export const FETCH_RESULTS_FAILED = 'FETCH_RESULTS_FAILED'; export const UPDATE_RESULTS = 'UPDATE_RESULTS'; export const CLEAR_RESULTS = 'CLEAR_RESULTS'; +export const FETCH_RESULTS_FAILED = 'FETCH_RESULTS_FAILED'; + +export const FETCH_MANUSCRIPTS = 'FETCH_MANUSCRIPTS'; +export const UPDATE_MANUSCRIPTS = 'UPDATE_MANUSCRIPTS'; +export const CLEAR_MANUSCRIPTS = 'CLEAR_MANUSCRIPTS'; +export const FETCH_MANUSCRIPTS_FAILED = 'FETCH_MANUSCRIPTS_FAILED'; + +export const FETCH_PLACES = 'FETCH_PLACES'; +export const UPDATE_PLACES = 'UPDATE_PLACES'; +export const CLEAR_PLACES = 'CLEAR_PLACES'; +export const FETCH_PLACES_FAILED = 'FETCH_PLACES_FAILED'; + export const UPDATE_RESULTS_FILTER = 'UPDATE_RESULTS_FILTER'; export const SORT_RESULTS = 'SORT_RESULTS'; export const CLEAR_ERROR = 'CLEAR_ERROR'; @@ -60,10 +71,7 @@ export const fetchSuggestionsFailed = (error) => ({ error }); -export const fetchResultsFailed = (error) => ({ - type: FETCH_RESULTS_FAILED, - error -}); + export const updateSuggestions = ({ suggestions }) => ({ type: UPDATE_SUGGESTIONS, @@ -74,14 +82,11 @@ export const clearSuggestions = () => ({ type: CLEAR_SUGGESTIONS, }); +// Results export const fetchResults = () => ({ type: FETCH_RESULTS, }); -export const fetchAllResults = () => ({ - type: FETCH_ALL_RESULTS, -}); - export const updateResults = ({ results }) => ({ type: UPDATE_RESULTS, results @@ -91,6 +96,54 @@ export const clearResults = () => ({ type: CLEAR_RESULTS, }); +export const fetchResultsFailed = (error) => ({ + type: FETCH_RESULTS_FAILED, + error +}); + +// Manuscripts +export const fetchManuscripts = () => ({ + type: FETCH_MANUSCRIPTS, +}); + +export const updateManuscripts = ({ manuscripts }) => ({ + type: UPDATE_MANUSCRIPTS, + manuscripts +}); + +export const clearManuscripts = () => ({ + type: CLEAR_MANUSCRIPTS, +}); + +export const fetchManuscriptsFailed = (error) => ({ + type: FETCH_MANUSCRIPTS_FAILED, + error +}); + +// Places +export const fetchPlaces = () => ({ + type: FETCH_PLACES, +}); + +export const updatePlaces = ({ places }) => ({ + type: UPDATE_PLACES, + places +}); + +export const clearPlaces = () => ({ + type: CLEAR_PLACES, +}); + +export const fetchPlacesFailed = (error) => ({ + type: FETCH_PLACES_FAILED, + error +}); + + + + + + export const updateResultsFilter = (filter) => ({ type: UPDATE_RESULTS_FILTER, filter diff --git a/src/client/components/SearchField.js b/src/client/components/SearchField.js index ab151d861e662b8cc9a767dd09a93a280ba02eac..4df465d60d3adb854794840927731a7086f5722f 100644 --- a/src/client/components/SearchField.js +++ b/src/client/components/SearchField.js @@ -50,7 +50,7 @@ class SearchField extends React.Component { handleClick = () => { //this.props.updateQuery(this.state.value); this.props.clearResults(); - this.props.fetchAllResults(); + this.props.fetchResults(); }; render() { diff --git a/src/client/components/VirtualizedTable.js b/src/client/components/VirtualizedTable.js index a547810499a7860848307426878c1b6b83bb54b2..a1e06d777582d2dc205a1c708389127ad1ae8c2c 100644 --- a/src/client/components/VirtualizedTable.js +++ b/src/client/components/VirtualizedTable.js @@ -161,10 +161,9 @@ class VirtualizedTable extends React.PureComponent { const searchField = ( <SearchField search={this.props.search} - fetchResults={this.props.fetchResults} - fetchAllResults={this.props.fetchAllResults} + fetchResults={this.props.fetchManuscripts} updateQuery={this.props.updateQuery} - clearResults={this.props.clearResults} + clearResults={this.props.clearManuscripts} /> ); @@ -230,7 +229,8 @@ class VirtualizedTable extends React.PureComponent { /> <Column label="Creation place" - cellDataGetter={({rowData}) => valueFromArray('creationPlace', rowData)} + // cellDataGetter={({rowData}) => valueFromArray('creationPlace', rowData)} + cellDataGetter={({rowData}) => rowData.creationPlace} dataKey="creationPlace" headerRenderer={headerRenderer} width={columnWidth} @@ -294,9 +294,8 @@ VirtualizedTable.propTypes = { updateQuery: PropTypes.func.isRequired, fetchSuggestions: PropTypes.func.isRequired, clearSuggestions: PropTypes.func.isRequired, - fetchResults: PropTypes.func.isRequired, - fetchAllResults: PropTypes.func.isRequired, - clearResults: PropTypes.func.isRequired, + fetchManuscripts: PropTypes.func.isRequired, + clearManuscripts: PropTypes.func.isRequired, bounceMarker: PropTypes.func.isRequired, openMarkerPopup: PropTypes.func.isRequired, removeTempMarker: PropTypes.func.isRequired, diff --git a/src/client/containers/MapApp.js b/src/client/containers/MapApp.js index 64aac9b89d6fbf8c888cc6cf3bf216dff5914fbc..92dedbf2f975eadc29f3135d6014c0a0ac27dc9f 100644 --- a/src/client/containers/MapApp.js +++ b/src/client/containers/MapApp.js @@ -22,9 +22,10 @@ import { toggleDataset, fetchSuggestions, clearSuggestions, - fetchResults, - fetchAllResults, - clearResults, + fetchManuscripts, + fetchPlaces, + clearManuscripts, + clearPlaces, getGeoJSON, updateResultFormat, updateMapMode, @@ -136,7 +137,7 @@ let MapApp = (props) => { // console.log('resultFormat', resultFormat) // console.log('mapMode', mapMode) //console.log(props.results) - //console.log(manuscripts) + console.log(manuscripts) let table = ''; if ((oneColumnView && options.resultFormat === 'table') || (!oneColumnView)) { @@ -149,9 +150,8 @@ let MapApp = (props) => { sortResults={props.sortResults} updateResultsFilter={props.updateResultsFilter} updateQuery={props.updateQuery} - fetchResults={props.fetchResults} - fetchAllResults={props.fetchAllResults} - clearResults={props.clearResults} + fetchManuscripts={props.fetchManuscripts} + clearManuscripts={props.clearManuscripts} fetchSuggestions={props.fetchSuggestions} clearSuggestions={props.clearSuggestions} bounceMarker={props.bounceMarker} @@ -268,8 +268,8 @@ const mapStateToProps = (state) => { search: state.search, map: state.map, // results: getVisibleResults(state.search), - manuscripts: state.search.results.manuscripts, - creationPlaces: state.search.results.creationPlaces, + manuscripts: state.search.manuscripts, + creationPlaces: state.search.places, //resultValues: getVisibleValues(state.search), resultValues: {}, }; @@ -280,9 +280,10 @@ const mapDispatchToProps = ({ toggleDataset, fetchSuggestions, clearSuggestions, - fetchResults, - fetchAllResults, - clearResults, + fetchManuscripts, + fetchPlaces, + clearManuscripts, + clearPlaces, sortResults, getGeoJSON, updateResultFormat, @@ -310,9 +311,10 @@ MapApp.propTypes = { toggleDataset: PropTypes.func.isRequired, fetchSuggestions: PropTypes.func.isRequired, clearSuggestions: PropTypes.func.isRequired, - fetchResults: PropTypes.func.isRequired, - fetchAllResults: PropTypes.func.isRequired, - clearResults: PropTypes.func.isRequired, + fetchManuscripts: PropTypes.func.isRequired, + fetchPlaces: PropTypes.func.isRequired, + clearManuscripts: PropTypes.func.isRequired, + clearPlaces: PropTypes.func.isRequired, sortResults: PropTypes.func.isRequired, getGeoJSON: PropTypes.func.isRequired, bounceMarker: PropTypes.func.isRequired, diff --git a/src/client/epics/index.js b/src/client/epics/index.js index 48605d22236fbf8111764d618748cdfbb3c51c3d..9b7c470858a03880452f3763a1b5cc3a99d5a9a4 100644 --- a/src/client/epics/index.js +++ b/src/client/epics/index.js @@ -5,13 +5,15 @@ import { combineEpics } from 'redux-observable'; import { Observable } from 'rxjs/Observable'; import { updateSuggestions, - updateResults, + updateManuscripts, + updatePlaces, updateGeoJSON, FETCH_SUGGESTIONS, FETCH_SUGGESTIONS_FAILED, - FETCH_RESULTS, - FETCH_ALL_RESULTS, - FETCH_RESULTS_FAILED, + FETCH_MANUSCRIPTS, + FETCH_MANUSCRIPTS_FAILED, + FETCH_PLACES, + FETCH_PLACES_FAILED, GET_GEOJSON, GET_GEOJSON_FAILED } from '../actions'; @@ -50,37 +52,37 @@ const getSuggestionsEpic = (action$, store) => { }); }; -const getResultsEpic = (action$, store) => { - const searchUrl = hiplaApiUrl + 'search'; - return action$.ofType(FETCH_RESULTS) - .debounceTime(500) - .switchMap(() => { - const { query, datasets } = store.getState().search; - if (query.length < 3) { - return []; - } - const dsParams = _.map(pickSelectedDatasets(datasets), ds => `dataset=${ds}`).join('&'); - const requestUrl = `${searchUrl}?q=${query}&${dsParams}`; - return ajax.getJSON(requestUrl) - .map(response => updateResults({ results: response })) - .catch(error => Observable.of({ - type: FETCH_RESULTS_FAILED, - error: error, - })); - }); -}; +// const getResultsEpic = (action$, store) => { +// const searchUrl = hiplaApiUrl + 'search'; +// return action$.ofType(FETCH_RESULTS) +// .debounceTime(500) +// .switchMap(() => { +// const { query, datasets } = store.getState().search; +// if (query.length < 3) { +// return []; +// } +// const dsParams = _.map(pickSelectedDatasets(datasets), ds => `dataset=${ds}`).join('&'); +// const requestUrl = `${searchUrl}?q=${query}&${dsParams}`; +// return ajax.getJSON(requestUrl) +// .map(response => updateResults({ results: response })) +// .catch(error => Observable.of({ +// type: FETCH_RESULTS_FAILED, +// error: error, +// })); +// }); +// }; -const getAllResultsEpic = (action$, store) => { - const searchUrl = hiplaApiUrl + 'all'; - return action$.ofType(FETCH_ALL_RESULTS) +const getManuscripts = (action$, store) => { + const searchUrl = hiplaApiUrl + 'manuscripts'; + return action$.ofType(FETCH_MANUSCRIPTS) .switchMap(() => { const { datasets } = store.getState().search; const dsParams = _.map(pickSelectedDatasets(datasets), ds => `dataset=${ds}`).join('&'); const requestUrl = `${searchUrl}?${dsParams}`; return ajax.getJSON(requestUrl) - .map(response => updateResults({ results: response })) + .map(response => updateManuscripts({ manuscripts: response })) .catch(error => Observable.of({ - type: FETCH_RESULTS_FAILED, + type: FETCH_MANUSCRIPTS_FAILED, error: error, })); }); @@ -108,6 +110,10 @@ const getGeoJSONEpic = (action$) => { }; -const rootEpic = combineEpics(getSuggestionsEpic, getResultsEpic, getAllResultsEpic, getGeoJSONEpic); +const rootEpic = combineEpics( + getSuggestionsEpic, + getManuscripts, + getGeoJSONEpic +); export default rootEpic; diff --git a/src/client/reducers/search.js b/src/client/reducers/search.js index d25650b7e602013ea022b1a67416f3a9b5aa18e1..a70d32fdd39384d0e8d7369b9b3b59788b55f4fd 100644 --- a/src/client/reducers/search.js +++ b/src/client/reducers/search.js @@ -2,17 +2,18 @@ import { UPDATE_QUERY, TOGGLE_DATASET, FETCH_SUGGESTIONS, - FETCH_RESULTS, UPDATE_SUGGESTIONS, CLEAR_SUGGESTIONS, - UPDATE_RESULTS, - CLEAR_RESULTS, + FETCH_MANUSCRIPTS, + FETCH_PLACES, + UPDATE_MANUSCRIPTS, + CLEAR_MANUSCRIPTS, + UPDATE_PLACES, + CLEAR_PLACES, UPDATE_RESULTS_FILTER, SORT_RESULTS } from '../actions'; -import sampleResults from './sampleResults'; - export const INITIAL_STATE = { query: '', datasets: { @@ -32,11 +33,8 @@ export const INITIAL_STATE = { suggestions: [], suggestionsQuery: '', fetchingSuggestions: false, - results: { - 'manuscripts': [], - 'creationPlaces': {} - }, - //results: sampleResults, + manuscripts: [], + places: {}, resultsFilter: { 'id': new Set(), 'label': new Set(), @@ -72,7 +70,8 @@ const search = (state = INITIAL_STATE, action) => { }; case FETCH_SUGGESTIONS: return { ...state, fetchingSuggestions: true }; - case FETCH_RESULTS: + case FETCH_MANUSCRIPTS: + case FETCH_PLACES: return { ...state, fetchingResults: true }; case CLEAR_SUGGESTIONS: return { @@ -88,21 +87,32 @@ const search = (state = INITIAL_STATE, action) => { suggestionsQuery: state.query, fetchingSuggestions: false }; - case CLEAR_RESULTS: + case UPDATE_MANUSCRIPTS: + return { + ...state, + manuscripts: action.manuscripts, + //resultsQuery: state.query, + fetchingResults: false + }; + case UPDATE_PLACES: return { ...state, - results: { - 'manuscripts': [], - 'creationPlaces': {} - }, + places: action.places, + //resultsQuery: state.query, + fetchingResults: false + }; + case CLEAR_MANUSCRIPTS: + return { + ...state, + 'manuscripts': [], resultsQuery: '', fetchingResults: false }; - case UPDATE_RESULTS: + case CLEAR_PLACES: return { ...state, - results: action.results, - resultsQuery: state.query, + 'places': {}, + resultsQuery: '', fetchingResults: false }; case UPDATE_RESULTS_FILTER: diff --git a/src/server/index.js b/src/server/index.js index e14fa2fc8fd2309205f0d1197fc0a65096435787..37af1895d0ff396c84fc8ae99a2c2fa2b985a929 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -53,7 +53,7 @@ app.get('/search', (req, res) => { }); }); -app.get('/all', (req, res) => { +app.get('/manuscripts', (req, res) => { const queryDatasets = _.castArray(req.query.dataset); return sparqlSearchEngine.getFederatedManuscripts(queryDatasets).then((data) => { diff --git a/src/server/sparql/Datasets.js b/src/server/sparql/Datasets.js index 917f3e81666b00698a20213f50326a03facbc430..610ed7bb7c64ec10bfc8215b485cd5236afb6c02 100644 --- a/src/server/sparql/Datasets.js +++ b/src/server/sparql/Datasets.js @@ -23,7 +23,7 @@ module.exports = { (GROUP_CONCAT(DISTINCT ?label_id; SEPARATOR=",") AS ?label) (GROUP_CONCAT(DISTINCT ?author_id; SEPARATOR=",") AS ?author) (GROUP_CONCAT(DISTINCT ?timespan_id; SEPARATOR=",") AS ?timespan) - (GROUP_CONCAT(DISTINCT ?creation_place_id; SEPARATOR=",") AS ?creationPlace) + (GROUP_CONCAT(DISTINCT ?creation_place; SEPARATOR=",") AS ?creationPlace) (GROUP_CONCAT(DISTINCT ?material_id; SEPARATOR=",") AS ?material) (GROUP_CONCAT(DISTINCT ?language_id; SEPARATOR=",") AS ?language) WHERE { @@ -34,7 +34,11 @@ module.exports = { ?expression_creation frbroo:R18_created ?id . OPTIONAL { ?expression_creation crm:P14_carried_out_by ?author_id . } OPTIONAL { ?expression_creation crm:P4_has_time_span ?timespan_id . } - OPTIONAL { ?expression_creation crm:P7_took_place_at ?creation_place_id . } + OPTIONAL { + ?expression_creation crm:P7_took_place_at ?creation_place_id . + ?creation_place_id skos:prefLabel ?creation_place_label . + BIND(CONCAT(STR(?creation_place_id), ":", STR(?creation_place_label)) AS ?creation_place) + } OPTIONAL { ?id crm:P128_carries ?expression . ?expression crm:P72_has_language ?language_id . diff --git a/src/server/sparql/SparqlSearchEngine.js b/src/server/sparql/SparqlSearchEngine.js index f162dcc67f951d52eb8ce62cd00d95c8e9c58765..a9e159b2f1db39be8a48d08b3a1ea962a2da0af4 100644 --- a/src/server/sparql/SparqlSearchEngine.js +++ b/src/server/sparql/SparqlSearchEngine.js @@ -22,14 +22,15 @@ class SparqlSearchEngine { getAllManuscripts(datasetId) { const { endpoint, allQuery } = datasetConfig[datasetId]; + console.log(allQuery) return this.doSearch(allQuery, endpoint, makeObjectList); } getFederatedManuscripts(datasets) { return Promise.all(datasets.map((datasetId) => this.getAllManuscripts(datasetId))) - .then(mergeAllResults) - .then((manuscripts) => this.getPlaces(manuscripts)); + .then(mergeAllResults); + // .then((manuscripts) => this.getPlaces(manuscripts)); } getPlaces(manuscripts) {