From 51d29b4f5b24e8a87bf7340ad5163c81d9d456f5 Mon Sep 17 00:00:00 2001
From: esikkala <esko.ikkala@aalto.fi>
Date: Wed, 14 Nov 2018 17:19:55 +0200
Subject: [PATCH] Refactor facet functions

---
 src/client/actions/index.js          |  3 +-
 src/client/components/FacetDialog.js | 10 ++----
 src/client/components/ResultTable.js |  1 +
 src/client/components/Tree.js        | 15 ++++----
 src/client/containers/MapApp.js      |  2 ++
 src/client/epics/index.js            |  9 ++---
 src/client/reducers/facet.js         | 26 ++++++++++++++
 src/client/reducers/search.js        | 27 ---------------
 src/server/index.js                  |  5 ++-
 src/server/sparql/Datasets.js        | 46 +++++++++++++++++++++++++
 src/server/sparql/Manuscripts.js     | 51 ++--------------------------
 11 files changed, 97 insertions(+), 98 deletions(-)

diff --git a/src/client/actions/index.js b/src/client/actions/index.js
index 9ffc6c5f..c1dc88f9 100644
--- a/src/client/actions/index.js
+++ b/src/client/actions/index.js
@@ -151,9 +151,8 @@ export const fetchPlaceFailed = (error) => ({
 });
 
 // Facet
