diff --git a/client/app/scripts/components/node-details/__tests__/node-details-health-link-item-test.js b/client/app/scripts/components/node-details/__tests__/node-details-health-link-item-test.js new file mode 100644 index 000000000..f379b2f30 --- /dev/null +++ b/client/app/scripts/components/node-details/__tests__/node-details-health-link-item-test.js @@ -0,0 +1,29 @@ +import moment from 'moment'; + +import { appendTime } from '../node-details-health-link-item'; + + +describe('NodeDetailsHealthLinkItem', () => { + describe('appendTime', () => { + const time = moment.unix(1496275200); + + it('returns url for empty url or time', () => { + expect(appendTime('', time)).toEqual(''); + expect(appendTime('foo', null)).toEqual('foo'); + expect(appendTime('', null)).toEqual(''); + }); + + it('appends as json for cloud link', () => { + const url = appendTime('/prom/:orgid/notebook/new/%7B%22cells%22%3A%5B%7B%22queries%22%3A%5B%22go_goroutines%22%5D%7D%5D%7D', time); + expect(url).toContain(time.unix()); + + const payload = JSON.parse(decodeURIComponent(url.substr(url.indexOf('new/') + 4))); + expect(payload.time.queryEnd).toEqual(time.unix()); + }); + + it('appends as GET parameter', () => { + expect(appendTime('http://example.test?q=foo', time)).toEqual('http://example.test?q=foo&time=1496275200'); + expect(appendTime('http://example.test/q=foo/', time)).toEqual('http://example.test/q=foo/?time=1496275200'); + }); + }); +}); diff --git a/client/app/scripts/components/node-details/node-details-health-link-item.js b/client/app/scripts/components/node-details/node-details-health-link-item.js index 72f1fc6ec..f9084390c 100644 --- a/client/app/scripts/components/node-details/node-details-health-link-item.js +++ b/client/app/scripts/components/node-details/node-details-health-link-item.js @@ -1,4 +1,5 @@ import React from 'react'; +import { connect } from 'react-redux'; import NodeDetailsHealthItem from './node-details-health-item'; import CloudLink from '../cloud-link'; @@ -6,7 +7,37 @@ import { getMetricColor } from '../../utils/metric-utils'; import { darkenColor } from '../../utils/color-utils'; import { trackMixpanelEvent } from '../../utils/tracking-utils'; -export default class NodeDetailsHealthLinkItem extends React.Component { +/** + * @param {string} url + * @param {Moment} time + * @returns {string} + */ +export function appendTime(url, time) { + if (!url || !time) return url; + + // rudimentary check whether we have a cloud link + const cloudLinkPathEnd = 'notebook/new/'; + const pos = url.indexOf(cloudLinkPathEnd); + if (pos !== -1) { + let payload; + const json = decodeURIComponent(url.substr(pos + cloudLinkPathEnd.length)); + try { + payload = JSON.parse(json); + payload.time = { queryEnd: time.unix() }; + } catch (e) { + return url; + } + + return `${url.substr(0, pos + cloudLinkPathEnd.length)}${encodeURIComponent(JSON.stringify(payload) || '')}`; + } + + if (url.indexOf('?') !== -1) { + return `${url}&time=${time.unix()}`; + } + return `${url}?time=${time.unix()}`; +} + +class NodeDetailsHealthLinkItem extends React.Component { constructor(props) { super(props); @@ -32,10 +63,12 @@ export default class NodeDetailsHealthLinkItem extends React.Component { } render() { - const { id, url, ...props } = this.props; + const { id, url, pausedAt, ...props } = this.props; const metricColor = getMetricColor(id); const labelColor = this.state.hovered && !props.valueEmpty && darkenColor(metricColor); + const timedUrl = appendTime(url, pausedAt); + return (