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