--- /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;