diff --git a/client/app/scripts/actions/app-actions.js b/client/app/scripts/actions/app-actions.js index c182e8e2a..2dfb83e68 100644 --- a/client/app/scripts/actions/app-actions.js +++ b/client/app/scripts/actions/app-actions.js @@ -1,15 +1,14 @@ import debug from 'debug'; import trimStart from 'lodash/trimStart'; -import reduce from 'lodash/reduce'; import map from 'lodash/map'; import each from 'lodash/each'; -import { fromJS } from 'immutable'; +import find from 'lodash/find'; import ActionTypes from '../constants/action-types'; import { saveGraph } from '../utils/file-utils'; import { modulo } from '../utils/math-utils'; -import { updateRoute } from '../utils/router-utils'; -import { parseQuery, searchTopology } from '../utils/search-utils'; +import { updateRoute, parseUrlQuery } from '../utils/router-utils'; +import { parseQuery } from '../utils/search-utils'; import { bufferDeltaUpdate, resumeUpdate, resetUpdateBuffer } from '../utils/update-buffer-utils'; import { doControlRequest, getAllNodes, getNodesDelta, getNodeDetails, @@ -17,6 +16,7 @@ import { doControlRequest, getAllNodes, getNodesDelta, getNodeDetails, import { getActiveTopologyOptions, getCurrentTopologyUrl } from '../utils/topology-utils'; import { storageSet } from '../utils/storage-utils'; +import { waterfall } from '../utils/async-utils'; const log = debug('scope:app-actions'); @@ -687,34 +687,9 @@ export function toggleTroubleshootingMenu(ev) { }; } -function convertQueryString(paramString) { - const pairs = trimStart(paramString, '?').split('&'); - return reduce(pairs, (result, pair) => { - const [k, v] = pair.split('='); - result[k] = v; - return result; - }, {}); -} - -function waterfall(series, target, cb) { - function next(result) { - const fn = series.shift(); - if (fn) { - try { - fn(result, next); - } catch (e) { - cb(e); - } - } else { - cb(null, result); - } - } - next(target, next); -} - export function translateUrlParamsToViewState(queryString) { - return () => { - const params = convertQueryString(queryString); + return (dispatch) => { + const params = parseUrlQuery(queryString); if (params.node) { // Get the list of topologies fetch('api/topology').then(response => response.json()) @@ -729,6 +704,7 @@ export function translateUrlParamsToViewState(queryString) { .then((json) => { // Append each node in the list to the result object. each(json.nodes, (node, id) => { + node.topology = topo; result[id] = node; }); cb(result); @@ -738,9 +714,14 @@ export function translateUrlParamsToViewState(queryString) { // Run the series waterfall(series, {}, (err, nodes) => { if (err) { throw err; } - // const collection = flatten(map(r, ({nodes}) => values(nodes))); - const result = searchTopology(fromJS(nodes), { query: params.node }); - console.log(result.toJS()); + const match = find(nodes, n => n.label === params.node); + + if (match) { + dispatch({ + type: ActionTypes.ROUTE_FROM_LINK, + node: match + }); + } }); }); } diff --git a/client/app/scripts/constants/action-types.js b/client/app/scripts/constants/action-types.js index c56f06286..7404e0e77 100644 --- a/client/app/scripts/constants/action-types.js +++ b/client/app/scripts/constants/action-types.js @@ -47,6 +47,7 @@ const ACTION_TYPES = [ 'RECEIVE_ERROR', 'RESET_LOCAL_VIEW_STATE', 'ROUTE_TOPOLOGY', + 'ROUTE_FROM_LINK', 'SELECT_METRIC', 'SHOW_HELP', 'SET_EXPORTING_GRAPH', diff --git a/client/app/scripts/main.dev.js b/client/app/scripts/main.dev.js index bba8e6597..f9f3cec38 100644 --- a/client/app/scripts/main.dev.js +++ b/client/app/scripts/main.dev.js @@ -16,10 +16,15 @@ const store = configureStore(); function renderApp() { const App = require('./components/app').default; - ReactDOM.render(( - + const DevApp = () => ( +
+
+ ); + ReactDOM.render(( + + ), document.getElementById('app')); } diff --git a/client/app/scripts/reducers/root.js b/client/app/scripts/reducers/root.js index 31a1532a9..8b36f4c37 100644 --- a/client/app/scripts/reducers/root.js +++ b/client/app/scripts/reducers/root.js @@ -714,6 +714,19 @@ export function rootReducer(state = initialState, action) { return state.set('showingTroubleshootingMenu', !state.get('showingTroubleshootingMenu')); } + case ActionTypes.ROUTE_FROM_LINK: { + const { id, topology } = action.node; + const topologyId = state.get('topologies').find(t => t.get('name') === topology.name).get('id'); + + state = state.setIn(['nodeDetails', id], { + id, + label: action.node.label, + origin: null, + topologyId, + }); + return state.set('currentTopologyId', topologyId).set('selectedNodeId', id); + } + default: { return state; } diff --git a/client/app/scripts/utils/__tests__/router-utils-test.js b/client/app/scripts/utils/__tests__/router-utils-test.js deleted file mode 100644 index 7cec45988..000000000 --- a/client/app/scripts/utils/__tests__/router-utils-test.js +++ /dev/null @@ -1,14 +0,0 @@ -import { translateUrlParams } from '../router-utils'; - -describe('router-utils', () => { - it('translates a query to a view state', () => { - // const dispatch = createSpy(); - // const state = Object.assign({}, initialState, { - // nodes: [{node_1: 'some_id'}] - // }); - // window.location.search = '?node=node_1'; - // const page = getRouter(dispatch, state); - // expect(page).toBeTruthy(); - translateUrlParams('?key=value&otherkey=othervalue', []); - }); -}); diff --git a/client/app/scripts/utils/async-utils.js b/client/app/scripts/utils/async-utils.js new file mode 100644 index 000000000..d78458f1f --- /dev/null +++ b/client/app/scripts/utils/async-utils.js @@ -0,0 +1,16 @@ + +export function waterfall(series, target, cb) { + function next(result) { + const fn = series.shift(); + if (fn) { + try { + fn(result, next); + } catch (e) { + cb(e); + } + } else { + cb(null, result); + } + } + next(target, next); +} diff --git a/client/app/scripts/utils/router-utils.js b/client/app/scripts/utils/router-utils.js index 9f222641a..73c16be1a 100644 --- a/client/app/scripts/utils/router-utils.js +++ b/client/app/scripts/utils/router-utils.js @@ -1,4 +1,6 @@ import page from 'page'; +import reduce from 'lodash/reduce'; +import trimStart from 'lodash/trimStart'; import { route } from '../actions/app-actions'; import { storageGet, storageSet } from './storage-utils'; @@ -71,7 +73,6 @@ export function updateRoute(getState) { .replace('#!/state/', '') .replace('#!/', '') || '{}'; const prevState = JSON.parse(decodeURL(urlStateString)); - // back up state in storage as well storageSet(STORAGE_STATE_KEY, stateUrl); @@ -86,7 +87,6 @@ export function updateRoute(getState) { export function getRouter(dispatch, initialState) { // strip any trailing '/'s. page.base(window.location.pathname.replace(/\/$/, '')); - page('/', () => { // recover from storage state on empty URL const storageState = storageGet(STORAGE_STATE_KEY); @@ -108,3 +108,12 @@ export function getRouter(dispatch, initialState) { return page; } + +export function parseUrlQuery(queryString) { + const pairs = trimStart(queryString, '?').split('&'); + return reduce(pairs, (result, pair) => { + const [k, v] = pair.split('='); + result[k] = v; + return result; + }, {}); +} diff --git a/client/app/scripts/utils/search-utils.js b/client/app/scripts/utils/search-utils.js index a4c72552b..e136ce19c 100644 --- a/client/app/scripts/utils/search-utils.js +++ b/client/app/scripts/utils/search-utils.js @@ -76,6 +76,7 @@ function findNodeMatch(nodeMatches, keyPath, text, query, prefix, label, truncat {text, label, start: index, length: firstMatch.length, truncate}); } } + return nodeMatches; }