mirror of
https://github.com/weaveworks/scope.git
synced 2026-08-18 03:46:45 +00:00
Search all fields by default, gray out nodes if no match
This commit is contained in:
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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, '');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user