mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 17:51:21 +00:00
Initial version of the resource view (#2296)
* Added resource view selector button * Showing resource boxes in the resource view * Crude CPU resource view prototype * Improved the viewMode state logic * Extracted zooming into a separate wrapper component * Split the layout selectors between graph-view and resource-view * Proper zooming logic for the resource view * Moved all node networks utils to selectors * Improved the zoom caching logic * Further refactoring of selectors * Added sticky labels to the resource boxes * Added panning translation limits in the resource view * Renamed GridModeSelector -> ViewModeSelector * Polished the topology resource view selection logic * Search bar hidden in the resource view * Added per-layer topology names to the resource view * Made metric selectors work for the resource view * Adjusted the viewport selectors * Renamed viewport selector to canvas (+ maximal zoom fix) * Showing more useful metric info in the resource box labels * Fetching only necessary nodes for the resource view * Refactored the resource view layer component * Addressed first batch UI comments (from the Scope meeting) * Switch to deep zooming transform in the resource view to avoid SVG precision errors * Renamed and moved resource view components * Polished all the resource view components * Changing the available metrics selection * Improved and polished the state transition logic for the resource view * Separated zoom limits from the zoom active state * Renaming and bunch of comments * Addressed all the UI comments (@davkal + @fons) * Made graph view selectors independent from resource view selectors
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
import {
|
||||
doControlRequest,
|
||||
getAllNodes,
|
||||
getResourceViewNodesSnapshot,
|
||||
getNodesDelta,
|
||||
getNodeDetails,
|
||||
getTopologies,
|
||||
@@ -23,7 +24,16 @@ import {
|
||||
import { getCurrentTopologyUrl } from '../utils/topology-utils';
|
||||
import { storageSet } from '../utils/storage-utils';
|
||||
import { loadTheme } from '../utils/contrast-utils';
|
||||
import { activeTopologyOptionsSelector } from '../selectors/topology';
|
||||
import { availableMetricsSelector, pinnedMetricSelector } from '../selectors/node-metric';
|
||||
import {
|
||||
activeTopologyOptionsSelector,
|
||||
isResourceViewModeSelector,
|
||||
} from '../selectors/topology';
|
||||
import {
|
||||
GRAPH_VIEW_MODE,
|
||||
TABLE_VIEW_MODE,
|
||||
RESOURCE_VIEW_MODE,
|
||||
} from '../constants/naming';
|
||||
|
||||
const log = debug('scope:app-actions');
|
||||
|
||||
@@ -141,7 +151,7 @@ export function unpinMetric() {
|
||||
export function pinNextMetric(delta) {
|
||||
return (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const metrics = state.get('availableCanvasMetrics').map(m => m.get('id'));
|
||||
const metrics = availableMetricsSelector(state).map(m => m.get('id'));
|
||||
const currentIndex = metrics.indexOf(state.get('selectedMetric'));
|
||||
const nextIndex = modulo(currentIndex + delta, metrics.count());
|
||||
const nextMetric = metrics.get(nextIndex);
|
||||
@@ -248,25 +258,57 @@ export function clickForceRelayout() {
|
||||
};
|
||||
}
|
||||
|
||||
export function doSearch(searchQuery) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: ActionTypes.DO_SEARCH,
|
||||
searchQuery
|
||||
});
|
||||
updateRoute(getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function setViewportDimensions(width, height) {
|
||||
return (dispatch) => {
|
||||
dispatch({ type: ActionTypes.SET_VIEWPORT_DIMENSIONS, width, height });
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleGridMode(enabledArgument) {
|
||||
export function setGraphView() {
|
||||
return (dispatch, getState) => {
|
||||
const enabled = (enabledArgument === undefined) ?
|
||||
!getState().get('gridMode') :
|
||||
enabledArgument;
|
||||
dispatch({
|
||||
type: ActionTypes.SET_GRID_MODE,
|
||||
enabled
|
||||
type: ActionTypes.SET_VIEW_MODE,
|
||||
viewMode: GRAPH_VIEW_MODE,
|
||||
});
|
||||
updateRoute(getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function setTableView() {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: ActionTypes.SET_VIEW_MODE,
|
||||
viewMode: TABLE_VIEW_MODE,
|
||||
});
|
||||
updateRoute(getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function setResourceView() {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: ActionTypes.SET_VIEW_MODE,
|
||||
viewMode: RESOURCE_VIEW_MODE,
|
||||
});
|
||||
// Pin the first metric if none of the visible ones is pinned.
|
||||
if (!pinnedMetricSelector(getState())) {
|
||||
dispatch({ type: ActionTypes.PIN_METRIC });
|
||||
}
|
||||
getResourceViewNodesSnapshot(getState, dispatch);
|
||||
updateRoute(getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function clickNode(nodeId, label, origin) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({
|
||||
@@ -323,6 +365,25 @@ export function clickResumeUpdate() {
|
||||
};
|
||||
}
|
||||
|
||||
function updateTopology(dispatch, getState) {
|
||||
const state = getState();
|
||||
// If we're in the resource view, get the snapshot of all the relevant node topologies.
|
||||
if (isResourceViewModeSelector(state)) {
|
||||
getResourceViewNodesSnapshot(getState, dispatch);
|
||||
}
|
||||
updateRoute(getState);
|
||||
// update all request workers with new options
|
||||
resetUpdateBuffer();
|
||||
// NOTE: This is currently not needed for our static resource
|
||||
// view, but we'll need it here later and it's simpler to just
|
||||
// keep it than to redo the nodes delta updating logic.
|
||||
getNodesDelta(
|
||||
getCurrentTopologyUrl(state),
|
||||
activeTopologyOptionsSelector(state),
|
||||
dispatch
|
||||
);
|
||||
}
|
||||
|
||||
export function clickShowTopologyForNode(topologyId, nodeId) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({
|
||||
@@ -330,15 +391,7 @@ export function clickShowTopologyForNode(topologyId, nodeId) {
|
||||
topologyId,
|
||||
nodeId
|
||||
});
|
||||
updateRoute(getState);
|
||||
// update all request workers with new options
|
||||
resetUpdateBuffer();
|
||||
const state = getState();
|
||||
getNodesDelta(
|
||||
getCurrentTopologyUrl(state),
|
||||
activeTopologyOptionsSelector(state),
|
||||
dispatch
|
||||
);
|
||||
updateTopology(dispatch, getState);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -348,15 +401,7 @@ export function clickTopology(topologyId) {
|
||||
type: ActionTypes.CLICK_TOPOLOGY,
|
||||
topologyId
|
||||
});
|
||||
updateRoute(getState);
|
||||
// update all request workers with new options
|
||||
resetUpdateBuffer();
|
||||
const state = getState();
|
||||
getNodesDelta(
|
||||
getCurrentTopologyUrl(state),
|
||||
activeTopologyOptionsSelector(state),
|
||||
dispatch
|
||||
);
|
||||
updateTopology(dispatch, getState);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -397,16 +442,6 @@ export function doControl(nodeId, control) {
|
||||
};
|
||||
}
|
||||
|
||||
export function doSearch(searchQuery) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: ActionTypes.DO_SEARCH,
|
||||
searchQuery
|
||||
});
|
||||
updateRoute(getState);
|
||||
};
|
||||
}
|
||||
|
||||
export function enterEdge(edgeId) {
|
||||
return {
|
||||
type: ActionTypes.ENTER_EDGE,
|
||||
@@ -700,6 +735,12 @@ export function route(urlState) {
|
||||
state.get('nodeDetails'),
|
||||
dispatch
|
||||
);
|
||||
// If we are landing on the resource view page, we need to fetch not only all the
|
||||
// nodes for the current topology, but also the nodes of all the topologies that make
|
||||
// the layers in the resource view.
|
||||
if (isResourceViewModeSelector(state)) {
|
||||
getResourceViewNodesSnapshot(getState, dispatch);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user