-export const fetchFacet = (property) => ({
+export const fetchFacet = () => ({
   type: FETCH_FACET,
-  property
 });
 export const updateFacet = ({ facetValues }) => ({
   type: UPDATE_FACET,
diff --git a/src/client/components/FacetDialog.js b/src/client/components/FacetDialog.js
index 4d4b2572..94925d6c 100644
--- a/src/client/components/FacetDialog.js
+++ b/src/client/components/FacetDialog.js
@@ -40,14 +40,9 @@ class FacetDialog extends React.Component {
     }
   }
 
-  handleClickOpen = () => {
-    this.props.fetchFacet(this.props.property);
-    this.setState({ open: true });
-  };
+  handleClickOpen = () => this.setState({ open: true });
 
-  handleClose = () => {
-    this.setState({ open: false });
-  };
+  handleClose = () => this.setState({ open: false });
 
   render() {
     const { classes, propertyLabel, facet } = this.props;
@@ -75,6 +70,7 @@ class FacetDialog extends React.Component {
               :
               <Tree
                 data={facet.facetValues.creationPlace}
+                fetchFacet={this.props.fetchFacet}
                 updateFilter={this.props.updateFilter}
               />}
           </DialogContent>
diff --git a/src/client/components/ResultTable.js b/src/client/components/ResultTable.js
index d3c731ff..b9c74e0e 100644
--- a/src/client/components/ResultTable.js
+++ b/src/client/components/ResultTable.js
@@ -57,6 +57,7 @@ class ResultTable extends React.Component {
   componentDidMount = () => {
     this.props.fetchResults();
     this.props.fetchManuscripts(0);
+    this.props.fetchFacet();
   }
 
   idRenderer = (row) => {
diff --git a/src/client/components/Tree.js b/src/client/components/Tree.js
index bbb5077f..9426a552 100644
--- a/src/client/components/Tree.js
+++ b/src/client/components/Tree.js
@@ -37,12 +37,14 @@ class Tree extends Component {
     };
   }
 
-  handleCheckboxChange = name => event => {
-    console.log(name)
-    console.log(event.target.checked)
-    // this.props.updateFilter({
-    //
-    // })
+  handleCheckboxChange = name => () => {
+    //console.log(name)
+    //console.log(event.target.checked)
+    this.props.updateFilter({
+      property: 'creationPlace',
+      value: name
+    });
+    this.props.fetchFacet();
   };
 
   render() {
@@ -170,6 +172,7 @@ class Tree extends Component {
 Tree.propTypes = {
   classes: PropTypes.object.isRequired,
   data: PropTypes.array.isRequired,
+  fetchFacet: PropTypes.func.isRequired,
   updateFilter: PropTypes.func.isRequired,
 };
 
diff --git a/src/client/containers/MapApp.js b/src/client/containers/MapApp.js
index 84dc5750..60d44911 100644
--- a/src/client/containers/MapApp.js
+++ b/src/client/containers/MapApp.js
@@ -89,6 +89,8 @@ let MapApp = (props) => {
   // browser
   // error,
 
+  // console.log(props.facet)
+
   return (
     <div className={classes.root}>
       <div className={classes.appFrame}>
diff --git a/src/client/epics/index.js b/src/client/epics/index.js
index 0f6bca26..083ca292 100644
--- a/src/client/epics/index.js
+++ b/src/client/epics/index.js
@@ -1,6 +1,6 @@
 
 import { ajax } from 'rxjs/ajax';
-import { mergeMap, map } from 'rxjs/operators';
+import { mergeMap, map, withLatestFrom } from 'rxjs/operators';
 import { combineEpics, ofType } from 'redux-observable';
 import {
   updateManuscripts,
@@ -57,9 +57,10 @@ const getPlace = action$ => action$.pipe(
 
 const getFacet = action$ => action$.pipe(
   ofType(FETCH_FACET),
-  mergeMap((action) => {
-    const searchUrl = apiUrl + 'facet';
-    const requestUrl = `${searchUrl}?property=${action.property}`;
+  mergeMap(() => {
+    const requestUrl = `${apiUrl}facet`;
+    //const facetFilters = state$.getState().facet.facetFilters;
+    //let str = Object.entries(facetFilters).map(([key, set]) => `${key}=${Array.from(set)}`).join('&');
     return ajax.getJSON(requestUrl).pipe(
       map(response => updateFacet({ facetValues: response }))
     );
diff --git a/src/client/reducers/facet.js b/src/client/reducers/facet.js
index 1c7d0cb1..f02b7464 100644
--- a/src/client/reducers/facet.js
+++ b/src/client/reducers/facet.js
@@ -1,6 +1,7 @@
 import {
   FETCH_FACET,
   UPDATE_FACET,
+  UPDATE_FILTER
 } from '../actions';
 
 export const INITIAL_STATE = {
@@ -16,6 +17,10 @@ export const INITIAL_STATE = {
     creationPlace: [],
     author: []
   },
+  facetFilters: {
+    creationPlace: new Set(),
+    author: new Set(),
+  },
   fetchingFacet : false
 };
 
@@ -29,9 +34,30 @@ const facet = (state = INITIAL_STATE, action) => {
         facetValues: action.facetValues,
         fetchingFacet: false
       };
+    case UPDATE_FILTER:
+      return updateFilter(state, action);
     default:
       return state;
   }
 };
 
+const updateFilter = (state, action) => {
+  const { property, value } = action.filter;
+  let nSet = state.facetFilters[property];
+  if (nSet.has(value)) {
+    nSet.delete(value);
+  } else {
+    nSet.add(value);
+  }
+  const newFilter = updateObject(state.filters, { [property]: nSet });
+  return updateObject(state, { facetFilters: newFilter });
+};
+
+const updateObject = (oldObject, newValues) => {
+  // Encapsulate the idea of passing a new object as the first parameter
+  // to Object.assign to ensure we correctly copy data instead of mutating
+  //console.log(Object.assign({}, oldObject, newValues));
+  return Object.assign({}, oldObject, newValues);
+};
+
 export default facet;
diff --git a/src/client/reducers/search.js b/src/client/reducers/search.js
index 3d069181..b5002020 100644
--- a/src/client/reducers/search.js
+++ b/src/client/reducers/search.js
@@ -15,7 +15,6 @@ import {
   CLEAR_PLACES,
   UPDATE_PLACE,
   SORT_RESULTS,
-  UPDATE_FILTER
 } from '../actions';
 
 export const INITIAL_STATE = {
@@ -34,10 +33,6 @@ export const INITIAL_STATE = {
       'selected': false
     },
   },
-  filters: {
-    creationPlace: new Set(),
-    author: new Set(),
-  },
   suggestions: [],
   suggestionsQuery: '',
   fetchingSuggestions: false,
@@ -132,10 +127,7 @@ const search = (state = INITIAL_STATE, action) => {
         'places': {},
         fetchingPlaces: false
       };
-    case UPDATE_FILTER:
-      return updateFilter(state, action);
     case SORT_RESULTS:
-      //console.log(action)
       return {
         ...state,
         sortBy: action.options.sortBy,
@@ -146,23 +138,4 @@ const search = (state = INITIAL_STATE, action) => {
   }
 };
 
-const updateFilter = (state, action) => {
-  const { property, value } = action.filter;
-  let nSet = state.filters[property];
-  if (nSet.has(value)) {
-    nSet.delete(value);
-  } else {
-    nSet.add(value);
-  }
-  const newFilter = updateObject(state.filters, { [property]: nSet });
-  return updateObject(state, { filters: newFilter });
-};
-
-const updateObject = (oldObject, newValues) => {
-  // Encapsulate the idea of passing a new object as the first parameter
-  // to Object.assign to ensure we correctly copy data instead of mutating
-  //console.log(Object.assign({}, oldObject, newValues));
-  return Object.assign({}, oldObject, newValues);
-};
-
 export default search;
diff --git a/src/server/index.js b/src/server/index.js
index 196dfa4b..c74b02a7 100644
--- a/src/server/index.js
+++ b/src/server/index.js
@@ -85,13 +85,12 @@ app.get('/places/:placeId?', (req, res) => {
 });
 
 app.get('/facet', (req, res) => {
-  const property = req.query.property;
-  return getFacet(property).then((data) => {
+  return getFacet().then((data) => {
     const facetValues = {
       creationPlace: data,
       author: []
     };
-    //console.log(data);
+    // console.log(data);
     res.json(facetValues);
   })
     .catch((err) => {
diff --git a/src/server/sparql/Datasets.js b/src/server/sparql/Datasets.js
index 816649a8..5a4e477a 100644
--- a/src/server/sparql/Datasets.js
+++ b/src/server/sparql/Datasets.js
@@ -305,6 +305,52 @@ module.exports = {
         #}
       }
         `,
+    'facetQuery': `
+          PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
+          PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+          PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+          PREFIX crm: <http://www.cidoc-crm.org/cidoc-crm/>
+          PREFIX owl: <http://www.w3.org/2002/07/owl#>
+          PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
+          PREFIX text: <http://jena.apache.org/text#>
+          PREFIX dct: <http://purl.org/dc/terms/>
+          PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
+          PREFIX sch: <http://schema.org/>
+          PREFIX geosparql: <http://www.opengis.net/ont/geosparql#>
+          PREFIX frbroo: <http://erlangen-crm.org/efrbroo/>
+          PREFIX mmm-schema: <http://ldf.fi/mmm/schema/>
+          SELECT DISTINCT ?cnt ?facet_text ?value ?parent
+          WHERE {
+            SELECT DISTINCT ?cnt ?value ?facet_text ?parent {
+              { SELECT DISTINCT (count(DISTINCT ?id) as ?cnt) ?value ?parent
+                {
+                  ?id a frbroo:F4_Manifestation_Singleton .
+                  ?id skos:prefLabel ?name .
+                  ?id ^frbroo:R18_created/crm:P7_took_place_at ?value .
+                  OPTIONAL { ?value mmm-schema:parent ?parent }
+                }
+                GROUP BY ?value ?parent
+              }
+              FILTER(BOUND(?value)) BIND(COALESCE(?value, <http://ldf.fi/NONEXISTENT_URI>) AS ?labelValue)
+              OPTIONAL { ?labelValue skos:prefLabel ?lbl .
+                FILTER(langMatches(lang(?lbl), "fi")) . }
+              OPTIONAL { ?labelValue rdfs:label ?lbl .
+                FILTER(langMatches(lang(?lbl), "fi")) . }
+              OPTIONAL { ?labelValue skos:prefLabel ?lbl .
+                FILTER(langMatches(lang(?lbl), "en")) . }
+              OPTIONAL { ?labelValue rdfs:label ?lbl .
+                FILTER(langMatches(lang(?lbl), "en")) . }
+              OPTIONAL { ?labelValue skos:prefLabel ?lbl .
+                FILTER(langMatches(lang(?lbl), "sv")) . }
+              OPTIONAL { ?labelValue rdfs:label ?lbl .
+                FILTER(langMatches(lang(?lbl), "sv")) . }
+              OPTIONAL { ?labelValue skos:prefLabel ?lbl .
+                FILTER(langMatches(lang(?lbl), "")) . }
+              OPTIONAL { ?labelValue rdfs:label ?lbl .
+                FILTER(langMatches(lang(?lbl), "")) . }
+              BIND(COALESCE(?lbl, IF(!ISURI(?value), ?value, "")) AS ?facet_text) }
+          }
+    `,
     'tgn': {
       // Getty LOD documentation:
       // http://vocab.getty.edu/queries#Places_by_Type
diff --git a/src/server/sparql/Manuscripts.js b/src/server/sparql/Manuscripts.js
index 0cdee0db..faa581b6 100644
--- a/src/server/sparql/Manuscripts.js
+++ b/src/server/sparql/Manuscripts.js
@@ -37,8 +37,8 @@ export const getPlace = (id) => {
   return sparqlSearchEngine.doSearch(placeQuery, endpoint, makeObjectList);
 };
 
-export const getFacet = (property) => {
-  const { endpoint } = datasetConfig['mmm'];
+export const getFacet = () => {
+  const { endpoint, facetQuery } = datasetConfig['mmm'];
   // console.log(facetQuery)
   return sparqlSearchEngine.doSearch(facetQuery, endpoint, mapFacet);
 };
@@ -53,50 +53,3 @@ const generateFilter = (filterObj) => {
   }
   return filterStr;
 };
-
-const facetQuery = `
-  PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
-  PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
-  PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
-  PREFIX crm: <http://www.cidoc-crm.org/cidoc-crm/>
-  PREFIX owl: <http://www.w3.org/2002/07/owl#>
-  PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
-  PREFIX text: <http://jena.apache.org/text#>
-  PREFIX dct: <http://purl.org/dc/terms/>
-  PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
-  PREFIX sch: <http://schema.org/>
-  PREFIX geosparql: <http://www.opengis.net/ont/geosparql#>
-  PREFIX frbroo: <http://erlangen-crm.org/efrbroo/>
-  PREFIX mmm-schema: <http://ldf.fi/mmm/schema/>
-  SELECT DISTINCT ?cnt ?facet_text ?value ?parent
-  WHERE {
-    SELECT DISTINCT ?cnt ?value ?facet_text ?parent {
-      { SELECT DISTINCT (count(DISTINCT ?id) as ?cnt) ?value ?parent
-        {
-          ?id a frbroo:F4_Manifestation_Singleton .
-          ?id skos:prefLabel ?name .
-          ?id ^frbroo:R18_created/crm:P7_took_place_at ?value .
-          OPTIONAL { ?value mmm-schema:parent ?parent }
-        }
-        GROUP BY ?value ?parent
-      }
-      FILTER(BOUND(?value)) BIND(COALESCE(?value, <http://ldf.fi/NONEXISTENT_URI>) AS ?labelValue)
-      OPTIONAL { ?labelValue skos:prefLabel ?lbl .
-        FILTER(langMatches(lang(?lbl), "fi")) . }
-      OPTIONAL { ?labelValue rdfs:label ?lbl .
-        FILTER(langMatches(lang(?lbl), "fi")) . }
-      OPTIONAL { ?labelValue skos:prefLabel ?lbl .
-        FILTER(langMatches(lang(?lbl), "en")) . }
-      OPTIONAL { ?labelValue rdfs:label ?lbl .
-        FILTER(langMatches(lang(?lbl), "en")) . }
-      OPTIONAL { ?labelValue skos:prefLabel ?lbl .
-        FILTER(langMatches(lang(?lbl), "sv")) . }
-      OPTIONAL { ?labelValue rdfs:label ?lbl .
-        FILTER(langMatches(lang(?lbl), "sv")) . }
-      OPTIONAL { ?labelValue skos:prefLabel ?lbl .
-        FILTER(langMatches(lang(?lbl), "")) . }
-      OPTIONAL { ?labelValue rdfs:label ?lbl .
-        FILTER(langMatches(lang(?lbl), "")) . }
-      BIND(COALESCE(?lbl, IF(!ISURI(?value), ?value, "")) AS ?facet_text) }
-  }
-`;
-- 
GitLab