mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-03 18:20:27 +00:00
Keep topology nav visible if selected
If the scope-app API unexpectedly restarts, it has no report at hand (until it gets one from the probe) and sends node count 0 to the frontend for all topologies. Once the report arrives, it will send the proper count. What happened was the frontend did hide Processes for a short time till the node count recovered. This moved the topology selection to the always visible Containers (hide_if_empty == false) while keeping the graph as is. Once the node count recovers, Processes comes back but the selection is still at Containers. We now keep the selected topology visible at all time even if the API returns a node count of 0. This recovers nicely when the correct node counts come in. Once the user selects a different topology while and a backend response arrives, it disappears. Fixes #2646
This commit is contained in:
@@ -280,6 +280,25 @@ describe('RootReducer', () => {
|
|||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ReceiveTopologiesHiddenAction = {
|
||||||
|
type: ActionTypes.RECEIVE_TOPOLOGIES,
|
||||||
|
topologies: [{
|
||||||
|
url: '/topo1',
|
||||||
|
name: 'Topo1',
|
||||||
|
stats: {
|
||||||
|
node_count: 1
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
hide_if_empty: true,
|
||||||
|
url: '/topo2',
|
||||||
|
name: 'Topo2',
|
||||||
|
stats: {
|
||||||
|
node_count: 0,
|
||||||
|
filtered_nodes: 0
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
const RouteAction = {
|
const RouteAction = {
|
||||||
type: ActionTypes.ROUTE_TOPOLOGY,
|
type: ActionTypes.ROUTE_TOPOLOGY,
|
||||||
state: {}
|
state: {}
|
||||||
@@ -567,6 +586,21 @@ describe('RootReducer', () => {
|
|||||||
expect(isTopologyNodeCountZero(nextState)).toBeFalsy();
|
expect(isTopologyNodeCountZero(nextState)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('keeps hidden topology visible if selected', () => {
|
||||||
|
let nextState = initialState;
|
||||||
|
nextState = reducer(nextState, ClickTopology2Action);
|
||||||
|
nextState = reducer(nextState, ReceiveTopologiesHiddenAction);
|
||||||
|
expect(nextState.get('currentTopologyId')).toEqual('topo2');
|
||||||
|
expect(nextState.get('topologies').toJS().length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps hidden topology hidden if not selected', () => {
|
||||||
|
let nextState = initialState;
|
||||||
|
nextState = reducer(nextState, ClickTopologyAction);
|
||||||
|
nextState = reducer(nextState, ReceiveTopologiesHiddenAction);
|
||||||
|
expect(nextState.get('topologies').toJS().length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
// selection of relatives
|
// selection of relatives
|
||||||
|
|
||||||
it('keeps relatives as a stack', () => {
|
it('keeps relatives as a stack', () => {
|
||||||
|
|||||||
@@ -110,17 +110,17 @@ function calcSelectType(topology) {
|
|||||||
// adds ID field to topology (based on last part of URL path) and save urls in
|
// adds ID field to topology (based on last part of URL path) and save urls in
|
||||||
// map for easy lookup
|
// map for easy lookup
|
||||||
function processTopologies(state, nextTopologies) {
|
function processTopologies(state, nextTopologies) {
|
||||||
|
// add IDs to topology objects in-place
|
||||||
|
const topologiesWithId = updateTopologyIds(nextTopologies);
|
||||||
// filter out hidden topos
|
// filter out hidden topos
|
||||||
const visibleTopologies = filterHiddenTopologies(nextTopologies);
|
const visibleTopologies = filterHiddenTopologies(topologiesWithId, state.get('currentTopologyId'));
|
||||||
// set `selectType` field for topology and sub_topologies options (recursive).
|
// set `selectType` field for topology and sub_topologies options (recursive).
|
||||||
const topologiesWithSelectType = visibleTopologies.map(calcSelectType);
|
const topologiesWithSelectType = visibleTopologies.map(calcSelectType);
|
||||||
// add IDs to topology objects in-place
|
|
||||||
const topologiesWithId = updateTopologyIds(topologiesWithSelectType);
|
|
||||||
// cache URLs by ID
|
// cache URLs by ID
|
||||||
state = state.set('topologyUrlsById',
|
state = state.set('topologyUrlsById',
|
||||||
setTopologyUrlsById(state.get('topologyUrlsById'), topologiesWithId));
|
setTopologyUrlsById(state.get('topologyUrlsById'), topologiesWithSelectType));
|
||||||
|
|
||||||
const topologiesWithFullnames = addTopologyFullname(topologiesWithId);
|
const topologiesWithFullnames = addTopologyFullname(topologiesWithSelectType);
|
||||||
const immNextTopologies = fromJS(topologiesWithFullnames).sortBy(topologySorter);
|
const immNextTopologies = fromJS(topologiesWithFullnames).sortBy(topologySorter);
|
||||||
return state.set('topologies', immNextTopologies);
|
return state.set('topologies', immNextTopologies);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,9 +126,9 @@ export function setTopologyUrlsById(topologyUrlsById, topologies) {
|
|||||||
return urlMap;
|
return urlMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filterHiddenTopologies(topologies) {
|
export function filterHiddenTopologies(topologies, currentTopologyId) {
|
||||||
return topologies.filter(t => (!t.hide_if_empty || t.stats.node_count > 0 ||
|
return topologies.filter(t => (!t.hide_if_empty || t.stats.node_count > 0 ||
|
||||||
t.stats.filtered_nodes > 0));
|
t.stats.filtered_nodes > 0 || t.id === currentTopologyId));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCurrentTopologyOptions(state) {
|
export function getCurrentTopologyOptions(state) {
|
||||||
|
|||||||
Reference in New Issue
Block a user