clientjs/packages/dashboard-components/src/reducers/terms.js
changeset 0 5f4fcbc80b37
equal deleted inserted replaced
-1:000000000000 0:5f4fcbc80b37
       
     1 import _ from 'lodash';
       
     2 
       
     3 import { RECEIVE_ANNOTATIONS, RECEIVE_MESSAGES_COUNT } from '../actions';
       
     4 import { isDefinitionInTags } from '../utils';
       
     5 
       
     6 /**
       
     7  * termsMap is a mapping { term: [annotations,...] }
       
     8  * where annotation
       
     9  */
       
    10 function getDefinitionsAndReferences(annotations, termsMap) {
       
    11   return Object.keys(termsMap).reduce((res, term) => {
       
    12     res[term] = res[term] || {
       
    13       keywordAnnotations: termsMap[term],
       
    14       definitions: [],
       
    15       references: [],
       
    16     };
       
    17 
       
    18     termsMap[term].forEach((annotation) => {
       
    19       const annotationText = (annotation.text && annotation.text.trim()) || '';
       
    20       const tags = annotation.tags.map(t => t.toLowerCase());
       
    21       if (annotationText && isDefinitionInTags(tags)) {
       
    22         const annotationObj = annotation;
       
    23         annotationObj.isPersonal = true;
       
    24         res[term].definitions.push(annotationObj);
       
    25       }
       
    26     });
       
    27 
       
    28     annotations.forEach((annotation) => {
       
    29       const tags = annotation.tags.map(t => t.toLowerCase());
       
    30       if (isDefinitionInTags(tags) && tags.includes(term.toLowerCase())) {
       
    31         const annotationObj = annotation;
       
    32         annotationObj.isPersonal = false;
       
    33         res[term].definitions.push(annotationObj);
       
    34       } else {
       
    35         let exactText;
       
    36 
       
    37         (annotation.target[0].selector || []).some((selector) => {
       
    38           if (selector.type === 'TextQuoteSelector' && selector.exact) {
       
    39             exactText = selector.exact.trim().toLowerCase();
       
    40             return true;
       
    41           }
       
    42           return false;
       
    43         });
       
    44 
       
    45         if (exactText && exactText.includes(term.toLowerCase()) && !tags.includes('cat:mot-clef')) {
       
    46           res[term].references.push(annotation);
       
    47         }
       
    48       }
       
    49     });
       
    50     return res;
       
    51   }, {});
       
    52 }
       
    53 
       
    54 /**
       
    55  * Calculate stats on terms
       
    56  */
       
    57 function addTermStats(termsMap) {
       
    58   return _.reduce(
       
    59     termsMap,
       
    60     (res, termDef, term) => {
       
    61       res[term] = _.assign({
       
    62         definitionsNb: (termDef.definitions || []).length,
       
    63         referenceNb: (termDef.references || []).length,
       
    64       }, termDef);
       
    65       return res;
       
    66     },
       
    67     {},
       
    68   );
       
    69 }
       
    70 
       
    71 
       
    72 function terms(
       
    73   state = {
       
    74   },
       
    75   action,
       
    76 ) {
       
    77   switch (action.type) {
       
    78     case RECEIVE_ANNOTATIONS: {
       
    79       const { annotations } = action;
       
    80       // let termsMap = getTerms(annotations);
       
    81       let termsMap = action.terms;
       
    82       termsMap = getDefinitionsAndReferences(annotations, termsMap);
       
    83       return Object.assign({}, state, addTermStats(termsMap));
       
    84     }
       
    85     case RECEIVE_MESSAGES_COUNT: {
       
    86       const { terms: termList, messagesCount: counts } = action;
       
    87       const termCountMap = _.zipObject(termList, counts);
       
    88 
       
    89       return Object.assign({}, state, _.mapValues(
       
    90         state,
       
    91         (termDef, term) => Object.assign(
       
    92           {},
       
    93           termDef,
       
    94           { messagesCount: termCountMap[term] || 0 },
       
    95         ),
       
    96       ));
       
    97     }
       
    98     default:
       
    99       return state;
       
   100   }
       
   101 }
       
   102 
       
   103 export default terms;