Make translated challenge titles searchable
This commit is contained in:
		@@ -11,7 +11,8 @@ import {
 | 
				
			|||||||
} from './actions';
 | 
					} from './actions';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  createMapUi,
 | 
					  createMapUi,
 | 
				
			||||||
  filterComingSoonBetaFromEntities
 | 
					  filterComingSoonBetaFromEntities,
 | 
				
			||||||
 | 
					  searchableChallengeTitles
 | 
				
			||||||
} from '../utils';
 | 
					} from '../utils';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  delayedRedirect,
 | 
					  delayedRedirect,
 | 
				
			||||||
@@ -69,12 +70,18 @@ export default function fetchChallengesSaga(action$, getState, { services }) {
 | 
				
			|||||||
            entities,
 | 
					            entities,
 | 
				
			||||||
            isDev
 | 
					            isDev
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
 | 
					          const searchNames = searchableChallengeTitles(filteredEntities);
 | 
				
			||||||
          return Observable.of(
 | 
					          return Observable.of(
 | 
				
			||||||
            fetchChallengesCompleted(
 | 
					            fetchChallengesCompleted(
 | 
				
			||||||
              createNameIdMap(filteredEntities),
 | 
					              createNameIdMap(filteredEntities),
 | 
				
			||||||
              result
 | 
					              result
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            initMap(createMapUi(filteredEntities, result)),
 | 
					            initMap(
 | 
				
			||||||
 | 
					              createMapUi(
 | 
				
			||||||
 | 
					                filteredEntities,
 | 
				
			||||||
 | 
					                result,
 | 
				
			||||||
 | 
					                searchNames
 | 
				
			||||||
 | 
					              )),
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .catch(createErrorObservable);
 | 
					        .catch(createErrorObservable);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -303,6 +303,16 @@ export function filterComingSoonBetaFromEntities(
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function searchableChallengeTitles({ challenge: challengeMap } = {}) {
 | 
				
			||||||
 | 
					  return Object.keys(challengeMap)
 | 
				
			||||||
 | 
					    .map(dashedName => challengeMap[dashedName])
 | 
				
			||||||
 | 
					    .reduce((accu, current) => {
 | 
				
			||||||
 | 
					        accu[current.dashedName] = current.title;
 | 
				
			||||||
 | 
					        return accu;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    , {});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// interface Node {
 | 
					// interface Node {
 | 
				
			||||||
//   isHidden: Boolean,
 | 
					//   isHidden: Boolean,
 | 
				
			||||||
//   children: Void|[ ...Node ],
 | 
					//   children: Void|[ ...Node ],
 | 
				
			||||||
@@ -328,7 +338,8 @@ export function filterComingSoonBetaFromEntities(
 | 
				
			|||||||
// }
 | 
					// }
 | 
				
			||||||
export function createMapUi(
 | 
					export function createMapUi(
 | 
				
			||||||
  { superBlock: superBlockMap, block: blockMap } = {},
 | 
					  { superBlock: superBlockMap, block: blockMap } = {},
 | 
				
			||||||
  superBlocks
 | 
					  superBlocks,
 | 
				
			||||||
 | 
					  searchNameMap
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  if (!superBlocks || !superBlockMap || !blockMap) {
 | 
					  if (!superBlocks || !superBlockMap || !blockMap) {
 | 
				
			||||||
    return {};
 | 
					    return {};
 | 
				
			||||||
@@ -347,6 +358,7 @@ export function createMapUi(
 | 
				
			|||||||
            children: protect(blockMap[block]).challenges.map(challenge => {
 | 
					            children: protect(blockMap[block]).challenges.map(challenge => {
 | 
				
			||||||
              return {
 | 
					              return {
 | 
				
			||||||
                name: challenge,
 | 
					                name: challenge,
 | 
				
			||||||
 | 
					                title: searchNameMap[challenge],
 | 
				
			||||||
                isHidden: false,
 | 
					                isHidden: false,
 | 
				
			||||||
                children: null
 | 
					                children: null
 | 
				
			||||||
              };
 | 
					              };
 | 
				
			||||||
@@ -455,7 +467,7 @@ export function applyFilterToMap(tree, filterRegex) {
 | 
				
			|||||||
      // if leaf (challenge) then test if regex is a match
 | 
					      // if leaf (challenge) then test if regex is a match
 | 
				
			||||||
      if (!Array.isArray(node.children)) {
 | 
					      if (!Array.isArray(node.children)) {
 | 
				
			||||||
        // does challenge name meet filter criteria?
 | 
					        // does challenge name meet filter criteria?
 | 
				
			||||||
        if (filterRegex.test(node.name)) {
 | 
					        if (filterRegex.test(node.title)) {
 | 
				
			||||||
          // is challenge currently hidden?
 | 
					          // is challenge currently hidden?
 | 
				
			||||||
          if (node.isHidden) {
 | 
					          if (node.isHidden) {
 | 
				
			||||||
            // unhide challenge, it matches
 | 
					            // unhide challenge, it matches
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -989,7 +989,10 @@ test('common/app/routes/challenges/utils', function(t) {
 | 
				
			|||||||
            ]
 | 
					            ]
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }, ['superBlockA']);
 | 
					      },
 | 
				
			||||||
 | 
					      ['superBlockA'],
 | 
				
			||||||
 | 
					      { challengeA: 'ChallengeA title'}
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
      t.plan(3);
 | 
					      t.plan(3);
 | 
				
			||||||
      t.equal(actual.children[0].name, expected.children[0].name);
 | 
					      t.equal(actual.children[0].name, expected.children[0].name);
 | 
				
			||||||
      t.equal(
 | 
					      t.equal(
 | 
				
			||||||
@@ -1155,21 +1158,21 @@ test('common/app/routes/challenges/utils', function(t) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    t.test('should update child that is hidden', t => {
 | 
					    t.test('should update child that is hidden', t => {
 | 
				
			||||||
      t.plan(1);
 | 
					      t.plan(1);
 | 
				
			||||||
      const expected = { name: 'bar', isHidden: false };
 | 
					      const expected = { title: 'bar', isHidden: false };
 | 
				
			||||||
      const input = { name: 'bar', isHidden: true };
 | 
					      const input = { title: 'bar', isHidden: true };
 | 
				
			||||||
      const actual = applyFilterToMap(input, /bar/);
 | 
					      const actual = applyFilterToMap(input, /bar/);
 | 
				
			||||||
      t.deepLooseEqual(actual, expected);
 | 
					      t.deepLooseEqual(actual, expected);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    t.test('should unhide child that matches filter regex', t => {
 | 
					    t.test('should unhide child that matches filter regex', t => {
 | 
				
			||||||
      t.plan(1);
 | 
					      t.plan(1);
 | 
				
			||||||
      const expected = { name: 'foo' };
 | 
					      const expected = { title: 'foo' };
 | 
				
			||||||
      const actual = applyFilterToMap({ name: 'foo' }, /foo/);
 | 
					      const actual = applyFilterToMap({ title: 'foo' }, /foo/);
 | 
				
			||||||
      t.deepLooseEqual(actual, expected);
 | 
					      t.deepLooseEqual(actual, expected);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    t.test('should hide child that does not match filter', t => {
 | 
					    t.test('should hide child that does not match filter', t => {
 | 
				
			||||||
      t.plan(1);
 | 
					      t.plan(1);
 | 
				
			||||||
      const expected = { name: 'bar', isHidden: true };
 | 
					      const expected = { title: 'bar', isHidden: true };
 | 
				
			||||||
      const actual = applyFilterToMap({ name: 'bar' }, /foo/);
 | 
					      const actual = applyFilterToMap({ title: 'bar' }, /foo/);
 | 
				
			||||||
      t.deepLooseEqual(actual, expected);
 | 
					      t.deepLooseEqual(actual, expected);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    t.test('should not touch node that is already hidden', t => {
 | 
					    t.test('should not touch node that is already hidden', t => {
 | 
				
			||||||
@@ -1191,8 +1194,8 @@ test('common/app/routes/challenges/utils', function(t) {
 | 
				
			|||||||
        name: 'bar',
 | 
					        name: 'bar',
 | 
				
			||||||
        isHidden: false,
 | 
					        isHidden: false,
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
          { name: 'baz', isHidden: true },
 | 
					          { title: 'baz', isHidden: true },
 | 
				
			||||||
          { name: 'foo', isHidden: false }
 | 
					          { title: 'foo', isHidden: false }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      const actual = applyFilterToMap(expected, /foo/);
 | 
					      const actual = applyFilterToMap(expected, /foo/);
 | 
				
			||||||
@@ -1225,16 +1228,16 @@ test('common/app/routes/challenges/utils', function(t) {
 | 
				
			|||||||
        name: 'bar',
 | 
					        name: 'bar',
 | 
				
			||||||
        isHidden: true,
 | 
					        isHidden: true,
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
          { name: 'baz', isHidden: true },
 | 
					          { title: 'baz', isHidden: true },
 | 
				
			||||||
          { name: 'foo', isHidden: false }
 | 
					          { title: 'foo', isHidden: false }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      const expected = {
 | 
					      const expected = {
 | 
				
			||||||
        name: 'bar',
 | 
					        name: 'bar',
 | 
				
			||||||
        isHidden: false,
 | 
					        isHidden: false,
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
          { name: 'baz', isHidden: true },
 | 
					          { title: 'baz', isHidden: true },
 | 
				
			||||||
          { name: 'foo', isHidden: false }
 | 
					          { title: 'foo', isHidden: false }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      const actual = applyFilterToMap(input, /foo/);
 | 
					      const actual = applyFilterToMap(input, /foo/);
 | 
				
			||||||
@@ -1258,4 +1261,3 @@ test('common/app/routes/challenges/utils', function(t) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user