clientjs/packages/dashboard-components/src/reducers/terms.js
changeset 0 5f4fcbc80b37
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/clientjs/packages/dashboard-components/src/reducers/terms.js	Fri Sep 14 17:57:34 2018 +0200
@@ -0,0 +1,103 @@
+import _ from 'lodash';
+
+import { RECEIVE_ANNOTATIONS, RECEIVE_MESSAGES_COUNT } from '../actions';
+import { isDefinitionInTags } from '../utils';
+
+/**
+ * termsMap is a mapping { term: [annotations,...] }
+ * where annotation
+ */
+function getDefinitionsAndReferences(annotations, termsMap) {
+  return Object.keys(termsMap).reduce((res, term) => {
+    res[term] = res[term] || {
+      keywordAnnotations: termsMap[term],
+      definitions: [],
+      references: [],
+    };
+
+    termsMap[term].forEach((annotation) => {
+      const annotationText = (annotation.text && annotation.text.trim()) || '';
+      const tags = annotation.tags.map(t => t.toLowerCase());
+      if (annotationText && isDefinitionInTags(tags)) {
+        const annotationObj = annotation;
+        annotationObj.isPersonal = true;
+        res[term].definitions.push(annotationObj);
+      }
+    });
+
+    annotations.forEach((annotation) => {
+      const tags = annotation.tags.map(t => t.toLowerCase());
+      if (isDefinitionInTags(tags) && tags.includes(term.toLowerCase())) {
+        const annotationObj = annotation;
+        annotationObj.isPersonal = false;
+        res[term].definitions.push(annotationObj);
+      } else {
+        let exactText;
+
+        (annotation.target[0].selector || []).some((selector) => {
+          if (selector.type === 'TextQuoteSelector' && selector.exact) {
+            exactText = selector.exact.trim().toLowerCase();
+            return true;
+          }
+          return false;
+        });
+
+        if (exactText && exactText.includes(term.toLowerCase()) && !tags.includes('cat:mot-clef')) {
+          res[term].references.push(annotation);
+        }
+      }
+    });
+    return res;
+  }, {});
+}
+
+/**
+ * Calculate stats on terms
+ */
+function addTermStats(termsMap) {
+  return _.reduce(
+    termsMap,
+    (res, termDef, term) => {
+      res[term] = _.assign({
+        definitionsNb: (termDef.definitions || []).length,
+        referenceNb: (termDef.references || []).length,
+      }, termDef);
+      return res;
+    },
+    {},
+  );
+}
+
+
+function terms(
+  state = {
+  },
+  action,
+) {
+  switch (action.type) {
+    case RECEIVE_ANNOTATIONS: {
+      const { annotations } = action;
+      // let termsMap = getTerms(annotations);
+      let termsMap = action.terms;
+      termsMap = getDefinitionsAndReferences(annotations, termsMap);
+      return Object.assign({}, state, addTermStats(termsMap));
+    }
+    case RECEIVE_MESSAGES_COUNT: {
+      const { terms: termList, messagesCount: counts } = action;
+      const termCountMap = _.zipObject(termList, counts);
+
+      return Object.assign({}, state, _.mapValues(
+        state,
+        (termDef, term) => Object.assign(
+          {},
+          termDef,
+          { messagesCount: termCountMap[term] || 0 },
+        ),
+      ));
+    }
+    default:
+      return state;
+  }
+}
+
+export default terms;