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