Search all fields by default, gray out nodes if no match

This commit is contained in:
David Kaltschmidt
2016-05-11 18:08:59 +02:00
parent 8669266f25
commit 3ee802a516
6 changed files with 73 additions and 66 deletions
+36 -42
View File
@@ -1,71 +1,67 @@
import { Map as makeMap } from 'immutable';
import { slugify } from './string-utils';
// topolevel search fields
const SEARCH_FIELDS = makeMap({
label: 'label',
sublabel: 'label_minor'
});
// TODO make this dynamic based on topology
const SEARCH_TABLES = makeMap({
dockerlabel: 'docker_label_',
dockerenv: 'docker_env_',
});
const PREFIX_DELIMITER = ':';
const PREFIX_ALL = 'all';
const PREFIX_ALL_SHORT = 'a';
const PREFIX_METADATA = 'metadata';
const PREFIX_METADATA_SHORT = 'm';
function findNodeMatch(nodeMatches, keyPath, text, query, label) {
const index = text.indexOf(query);
if (index > -1) {
nodeMatches = nodeMatches.setIn(keyPath,
{text, label, matches: [{start: index, length: query.length}]});
function matchPrefix(label, prefix) {
if (label && prefix) {
return (new RegExp(prefix, 'i')).test(slugify(label));
}
return false;
}
function findNodeMatch(nodeMatches, keyPath, text, query, prefix, label) {
if (!prefix || matchPrefix(label, prefix)) {
const queryRe = new RegExp(query, 'i');
const matches = text.match(queryRe);
if (matches) {
const firstMatch = matches[0];
const index = text.search(queryRe);
nodeMatches = nodeMatches.setIn(keyPath,
{text, label, matches: [{start: index, length: firstMatch.length}]});
}
}
return nodeMatches;
}
function searchTopology(nodes, searchFields, prefix, query) {
function searchTopology(nodes, prefix, query) {
let nodeMatches = makeMap();
nodes.forEach((node, nodeId) => {
// top level fields
searchFields.forEach((field, label) => {
SEARCH_FIELDS.forEach((field, label) => {
const keyPath = [nodeId, label];
nodeMatches = findNodeMatch(nodeMatches, keyPath, node.get(field), query, label);
nodeMatches = findNodeMatch(nodeMatches, keyPath, node.get(field),
query, prefix, label);
});
// metadata
if (node.get('metadata') && (prefix === PREFIX_METADATA || prefix === PREFIX_METADATA_SHORT
|| prefix === PREFIX_ALL || prefix === PREFIX_ALL_SHORT)) {
if (node.get('metadata')) {
node.get('metadata').forEach(field => {
const keyPath = [nodeId, 'metadata', field.get('id')];
nodeMatches = findNodeMatch(nodeMatches, keyPath, field.get('value'),
query, field.get('label'));
query, prefix, field.get('label'));
});
}
// tables (envvars and labels)
const tables = node.get('tables');
if (tables) {
let searchTables;
if (prefix === PREFIX_ALL || prefix === PREFIX_ALL_SHORT) {
searchTables = SEARCH_TABLES;
} else if (prefix) {
searchTables = SEARCH_TABLES.filter((field, label) => prefix === label);
}
if (searchTables && searchTables.size > 0) {
searchTables.forEach((searchTable) => {
const table = tables.find(t => t.get('id') === searchTable);
if (table && table.get('rows')) {
table.get('rows').forEach(field => {
const keyPath = [nodeId, 'metadata', field.get('id')];
nodeMatches = findNodeMatch(nodeMatches, keyPath, field.get('value'),
query, field.get('label'));
});
}
});
}
tables.forEach((table) => {
if (table.get('rows')) {
table.get('rows').forEach(field => {
const keyPath = [nodeId, 'metadata', field.get('id')];
nodeMatches = findNodeMatch(nodeMatches, keyPath, field.get('value'),
query, prefix, field.get('label'));
});
}
});
}
});
return nodeMatches;
@@ -82,15 +78,13 @@ export function updateNodeMatches(state) {
if (query && (isPrefixQuery === isValidPrefixQuery)) {
const prefix = isValidPrefixQuery ? prefixQuery[0] : null;
let searchFields = SEARCH_FIELDS;
if (isPrefixQuery) {
query = prefixQuery[1];
searchFields = searchFields.filter((field, label) => label === prefix);
}
state.get('topologyUrlsById').forEach((url, topologyId) => {
const topologyNodes = state.getIn(['nodesByTopology', topologyId]);
if (topologyNodes) {
const nodeMatches = searchTopology(topologyNodes, searchFields, prefix, query);
const nodeMatches = searchTopology(topologyNodes, prefix, query);
state = state.setIn(['searchNodeMatches', topologyId], nodeMatches);
}
});
+5
View File
@@ -64,3 +64,8 @@ function makeFormatMetric(renderFn) {
export const formatMetric = makeFormatMetric(renderHtml);
export const formatMetricSvg = makeFormatMetric(renderSvg);
export const formatDate = d3.time.format.iso;
const CLEAN_LABEL_REGEX = /\W/g;
export function slugify(label) {
return label.replace(CLEAN_LABEL_REGEX, '');
}