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:
Filip Barl
2017-03-24 14:51:53 +01:00
committed by GitHub
parent 8814e856e0
commit 69fd397217
50 changed files with 1592 additions and 568 deletions

View File

@@ -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);
}
};
}