From f5b034c98c32ffa1a7d41699310ed866dd79b01c Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Wed, 13 Sep 2017 10:41:39 -0700 Subject: [PATCH 01/34] WIP Introduce SourceSelector component --- .../components/CellEditorOverlay.js | 4 +++ .../dashboards/components/DisplayOptions.js | 25 ++++++++++++------- .../dashboards/components/SourceSelector.js | 23 +++++++++++++++++ ui/src/dashboards/containers/DashboardPage.js | 6 +++++ .../style/components/ceo-display-options.scss | 2 -- 5 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 ui/src/dashboards/components/SourceSelector.js diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index 12e877dcb6..113817a28f 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -224,6 +224,7 @@ class CellEditorOverlay extends Component { render() { const { source, + sources, onCancel, templates, timeRange, @@ -280,6 +281,8 @@ class CellEditorOverlay extends Component { {isDisplayOptionsTabActive ? ({...s, text: s.name})) + render() { const { onSetBase, @@ -46,15 +49,18 @@ class DisplayOptions extends Component { return (
- +
+ + +
+
+
Source Selector
+
+ {}} + items={sources} + selected={sources[0].text} + /> +
+
+ +const {arrayOf, shape} = PropTypes + +SourceSelector.propTypes = { + sources: arrayOf(shape()).isRequired, +} + +export default SourceSelector diff --git a/ui/src/dashboards/containers/DashboardPage.js b/ui/src/dashboards/containers/DashboardPage.js index 18b9a2c447..0236d0ee21 100644 --- a/ui/src/dashboards/containers/DashboardPage.js +++ b/ui/src/dashboards/containers/DashboardPage.js @@ -190,6 +190,7 @@ class DashboardPage extends Component { const { source, + sources, timeRange, timeRange: {lower, upper}, showTemplateControlBar, @@ -277,6 +278,7 @@ class DashboardPage extends Component { {selectedCell ? { @@ -415,6 +419,7 @@ const mapStateToProps = state => { persisted: {autoRefresh, showTemplateControlBar}, }, dashboardUI: {dashboards, timeRange, cellQueryStatus}, + sources, } = state return { @@ -424,6 +429,7 @@ const mapStateToProps = state => { showTemplateControlBar, inPresentationMode, cellQueryStatus, + sources, } } diff --git a/ui/src/style/components/ceo-display-options.scss b/ui/src/style/components/ceo-display-options.scss index 94c707337f..2d47f22d48 100644 --- a/ui/src/style/components/ceo-display-options.scss +++ b/ui/src/style/components/ceo-display-options.scss @@ -17,8 +17,6 @@ padding: 30px; flex: 1 0 0; margin-right: 8px; - - &:last-child { margin-right: 0; } } .display-options--cellx2 { flex: 2 0 0; From af031f8e40d3ba2c817a569b2e80eb4fdb2b3c2c Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Wed, 13 Sep 2017 14:24:30 -0700 Subject: [PATCH 02/34] WIP Add some styles to SourceSelector --- ui/src/dashboards/components/AxesOptions.js | 2 +- .../dashboards/components/DisplayOptions.js | 35 +++++++++++++++++-- .../dashboards/components/SourceSelector.js | 22 ++++++++---- ui/src/shared/components/Dropdown.js | 8 ++++- .../style/components/ceo-display-options.scss | 8 +++-- 5 files changed, 62 insertions(+), 13 deletions(-) diff --git a/ui/src/dashboards/components/AxesOptions.js b/ui/src/dashboards/components/AxesOptions.js index bcdd746e12..d44640ea78 100644 --- a/ui/src/dashboards/components/AxesOptions.js +++ b/ui/src/dashboards/components/AxesOptions.js @@ -19,7 +19,7 @@ const AxesOptions = ({ const [min, max] = bounds return ( -
+
Y Axis Controls
diff --git a/ui/src/dashboards/components/DisplayOptions.js b/ui/src/dashboards/components/DisplayOptions.js index f4db8a2ee4..13421d544b 100644 --- a/ui/src/dashboards/components/DisplayOptions.js +++ b/ui/src/dashboards/components/DisplayOptions.js @@ -32,10 +32,38 @@ class DisplayOptions extends Component { : axes } - formatSources = this.props.sources.map(s => ({...s, text: s.name})) + dummySources = () => { + let dummies = [] + for (let i = 2; i < 13; i++) { + const id = 1 + i + dummies = [ + ...dummies, + { + id, + name: `dummyFlux ${i}`, + type: 'influx', + username: '', + url: `http://9X.se3ShredURL02x6tall1sStartURL16enlargedj216stretching1fganglingeexpanded1lankydeep4434longishsustained6EzURLTightURL30URLPieShrinkrwtoweringalankyPiURLr4qSHurl0prolongedloftyprotracted00greatd0Dwarfurl83runningcUrlTea1Redirx30Dwarfurl13a1lnk.in74nu1z106p6011lanky0Shrtndenduring1URl.iebkelongateShredURLi1dlastinglengthenedU7618ShrinkrDecentURLk2longishShrtndelongateds1U76MyURLsSitelutions000toweringShoterLinka1462Fly217ooexpanded1080B6541continuedstretched0U760elongated3Shrtnd301URL4SHurlganglingx07ShoterLinkrangywYATUC1719Is.gdURLvi3ShortURLv0a8stretchingprotractedc2URLcut0ganglingUlimit51DigBig16q3Redirx1l16c0010farawayYATUC0t1stretch0remote91b0bfaraway0elongate59URLvi4lnk.in841SimURLDwarfurlr32towering701Doiop07311a5825lastingz0918TinyLinkenlargedexpanded30CanURLUlimits105d33f0y6172Sitelutions3lengthened6longishShredURLk20a17x04ShrinkURLprotractedv3drawn%2Boutm6greatvXilXil58ShortURL9f1d16protracteddistant780151enlargedv6301URLsustainedspread%2Boutl00c38URLPie7gangling8035s08s131f8i0Ulimit0nTinyLink9elongatedlasting908deeplengthy0lanky116TraceURL7ax0m6ShrinkURLo1llastingShrinkURLCanURLm060great1TinyLink0561f19MyURL4370Fly21d2drawn%2Bout0stretchedenduring1113011026cURLvijenduringShortenURL18GetShortyShrinkr56e8y416URL7spread%2Bout7ocURLHawk5cahighDwarfurl1elongate4efcURL.co.ukz73Ulimit1RubyURLi7lnk.inDigBigdeep97protractedg58WapURL0761YepIt77esustainedremote452e461sustained9U76NanoRefjPiURL5enduring0X.seorSitelutions111stringyU76CanURL9Shrtnd9stringyBeam.toemSHurlgreatc0e011hremote162lengthenedstretchlengthy1506U76xrangy0Fly210tb3111eiURLCuttera1stringy5gangling0Shortlinksgangling10loftyc00A2Nd1MyURL1drawn%2Bouty5SmallrtURLCutterDigBig00g8Metamarkrunningre04prolonged4EasyURLfURl.ieUrlTeatoweringSnipURLjbr0191b170wextensiveMooURL1Shorl932U76spun%2Bout6tall2i0DoiopwlankyURLHawkq6EzURL921uURLHawkehcspread%2Bout11g10krunningystretching08oDecentURL16279Xil3stringy1l6321URLcutShrtndeuelongate1010lastingexpanded5ShrinkrMyURLstretching5drawn%2Bout50distant40faraway24elongate7nstretchinggreat7delongated1SnipURL301URL74e69ttallf1A2N31${i}`, + default: false, + telegraf: 'telegraf', + links: { + self: `/chronograf/v1/sources/${i}`, + }, + }, + ] + } + + return dummies + } + + formatSources = [...this.props.sources, ...this.dummySources()].map(s => ({ + ...s, + text: `${s.name} @ ${s.url}`, + })) render() { const { + source, onSetBase, onSetScale, onSetLabel, @@ -49,7 +77,7 @@ class DisplayOptions extends Component { return (
-
+
- +
{} -const SourceSelector = ({sources = []}) => +const SourceSelector = ({sources = [], source}) =>
-
Source Selector
-
+
InfluxDB Source Selector
+
+ {}} items={sources} - selected={sources[0].text} + buttonSize="btn-sm" + menuClass="dropdown-astronaut" + useAutoComplete={true} + selected={sources.find(s => s.id === source.id).text || '(No values)'} + onChoose={noop} + toggleStyle={{width: '75%'}} />
@@ -18,6 +27,7 @@ const {arrayOf, shape} = PropTypes SourceSelector.propTypes = { sources: arrayOf(shape()).isRequired, + source: shape({}).isRequired, } export default SourceSelector diff --git a/ui/src/shared/components/Dropdown.js b/ui/src/shared/components/Dropdown.js index 605bc62733..92efa21028 100644 --- a/ui/src/shared/components/Dropdown.js +++ b/ui/src/shared/components/Dropdown.js @@ -206,6 +206,7 @@ class Dropdown extends Component { iconName, buttonSize, buttonColor, + toggleStyle, useAutoComplete, } = this.props const {isOpen, searchTerm, filteredItems} = this.state @@ -222,6 +223,7 @@ class Dropdown extends Component { {useAutoComplete && isOpen ?
- :
+ :
{iconName ? : null} @@ -291,6 +296,7 @@ Dropdown.propTypes = { menuLabel: string, menuClass: string, useAutoComplete: bool, + toggleStyle: shape(), } export default OnClickOutside(Dropdown) diff --git a/ui/src/style/components/ceo-display-options.scss b/ui/src/style/components/ceo-display-options.scss index 2d47f22d48..3ccf6c450f 100644 --- a/ui/src/style/components/ceo-display-options.scss +++ b/ui/src/style/components/ceo-display-options.scss @@ -27,8 +27,12 @@ color: $g11-sidewalk; @include no-user-select(); } - - +.y-axis-controls { + margin-bottom: 8px; +} +.source-selector--dropdown { + width: 50%; +} .viz-type-selector { display: flex; flex-wrap: wrap; From f720c997e7b3acedbde4f0109daf213f294c9b5d Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Wed, 13 Sep 2017 14:57:19 -0700 Subject: [PATCH 03/34] Tweak styles --- ui/src/dashboards/components/SourceSelector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/dashboards/components/SourceSelector.js b/ui/src/dashboards/components/SourceSelector.js index 1d88dfbc4f..616782e11c 100644 --- a/ui/src/dashboards/components/SourceSelector.js +++ b/ui/src/dashboards/components/SourceSelector.js @@ -18,7 +18,7 @@ const SourceSelector = ({sources = [], source}) => useAutoComplete={true} selected={sources.find(s => s.id === source.id).text || '(No values)'} onChoose={noop} - toggleStyle={{width: '75%'}} + toggleStyle={{width: '50%'}} />
From c40380a6c48421bc802cb17ba72bd29635ef2f96 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Wed, 13 Sep 2017 15:36:54 -0700 Subject: [PATCH 04/34] WIP store seleted cellSource on state --- ui/src/dashboards/components/CellEditorOverlay.js | 12 ++++++++++-- ui/src/dashboards/components/DisplayOptions.js | 15 ++++++++++++++- ui/src/dashboards/components/SourceSelector.js | 15 +++++++-------- ui/src/style/components/ceo-display-options.scss | 3 --- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index 113817a28f..7959bba2fb 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -23,7 +23,7 @@ class CellEditorOverlay extends Component { constructor(props) { super(props) - const {cell: {name, type, queries, axes}} = props + const {cell: {name, type, queries, axes, source}} = props const queriesWorkingDraft = _.cloneDeep( queries.map(({queryConfig}) => ({...queryConfig, id: uuid.v4()})) @@ -35,6 +35,7 @@ class CellEditorOverlay extends Component { queriesWorkingDraft, activeQueryIndex: 0, isDisplayOptionsTabActive: false, + cellSource: source, axes, } } @@ -197,6 +198,10 @@ class CellEditorOverlay extends Component { }) } + handleSetCellSource = cellSource => { + this.setState({cellSource}) + } + getActiveQuery = () => { const {queriesWorkingDraft, activeQueryIndex} = this.state const activeQuery = queriesWorkingDraft[activeQueryIndex] @@ -233,12 +238,13 @@ class CellEditorOverlay extends Component { } = this.props const { + axes, + cellSource, activeQueryIndex, cellWorkingName, cellWorkingType, isDisplayOptionsTabActive, queriesWorkingDraft, - axes, } = this.state const queryActions = { @@ -283,11 +289,13 @@ class CellEditorOverlay extends Component { axes={axes} source={source} sources={sources} + cellSource={cellSource} onSetBase={this.handleSetBase} onSetLabel={this.handleSetLabel} onSetScale={this.handleSetScale} queryConfigs={queriesWorkingDraft} selectedGraphType={cellWorkingType} + onSetCellSource={this.handleSetCellSource} onSetPrefixSuffix={this.handleSetPrefixSuffix} onSelectGraphType={this.handleSelectGraphType} onSetYAxisBoundMin={this.handleSetYAxisBoundMin} diff --git a/ui/src/dashboards/components/DisplayOptions.js b/ui/src/dashboards/components/DisplayOptions.js index 13421d544b..18b8f3e7f5 100644 --- a/ui/src/dashboards/components/DisplayOptions.js +++ b/ui/src/dashboards/components/DisplayOptions.js @@ -61,12 +61,19 @@ class DisplayOptions extends Component { text: `${s.name} @ ${s.url}`, })) + findSelectedSource = ({id}) => { + const selected = this.formatSources.find(s => s.id === id) + return (selected && selected.text) || 'No sources' + } + render() { const { source, onSetBase, onSetScale, onSetLabel, + cellSource, + onSetCellSource, selectedGraphType, onSelectGraphType, onSetPrefixSuffix, @@ -87,7 +94,11 @@ class DisplayOptions extends Component { onSetYAxisBoundMin={onSetYAxisBoundMin} onSetYAxisBoundMax={onSetYAxisBoundMax} /> - +
{} - -const SourceSelector = ({sources = [], source}) => +const SourceSelector = ({sources = [], selected, onSetCellSource}) =>
InfluxDB Source Selector
buttonSize="btn-sm" menuClass="dropdown-astronaut" useAutoComplete={true} - selected={sources.find(s => s.id === source.id).text || '(No values)'} - onChoose={noop} - toggleStyle={{width: '50%'}} + selected={selected} + onChoose={onSetCellSource} + toggleStyle={{width: '50%', maxWidth: '300px'}} />
-const {arrayOf, shape} = PropTypes +const {arrayOf, func, shape, string} = PropTypes SourceSelector.propTypes = { sources: arrayOf(shape()).isRequired, - source: shape({}).isRequired, + onSetCellSource: func.isRequired, + selected: string, } export default SourceSelector diff --git a/ui/src/style/components/ceo-display-options.scss b/ui/src/style/components/ceo-display-options.scss index 3ccf6c450f..e0abc0a2fe 100644 --- a/ui/src/style/components/ceo-display-options.scss +++ b/ui/src/style/components/ceo-display-options.scss @@ -30,9 +30,6 @@ .y-axis-controls { margin-bottom: 8px; } -.source-selector--dropdown { - width: 50%; -} .viz-type-selector { display: flex; flex-wrap: wrap; From a0cb2d81f70242506485fcedbb5c1c558b39cecf Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Wed, 13 Sep 2017 15:53:18 -0700 Subject: [PATCH 05/34] Use default source if cellSource isnt in sources list --- .../dashboards/components/DisplayOptions.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/ui/src/dashboards/components/DisplayOptions.js b/ui/src/dashboards/components/DisplayOptions.js index 18b8f3e7f5..2c369a8763 100644 --- a/ui/src/dashboards/components/DisplayOptions.js +++ b/ui/src/dashboards/components/DisplayOptions.js @@ -61,18 +61,27 @@ class DisplayOptions extends Component { text: `${s.name} @ ${s.url}`, })) - findSelectedSource = ({id}) => { - const selected = this.formatSources.find(s => s.id === id) + findSelectedSource = () => { + const {cellSource, source: defaultSource} = this.props + const sources = this.formatSources + const cellSourceID = cellSource && cellSource.id + + let selected + selected = sources.find(s => s.id === cellSourceID) + + if (selected) { + return selected.text + } + + selected = sources.find(s => s.id === defaultSource.id) return (selected && selected.text) || 'No sources' } render() { const { - source, onSetBase, onSetScale, onSetLabel, - cellSource, onSetCellSource, selectedGraphType, onSelectGraphType, @@ -97,7 +106,7 @@ class DisplayOptions extends Component {
Date: Thu, 14 Sep 2017 13:13:47 -0500 Subject: [PATCH 06/34] Update dashboard cells to have optional data source URI. --- bolt/internal/internal.go | 2 + bolt/internal/internal.pb.go | 130 +++++++++++++++++---------------- bolt/internal/internal.proto | 1 + bolt/internal/internal_test.go | 1 + chronograf.go | 1 + server/dashboards_test.go | 4 + server/swagger.json | 5 ++ 7 files changed, 81 insertions(+), 63 deletions(-) diff --git a/bolt/internal/internal.go b/bolt/internal/internal.go index ca6df1827f..8d79dde745 100644 --- a/bolt/internal/internal.go +++ b/bolt/internal/internal.go @@ -195,6 +195,7 @@ func MarshalDashboard(d chronograf.Dashboard) ([]byte, error) { Command: q.Command, Label: q.Label, Range: r, + Source: q.Source, } } @@ -274,6 +275,7 @@ func UnmarshalDashboard(data []byte, d *chronograf.Dashboard) error { queries[j] = chronograf.DashboardQuery{ Command: q.Command, Label: q.Label, + Source: q.Source, } if q.Range.Upper != q.Range.Lower { queries[j].Range = &chronograf.Range{ diff --git a/bolt/internal/internal.pb.go b/bolt/internal/internal.pb.go index 4af4f8fd04..02d757fdc9 100644 --- a/bolt/internal/internal.pb.go +++ b/bolt/internal/internal.pb.go @@ -261,6 +261,7 @@ type Query struct { Wheres []string `protobuf:"bytes,5,rep,name=Wheres" json:"Wheres,omitempty"` Label string `protobuf:"bytes,6,opt,name=Label,proto3" json:"Label,omitempty"` Range *Range `protobuf:"bytes,7,opt,name=Range" json:"Range,omitempty"` + Source string `protobuf:"bytes,8,opt,name=Source,proto3" json:"Source,omitempty"` } func (m *Query) Reset() { *m = Query{} } @@ -327,67 +328,70 @@ func init() { func init() { proto.RegisterFile("internal.proto", fileDescriptorInternal) } var fileDescriptorInternal = []byte{ - // 985 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6e, 0x23, 0x45, - 0x10, 0x56, 0xcf, 0x8f, 0xed, 0x29, 0x67, 0x03, 0x6a, 0xad, 0xd8, 0x61, 0xb9, 0x98, 0x11, 0x48, - 0x06, 0x41, 0x40, 0xbb, 0x42, 0x42, 0xdc, 0x9c, 0x18, 0xad, 0x42, 0xb2, 0x4b, 0x68, 0x27, 0x81, - 0x0b, 0x5a, 0xb5, 0xc7, 0x95, 0x64, 0xb4, 0x63, 0xcf, 0xd0, 0x33, 0x13, 0x7b, 0xde, 0x82, 0x27, - 0x40, 0x42, 0xe2, 0xc4, 0x81, 0x03, 0x2f, 0xc0, 0x9d, 0xa7, 0x42, 0xd5, 0xdd, 0x33, 0x1e, 0xb3, - 0x59, 0xb4, 0x17, 0xf6, 0xd6, 0x5f, 0x55, 0xbb, 0xba, 0xe6, 0xab, 0xfa, 0x3e, 0x19, 0xf6, 0x93, - 0x55, 0x89, 0x6a, 0x25, 0xd3, 0x83, 0x5c, 0x65, 0x65, 0xc6, 0x07, 0x0d, 0x8e, 0xfe, 0x70, 0xa0, - 0x37, 0xcb, 0x2a, 0x15, 0x23, 0xdf, 0x07, 0xe7, 0x78, 0x1a, 0xb2, 0x11, 0x1b, 0xbb, 0xc2, 0x39, - 0x9e, 0x72, 0x0e, 0xde, 0x33, 0xb9, 0xc4, 0xd0, 0x19, 0xb1, 0x71, 0x20, 0xf4, 0x99, 0x62, 0xe7, - 0x75, 0x8e, 0xa1, 0x6b, 0x62, 0x74, 0xe6, 0x0f, 0x61, 0x70, 0x51, 0x50, 0xb5, 0x25, 0x86, 0x9e, - 0x8e, 0xb7, 0x98, 0x72, 0x67, 0xb2, 0x28, 0xd6, 0x99, 0x5a, 0x84, 0xbe, 0xc9, 0x35, 0x98, 0xbf, - 0x0d, 0xee, 0x85, 0x38, 0x0d, 0x7b, 0x3a, 0x4c, 0x47, 0x1e, 0x42, 0x7f, 0x8a, 0x57, 0xb2, 0x4a, - 0xcb, 0xb0, 0x3f, 0x62, 0xe3, 0x81, 0x68, 0x20, 0xd5, 0x39, 0xc7, 0x14, 0xaf, 0x95, 0xbc, 0x0a, - 0x07, 0xa6, 0x4e, 0x83, 0xf9, 0x01, 0xf0, 0xe3, 0x55, 0x81, 0x71, 0xa5, 0x70, 0xf6, 0x22, 0xc9, - 0x2f, 0x51, 0x25, 0x57, 0x75, 0x18, 0xe8, 0x02, 0x77, 0x64, 0xe8, 0x95, 0xa7, 0x58, 0x4a, 0x7a, - 0x1b, 0x74, 0xa9, 0x06, 0xf2, 0x08, 0xf6, 0x66, 0x37, 0x52, 0xe1, 0x62, 0x86, 0xb1, 0xc2, 0x32, - 0x1c, 0xea, 0xf4, 0x4e, 0x2c, 0xfa, 0x99, 0x41, 0x30, 0x95, 0xc5, 0xcd, 0x3c, 0x93, 0x6a, 0xf1, - 0x5a, 0x9c, 0x7d, 0x0a, 0x7e, 0x8c, 0x69, 0x5a, 0x84, 0xee, 0xc8, 0x1d, 0x0f, 0x1f, 0x3d, 0x38, - 0x68, 0x87, 0xd1, 0xd6, 0x39, 0xc2, 0x34, 0x15, 0xe6, 0x16, 0xff, 0x1c, 0x82, 0x12, 0x97, 0x79, - 0x2a, 0x4b, 0x2c, 0x42, 0x4f, 0xff, 0x84, 0x6f, 0x7f, 0x72, 0x6e, 0x53, 0x62, 0x7b, 0x29, 0xfa, - 0xdd, 0x81, 0x7b, 0x3b, 0xa5, 0xf8, 0x1e, 0xb0, 0x8d, 0xee, 0xca, 0x17, 0x6c, 0x43, 0xa8, 0xd6, - 0x1d, 0xf9, 0x82, 0xd5, 0x84, 0xd6, 0x7a, 0x7e, 0xbe, 0x60, 0x6b, 0x42, 0x37, 0x7a, 0x6a, 0xbe, - 0x60, 0x37, 0xfc, 0x23, 0xe8, 0xff, 0x54, 0xa1, 0x4a, 0xb0, 0x08, 0x7d, 0xfd, 0xf2, 0x5b, 0xdb, - 0x97, 0xbf, 0xab, 0x50, 0xd5, 0xa2, 0xc9, 0xd3, 0x97, 0xea, 0x89, 0x9b, 0xf1, 0xe9, 0x33, 0xc5, - 0x4a, 0xda, 0x8e, 0xbe, 0x89, 0xd1, 0xd9, 0x32, 0x64, 0x66, 0x46, 0x0c, 0x7d, 0x01, 0x9e, 0xdc, - 0x60, 0x11, 0x06, 0xba, 0xfe, 0xfb, 0xaf, 0x20, 0xe3, 0x60, 0xb2, 0xc1, 0xe2, 0xeb, 0x55, 0xa9, - 0x6a, 0xa1, 0xaf, 0x3f, 0x7c, 0x02, 0x41, 0x1b, 0xa2, 0xcd, 0x79, 0x81, 0xb5, 0xfe, 0xc0, 0x40, - 0xd0, 0x91, 0x7f, 0x00, 0xfe, 0xad, 0x4c, 0x2b, 0x43, 0xfc, 0xf0, 0xd1, 0xfe, 0xb6, 0xec, 0x64, - 0x93, 0x14, 0xc2, 0x24, 0xbf, 0x72, 0xbe, 0x64, 0xd1, 0x0f, 0xe0, 0x51, 0x88, 0x66, 0x9d, 0xe2, - 0xb5, 0x8c, 0xeb, 0xc3, 0xac, 0x5a, 0x2d, 0x8a, 0x90, 0x8d, 0xdc, 0xb1, 0x2b, 0x76, 0x62, 0xfc, - 0x1d, 0xe8, 0xcd, 0x4d, 0xd6, 0x19, 0xb9, 0xe3, 0x40, 0x58, 0xc4, 0xef, 0x83, 0x9f, 0xca, 0x39, - 0xa6, 0x56, 0x06, 0x06, 0x44, 0x7f, 0x31, 0x5a, 0x52, 0x33, 0x94, 0xce, 0x62, 0x98, 0xcf, 0x7e, - 0x17, 0x06, 0x34, 0xb0, 0xe7, 0xb7, 0x52, 0xd9, 0xe5, 0xe8, 0x13, 0xbe, 0x94, 0x8a, 0x7f, 0x06, - 0x3d, 0xdd, 0xde, 0x1d, 0x0b, 0xd2, 0x94, 0xbb, 0xa4, 0xbc, 0xb0, 0xd7, 0x5a, 0x9a, 0xbd, 0x0e, - 0xcd, 0x6d, 0x4b, 0x7e, 0xa7, 0x25, 0x5a, 0x3d, 0x9a, 0x57, 0xad, 0xa7, 0x74, 0x67, 0x65, 0x33, - 0x55, 0x73, 0x2b, 0xba, 0x80, 0x7b, 0x3b, 0x2f, 0xb6, 0x2f, 0xb1, 0xdd, 0x97, 0xb6, 0x54, 0x07, - 0x96, 0x5a, 0x12, 0x68, 0x81, 0x29, 0xc6, 0x25, 0x2e, 0x34, 0x2b, 0x03, 0xd1, 0xe2, 0xe8, 0x57, - 0xb6, 0xad, 0xab, 0xdf, 0x23, 0x09, 0xc6, 0xd9, 0x72, 0x29, 0x57, 0x0b, 0x5b, 0xba, 0x81, 0xc4, - 0xdb, 0x62, 0x6e, 0x4b, 0x3b, 0x8b, 0x39, 0x61, 0x95, 0x5b, 0x9e, 0x1d, 0x95, 0xf3, 0x11, 0x0c, - 0x97, 0x28, 0x8b, 0x4a, 0xe1, 0x12, 0x57, 0xa5, 0xa5, 0xa0, 0x1b, 0xe2, 0x0f, 0xa0, 0x5f, 0xca, - 0xeb, 0xe7, 0xb4, 0x20, 0x86, 0x8b, 0x5e, 0x29, 0xaf, 0x4f, 0xb0, 0xe6, 0xef, 0x41, 0x70, 0x95, - 0x60, 0xba, 0xd0, 0x29, 0xb3, 0xb6, 0x03, 0x1d, 0x38, 0xc1, 0x3a, 0xfa, 0x8d, 0x41, 0x6f, 0x86, - 0xea, 0x16, 0xd5, 0x6b, 0x69, 0xba, 0xeb, 0x79, 0xee, 0x7f, 0x78, 0x9e, 0x77, 0xb7, 0xe7, 0xf9, - 0x5b, 0xcf, 0xbb, 0x0f, 0xfe, 0x4c, 0xc5, 0xc7, 0x53, 0xdd, 0x91, 0x2b, 0x0c, 0xa0, 0xcd, 0x9b, - 0xc4, 0x65, 0x72, 0x8b, 0xd6, 0x08, 0x2d, 0x8a, 0x7e, 0x61, 0xd0, 0x3b, 0x95, 0x75, 0x56, 0x95, - 0x2f, 0x6d, 0xd8, 0x08, 0x86, 0x93, 0x3c, 0x4f, 0x93, 0x58, 0x96, 0x49, 0xb6, 0xb2, 0xdd, 0x76, - 0x43, 0x74, 0xe3, 0x69, 0x87, 0x3b, 0xd3, 0x77, 0x37, 0x44, 0x32, 0x3a, 0xd2, 0x56, 0x65, 0x7c, - 0xa7, 0x23, 0x23, 0xe3, 0x50, 0x3a, 0x49, 0x1f, 0x38, 0xa9, 0xca, 0xec, 0x2a, 0xcd, 0xd6, 0xfa, - 0x4b, 0x06, 0xa2, 0xc5, 0xd1, 0xdf, 0x0e, 0x78, 0x6f, 0xca, 0x82, 0xf6, 0x80, 0x25, 0x76, 0x90, - 0x2c, 0x69, 0x0d, 0xa9, 0xdf, 0x31, 0xa4, 0x10, 0xfa, 0xb5, 0x92, 0xab, 0x6b, 0x2c, 0xc2, 0x81, - 0xd6, 0x77, 0x03, 0x75, 0x46, 0x6b, 0xc4, 0x38, 0x51, 0x20, 0x1a, 0xd8, 0xee, 0x3c, 0x74, 0x76, - 0xfe, 0x13, 0x6b, 0x5a, 0x43, 0xdd, 0x51, 0xb8, 0x4b, 0xcb, 0xff, 0xe7, 0x55, 0x7f, 0x32, 0xf0, - 0x5b, 0xc1, 0x1c, 0xed, 0x0a, 0xe6, 0x68, 0x2b, 0x98, 0xe9, 0x61, 0x23, 0x98, 0xe9, 0x21, 0x61, - 0x71, 0xd6, 0x08, 0x46, 0x9c, 0xd1, 0xb0, 0x9e, 0xa8, 0xac, 0xca, 0x0f, 0x6b, 0x33, 0xd5, 0x40, - 0xb4, 0x98, 0xb6, 0xec, 0xfb, 0x1b, 0x54, 0x96, 0xea, 0x40, 0x58, 0x44, 0x3b, 0x79, 0xaa, 0xcd, - 0xc4, 0x90, 0x6b, 0x00, 0xff, 0x10, 0x7c, 0x41, 0xe4, 0x69, 0x86, 0x77, 0xe6, 0xa2, 0xc3, 0xc2, - 0x64, 0xa3, 0xc7, 0xf6, 0x1a, 0x55, 0xb9, 0xc8, 0x73, 0x54, 0x56, 0x4a, 0x06, 0xe8, 0xda, 0xd9, - 0x1a, 0x8d, 0x0b, 0xba, 0xc2, 0x80, 0xe8, 0x47, 0x08, 0x26, 0x29, 0xaa, 0x52, 0x54, 0xe9, 0xcb, - 0xde, 0xc9, 0xc1, 0xfb, 0x66, 0xf6, 0xed, 0xb3, 0x46, 0x80, 0x74, 0xde, 0xca, 0xc6, 0xfd, 0x97, - 0x6c, 0x4e, 0x64, 0x2e, 0x8f, 0xa7, 0x7a, 0x9f, 0x5c, 0x61, 0x51, 0xf4, 0x31, 0x78, 0x24, 0xcf, - 0x4e, 0x65, 0xef, 0x55, 0xd2, 0x9e, 0xf7, 0xf4, 0x5f, 0xa4, 0xc7, 0xff, 0x04, 0x00, 0x00, 0xff, - 0xff, 0x5a, 0xf0, 0x92, 0xd4, 0x34, 0x09, 0x00, 0x00, + // 1028 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0xd7, 0xf8, 0x4f, 0x12, 0xbf, 0x74, 0x0b, 0x1a, 0xad, 0x58, 0xb3, 0x5c, 0x82, 0x05, 0x52, + 0x40, 0x6c, 0x41, 0xbb, 0x42, 0x42, 0xdc, 0xd2, 0x06, 0xad, 0x4a, 0xbb, 0x4b, 0x99, 0xb4, 0xe5, + 0x84, 0x56, 0x13, 0xe7, 0xa5, 0xb5, 0xd6, 0x89, 0xcd, 0xd8, 0x6e, 0xe3, 0x6f, 0xc1, 0x27, 0x40, + 0x42, 0xe2, 0xc4, 0x81, 0x03, 0x5f, 0x80, 0xfb, 0x7e, 0x2a, 0xf4, 0x66, 0xc6, 0x8e, 0xc3, 0x76, + 0xd1, 0x5e, 0xe0, 0x36, 0xbf, 0xf7, 0xc6, 0x6f, 0x66, 0xde, 0xef, 0xfd, 0x7e, 0x09, 0xec, 0x27, + 0xeb, 0x12, 0xd5, 0x5a, 0xa6, 0x07, 0xb9, 0xca, 0xca, 0x8c, 0x0f, 0x1a, 0x1c, 0xfd, 0xe1, 0x40, + 0x6f, 0x96, 0x55, 0x2a, 0x46, 0xbe, 0x0f, 0xce, 0xf1, 0x34, 0x64, 0x23, 0x36, 0x76, 0x85, 0x73, + 0x3c, 0xe5, 0x1c, 0xbc, 0xe7, 0x72, 0x85, 0xa1, 0x33, 0x62, 0xe3, 0x40, 0xe8, 0x35, 0xc5, 0xce, + 0xeb, 0x1c, 0x43, 0xd7, 0xc4, 0x68, 0xcd, 0x1f, 0xc2, 0xe0, 0xa2, 0xa0, 0x6a, 0x2b, 0x0c, 0x3d, + 0x1d, 0x6f, 0x31, 0xe5, 0xce, 0x64, 0x51, 0xdc, 0x66, 0x6a, 0x11, 0xfa, 0x26, 0xd7, 0x60, 0xfe, + 0x2e, 0xb8, 0x17, 0xe2, 0x34, 0xec, 0xe9, 0x30, 0x2d, 0x79, 0x08, 0xfd, 0x29, 0x2e, 0x65, 0x95, + 0x96, 0x61, 0x7f, 0xc4, 0xc6, 0x03, 0xd1, 0x40, 0xaa, 0x73, 0x8e, 0x29, 0x5e, 0x29, 0xb9, 0x0c, + 0x07, 0xa6, 0x4e, 0x83, 0xf9, 0x01, 0xf0, 0xe3, 0x75, 0x81, 0x71, 0xa5, 0x70, 0xf6, 0x32, 0xc9, + 0x2f, 0x51, 0x25, 0xcb, 0x3a, 0x0c, 0x74, 0x81, 0x3b, 0x32, 0x74, 0xca, 0x33, 0x2c, 0x25, 0x9d, + 0x0d, 0xba, 0x54, 0x03, 0x79, 0x04, 0x7b, 0xb3, 0x6b, 0xa9, 0x70, 0x31, 0xc3, 0x58, 0x61, 0x19, + 0x0e, 0x75, 0x7a, 0x27, 0x16, 0xfd, 0xcc, 0x20, 0x98, 0xca, 0xe2, 0x7a, 0x9e, 0x49, 0xb5, 0x78, + 0xab, 0x9e, 0x3d, 0x02, 0x3f, 0xc6, 0x34, 0x2d, 0x42, 0x77, 0xe4, 0x8e, 0x87, 0x8f, 0x1f, 0x1c, + 0xb4, 0x64, 0xb4, 0x75, 0x8e, 0x30, 0x4d, 0x85, 0xd9, 0xc5, 0xbf, 0x80, 0xa0, 0xc4, 0x55, 0x9e, + 0xca, 0x12, 0x8b, 0xd0, 0xd3, 0x9f, 0xf0, 0xed, 0x27, 0xe7, 0x36, 0x25, 0xb6, 0x9b, 0xa2, 0xdf, + 0x1d, 0xb8, 0xb7, 0x53, 0x8a, 0xef, 0x01, 0xdb, 0xe8, 0x5b, 0xf9, 0x82, 0x6d, 0x08, 0xd5, 0xfa, + 0x46, 0xbe, 0x60, 0x35, 0xa1, 0x5b, 0xcd, 0x9f, 0x2f, 0xd8, 0x2d, 0xa1, 0x6b, 0xcd, 0x9a, 0x2f, + 0xd8, 0x35, 0xff, 0x04, 0xfa, 0x3f, 0x55, 0xa8, 0x12, 0x2c, 0x42, 0x5f, 0x9f, 0xfc, 0xce, 0xf6, + 0xe4, 0xef, 0x2b, 0x54, 0xb5, 0x68, 0xf2, 0xf4, 0x52, 0xcd, 0xb8, 0xa1, 0x4f, 0xaf, 0x29, 0x56, + 0xd2, 0x74, 0xf4, 0x4d, 0x8c, 0xd6, 0xb6, 0x43, 0x86, 0x33, 0xea, 0xd0, 0x97, 0xe0, 0xc9, 0x0d, + 0x16, 0x61, 0xa0, 0xeb, 0x7f, 0xf8, 0x86, 0x66, 0x1c, 0x4c, 0x36, 0x58, 0x7c, 0xb3, 0x2e, 0x55, + 0x2d, 0xf4, 0xf6, 0x87, 0x4f, 0x21, 0x68, 0x43, 0x34, 0x39, 0x2f, 0xb1, 0xd6, 0x0f, 0x0c, 0x04, + 0x2d, 0xf9, 0x47, 0xe0, 0xdf, 0xc8, 0xb4, 0x32, 0x8d, 0x1f, 0x3e, 0xde, 0xdf, 0x96, 0x9d, 0x6c, + 0x92, 0x42, 0x98, 0xe4, 0xd7, 0xce, 0x57, 0x2c, 0xfa, 0x93, 0x81, 0x47, 0x31, 0x22, 0x3b, 0xc5, + 0x2b, 0x19, 0xd7, 0x87, 0x59, 0xb5, 0x5e, 0x14, 0x21, 0x1b, 0xb9, 0x63, 0x57, 0xec, 0xc4, 0xf8, + 0x7b, 0xd0, 0x9b, 0x9b, 0xac, 0x33, 0x72, 0xc7, 0x81, 0xb0, 0x88, 0xdf, 0x07, 0x3f, 0x95, 0x73, + 0x4c, 0xad, 0x0e, 0x0c, 0xa0, 0xdd, 0xb9, 0xc2, 0x65, 0xb2, 0xb1, 0x32, 0xb0, 0x88, 0xe2, 0x45, + 0xb5, 0xa4, 0xb8, 0x91, 0x80, 0x45, 0xd4, 0xae, 0xb9, 0x2c, 0xda, 0x16, 0xd2, 0x9a, 0x2a, 0x17, + 0xb1, 0x4c, 0x9b, 0x1e, 0x1a, 0x10, 0xfd, 0xc5, 0x68, 0xfe, 0x0d, 0xdf, 0x9d, 0x99, 0x33, 0x1d, + 0x7d, 0x1f, 0x06, 0x34, 0x0b, 0x2f, 0x6e, 0xa4, 0xb2, 0x73, 0xd7, 0x27, 0x7c, 0x29, 0x15, 0xff, + 0x1c, 0x7a, 0xfa, 0xe5, 0x77, 0xcc, 0x5e, 0x53, 0xee, 0x92, 0xf2, 0xc2, 0x6e, 0x6b, 0x19, 0xf4, + 0x3a, 0x0c, 0xb6, 0x8f, 0xf5, 0xbb, 0x8f, 0x7d, 0x04, 0x3e, 0x8d, 0x42, 0xad, 0x6f, 0x7f, 0x67, + 0x65, 0x33, 0x30, 0x66, 0x57, 0x74, 0x01, 0xf7, 0x76, 0x4e, 0x6c, 0x4f, 0x62, 0xbb, 0x27, 0x6d, + 0x59, 0x0c, 0x2c, 0x6b, 0xa4, 0xfd, 0x02, 0x53, 0x8c, 0x4b, 0x5c, 0xe8, 0x7e, 0x0f, 0x44, 0x8b, + 0xa3, 0x5f, 0xd9, 0xb6, 0xae, 0x3e, 0x8f, 0xd4, 0x1d, 0x67, 0xab, 0x95, 0x5c, 0x2f, 0x6c, 0xe9, + 0x06, 0x52, 0xdf, 0x16, 0x73, 0x5b, 0xda, 0x59, 0xcc, 0x09, 0xab, 0xdc, 0x32, 0xe8, 0xa8, 0x9c, + 0x8f, 0x60, 0xb8, 0x42, 0x59, 0x54, 0x0a, 0x57, 0xb8, 0x2e, 0x6d, 0x0b, 0xba, 0x21, 0xfe, 0x00, + 0xfa, 0xa5, 0xbc, 0x7a, 0x41, 0xb3, 0x67, 0x99, 0x2c, 0xe5, 0xd5, 0x09, 0xd6, 0xfc, 0x03, 0x08, + 0x96, 0x09, 0xa6, 0x0b, 0x9d, 0x32, 0x74, 0x0e, 0x74, 0xe0, 0x04, 0xeb, 0xe8, 0x37, 0x06, 0xbd, + 0x19, 0xaa, 0x1b, 0x54, 0x6f, 0x65, 0x17, 0x5d, 0x3b, 0x75, 0xff, 0xc5, 0x4e, 0xbd, 0xbb, 0xed, + 0xd4, 0xdf, 0xda, 0xe9, 0x7d, 0xf0, 0x67, 0x2a, 0x3e, 0x9e, 0xea, 0x1b, 0xb9, 0xc2, 0x00, 0x9a, + 0xc6, 0x49, 0x5c, 0x26, 0x37, 0x68, 0x3d, 0xd6, 0xa2, 0xe8, 0x17, 0x06, 0xbd, 0x53, 0x59, 0x67, + 0x55, 0xf9, 0xda, 0x84, 0x8d, 0x60, 0x38, 0xc9, 0xf3, 0x34, 0x89, 0x65, 0x99, 0x64, 0x6b, 0x7b, + 0xdb, 0x6e, 0x88, 0x76, 0x3c, 0xeb, 0xf4, 0xce, 0xdc, 0xbb, 0x1b, 0x22, 0x85, 0x1e, 0x69, 0x17, + 0x34, 0x96, 0xd6, 0x51, 0xa8, 0x31, 0x3f, 0x9d, 0xa4, 0x07, 0x4e, 0xaa, 0x32, 0x5b, 0xa6, 0xd9, + 0xad, 0x7e, 0xc9, 0x40, 0xb4, 0x38, 0x7a, 0xe5, 0x80, 0xf7, 0x7f, 0xb9, 0xdb, 0x1e, 0xb0, 0xc4, + 0x12, 0xc9, 0x92, 0xd6, 0xeb, 0xfa, 0x1d, 0xaf, 0x0b, 0xa1, 0x5f, 0x2b, 0xb9, 0xbe, 0xc2, 0x22, + 0x1c, 0x68, 0xe7, 0x68, 0xa0, 0xce, 0x68, 0x8d, 0x18, 0x93, 0x0b, 0x44, 0x03, 0xdb, 0x99, 0x87, + 0xce, 0xcc, 0x7f, 0x66, 0xfd, 0x70, 0xa8, 0x6f, 0x14, 0xee, 0xb6, 0xe5, 0xbf, 0xb3, 0xc1, 0x57, + 0x0c, 0xfc, 0x56, 0x30, 0x47, 0xbb, 0x82, 0x39, 0xda, 0x0a, 0x66, 0x7a, 0xd8, 0x08, 0x66, 0x7a, + 0x48, 0x58, 0x9c, 0x35, 0x82, 0x11, 0x67, 0x44, 0xd6, 0x53, 0x95, 0x55, 0xf9, 0x61, 0x6d, 0x58, + 0x0d, 0x44, 0x8b, 0x69, 0xca, 0x7e, 0xb8, 0x46, 0x65, 0x5b, 0x1d, 0x08, 0x8b, 0x68, 0x26, 0x4f, + 0xb5, 0x99, 0x98, 0xe6, 0x1a, 0xc0, 0x3f, 0x06, 0x5f, 0x50, 0xf3, 0x74, 0x87, 0x77, 0x78, 0xd1, + 0x61, 0x61, 0xb2, 0x54, 0xd4, 0xfc, 0x57, 0xb1, 0xbf, 0x27, 0x16, 0x45, 0x4f, 0xec, 0xe7, 0x54, + 0xfd, 0x22, 0xcf, 0x51, 0x59, 0x89, 0x19, 0xa0, 0xcf, 0xcc, 0x6e, 0xd1, 0xb8, 0xa3, 0x2b, 0x0c, + 0x88, 0x7e, 0x84, 0x60, 0x92, 0xa2, 0x2a, 0x45, 0x95, 0xbe, 0xee, 0xa9, 0x1c, 0xbc, 0x6f, 0x67, + 0xdf, 0x3d, 0x6f, 0x84, 0x49, 0xeb, 0xad, 0x9c, 0xdc, 0x7f, 0xc8, 0xe9, 0x44, 0xe6, 0xf2, 0x78, + 0xaa, 0xe7, 0xcc, 0x15, 0x16, 0x45, 0x9f, 0x82, 0x47, 0xb2, 0xed, 0x54, 0xf6, 0xde, 0x24, 0xf9, + 0x79, 0x4f, 0xff, 0x2b, 0x7b, 0xf2, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x59, 0x2e, 0xc0, + 0xa7, 0x09, 0x00, 0x00, } diff --git a/bolt/internal/internal.proto b/bolt/internal/internal.proto index aa4fe470b2..9cd762d39d 100644 --- a/bolt/internal/internal.proto +++ b/bolt/internal/internal.proto @@ -108,6 +108,7 @@ message Query { repeated string Wheres = 5; // Wheres define the restrictions on the query string Label = 6; // Label is the name of the Y-Axis Range Range = 7; // Range is the upper and lower bound of the Y-Axis + string Source = 8; // Source is the optional URI to the data source } message Range { diff --git a/bolt/internal/internal_test.go b/bolt/internal/internal_test.go index 937a192d4f..244dd471cb 100644 --- a/bolt/internal/internal_test.go +++ b/bolt/internal/internal_test.go @@ -162,6 +162,7 @@ func Test_MarshalDashboard(t *testing.T) { Range: &chronograf.Range{ Upper: int64(100), }, + Source: "/chronograf/v1/sources/1", }, }, Axes: map[string]chronograf.Axis{ diff --git a/chronograf.go b/chronograf.go index 070862ed5f..d2d5c2bfa1 100644 --- a/chronograf.go +++ b/chronograf.go @@ -395,6 +395,7 @@ type DashboardQuery struct { Label string `json:"label,omitempty"` // Label is the Y-Axis label for the data Range *Range `json:"range,omitempty"` // Range is the default Y-Axis range for the data QueryConfig QueryConfig `json:"queryConfig,omitempty"` // QueryConfig represents the query state that is understood by the data explorer + Source string `json:"source"` // Source is the optional URI to the data source for this queryConfig } // TemplateQuery is used to retrieve choices for template replacement diff --git a/server/dashboards_test.go b/server/dashboards_test.go index ff740ba001..30ee0d0629 100644 --- a/server/dashboards_test.go +++ b/server/dashboards_test.go @@ -217,6 +217,7 @@ func Test_newDashboardResponse(t *testing.T) { H: 0, Queries: []chronograf.DashboardQuery{ { + Source: "/chronograf/v1/sources/1", Command: "SELECT donors from hill_valley_preservation_society where time > '1985-10-25 08:00:00'", }, }, @@ -236,6 +237,7 @@ func Test_newDashboardResponse(t *testing.T) { H: 0, Queries: []chronograf.DashboardQuery{ { + Source: "/chronograf/v1/sources/2", Command: "SELECT winning_horses from grays_sports_alamanc where time > now() - 15m", }, }, @@ -256,6 +258,7 @@ func Test_newDashboardResponse(t *testing.T) { Queries: []chronograf.DashboardQuery{ { Command: "SELECT donors from hill_valley_preservation_society where time > '1985-10-25 08:00:00'", + Source: "/chronograf/v1/sources/1", QueryConfig: chronograf.QueryConfig{ RawText: &[]string{"SELECT donors from hill_valley_preservation_society where time > '1985-10-25 08:00:00'"}[0], Fields: []chronograf.Field{}, @@ -303,6 +306,7 @@ func Test_newDashboardResponse(t *testing.T) { Queries: []chronograf.DashboardQuery{ { Command: "SELECT winning_horses from grays_sports_alamanc where time > now() - 15m", + Source: "/chronograf/v1/sources/2", QueryConfig: chronograf.QueryConfig{ Measurement: "grays_sports_alamanc", Fields: []chronograf.Field{ diff --git a/server/swagger.json b/server/swagger.json index baed5e911f..82e402fc4c 100644 --- a/server/swagger.json +++ b/server/swagger.json @@ -3766,6 +3766,11 @@ "query": { "type": "string" }, + "source": { + "type": "string", + "format": "url", + "description": "Optional URI for data source for this query" + }, "queryConfig": { "$ref": "#/definitions/QueryConfig" } From a39ab180ad65591ab6683c91d16cba981e6f15db Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 18 Sep 2017 14:47:18 -0700 Subject: [PATCH 07/34] Update source on a query --- .../components/CellEditorOverlay.js | 60 +++++++++++++++---- .../dashboards/components/DisplayOptions.js | 58 +++++------------- .../dashboards/components/SourceSelector.js | 6 +- ui/src/utils/buildQueriesForGraphs.js | 12 +++- 4 files changed, 78 insertions(+), 58 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index 7959bba2fb..37d2686b50 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -23,10 +23,20 @@ class CellEditorOverlay extends Component { constructor(props) { super(props) - const {cell: {name, type, queries, axes, source}} = props + const {cell: {name, type, queries, axes}, sources} = props + + let source = [...sources, ...this.dummySources].find( + s => + s.links.self === _.get(queries, ['0', source], props.source.links.self) + ) + source = source && source.links.self const queriesWorkingDraft = _.cloneDeep( - queries.map(({queryConfig}) => ({...queryConfig, id: uuid.v4()})) + queries.map(({queryConfig}) => ({ + ...queryConfig, + id: uuid.v4(), + source, + })) ) this.state = { @@ -35,7 +45,6 @@ class CellEditorOverlay extends Component { queriesWorkingDraft, activeQueryIndex: 0, isDisplayOptionsTabActive: false, - cellSource: source, axes, } } @@ -198,8 +207,13 @@ class CellEditorOverlay extends Component { }) } - handleSetCellSource = cellSource => { - this.setState({cellSource}) + handleSetQuerySource = source => { + const queriesWorkingDraft = this.state.queriesWorkingDraft.map(q => ({ + ..._.cloneDeep(q), + source: source.links.self, + })) + + this.setState({queriesWorkingDraft}) } getActiveQuery = () => { @@ -226,10 +240,38 @@ class CellEditorOverlay extends Component { } } + dummySources = () => { + let dummies = [] + for (let i = 2; i < 13; i++) { + const id = 1 + i + dummies = [ + ...dummies, + { + id, + name: `dummyFlux ${i}`, + type: 'influx', + username: '', + url: `http://9X.se3ShredURL02x6tall1sStartURL16enlargedj216stretching1fganglingeexpanded1lankydeep4434longishsustained6EzURLTightURL30URLPieShrinkrwtoweringalankyPiURLr4qSHurl0prolongedloftyprotracted00greatd0Dwarfurl83runningcUrlTea1Redirx30Dwarfurl13a1lnk.in74nu1z106p6011lanky0Shrtndenduring1URl.iebkelongateShredURLi1dlastinglengthenedU7618ShrinkrDecentURLk2longishShrtndelongateds1U76MyURLsSitelutions000toweringShoterLinka1462Fly217ooexpanded1080B6541continuedstretched0U760elongated3Shrtnd301URL4SHurlganglingx07ShoterLinkrangywYATUC1719Is.gdURLvi3ShortURLv0a8stretchingprotractedc2URLcut0ganglingUlimit51DigBig16q3Redirx1l16c0010farawayYATUC0t1stretch0remote91b0bfaraway0elongate59URLvi4lnk.in841SimURLDwarfurlr32towering701Doiop07311a5825lastingz0918TinyLinkenlargedexpanded30CanURLUlimits105d33f0y6172Sitelutions3lengthened6longishShredURLk20a17x04ShrinkURLprotractedv3drawn%2Boutm6greatvXilXil58ShortURL9f1d16protracteddistant780151enlargedv6301URLsustainedspread%2Boutl00c38URLPie7gangling8035s08s131f8i0Ulimit0nTinyLink9elongatedlasting908deeplengthy0lanky116TraceURL7ax0m6ShrinkURLo1llastingShrinkURLCanURLm060great1TinyLink0561f19MyURL4370Fly21d2drawn%2Bout0stretchedenduring1113011026cURLvijenduringShortenURL18GetShortyShrinkr56e8y416URL7spread%2Bout7ocURLHawk5cahighDwarfurl1elongate4efcURL.co.ukz73Ulimit1RubyURLi7lnk.inDigBigdeep97protractedg58WapURL0761YepIt77esustainedremote452e461sustained9U76NanoRefjPiURL5enduring0X.seorSitelutions111stringyU76CanURL9Shrtnd9stringyBeam.toemSHurlgreatc0e011hremote162lengthenedstretchlengthy1506U76xrangy0Fly210tb3111eiURLCuttera1stringy5gangling0Shortlinksgangling10loftyc00A2Nd1MyURL1drawn%2Bouty5SmallrtURLCutterDigBig00g8Metamarkrunningre04prolonged4EasyURLfURl.ieUrlTeatoweringSnipURLjbr0191b170wextensiveMooURL1Shorl932U76spun%2Bout6tall2i0DoiopwlankyURLHawkq6EzURL921uURLHawkehcspread%2Bout11g10krunningystretching08oDecentURL16279Xil3stringy1l6321URLcutShrtndeuelongate1010lastingexpanded5ShrinkrMyURLstretching5drawn%2Bout50distant40faraway24elongate7nstretchinggreat7delongated1SnipURL301URL74e69ttallf1A2N31${i}`, + default: false, + telegraf: 'telegraf', + links: { + self: `/chronograf/v1/sources/${i}`, + }, + }, + ] + } + + return dummies + } + + formatSources = [...this.props.sources, ...this.dummySources()].map(s => ({ + ...s, + text: `${s.name} @ ${s.url}`, + })) + render() { const { source, - sources, onCancel, templates, timeRange, @@ -239,7 +281,6 @@ class CellEditorOverlay extends Component { const { axes, - cellSource, activeQueryIndex, cellWorkingName, cellWorkingType, @@ -288,14 +329,13 @@ class CellEditorOverlay extends Component { ? { - let dummies = [] - for (let i = 2; i < 13; i++) { - const id = 1 + i - dummies = [ - ...dummies, - { - id, - name: `dummyFlux ${i}`, - type: 'influx', - username: '', - url: `http://9X.se3ShredURL02x6tall1sStartURL16enlargedj216stretching1fganglingeexpanded1lankydeep4434longishsustained6EzURLTightURL30URLPieShrinkrwtoweringalankyPiURLr4qSHurl0prolongedloftyprotracted00greatd0Dwarfurl83runningcUrlTea1Redirx30Dwarfurl13a1lnk.in74nu1z106p6011lanky0Shrtndenduring1URl.iebkelongateShredURLi1dlastinglengthenedU7618ShrinkrDecentURLk2longishShrtndelongateds1U76MyURLsSitelutions000toweringShoterLinka1462Fly217ooexpanded1080B6541continuedstretched0U760elongated3Shrtnd301URL4SHurlganglingx07ShoterLinkrangywYATUC1719Is.gdURLvi3ShortURLv0a8stretchingprotractedc2URLcut0ganglingUlimit51DigBig16q3Redirx1l16c0010farawayYATUC0t1stretch0remote91b0bfaraway0elongate59URLvi4lnk.in841SimURLDwarfurlr32towering701Doiop07311a5825lastingz0918TinyLinkenlargedexpanded30CanURLUlimits105d33f0y6172Sitelutions3lengthened6longishShredURLk20a17x04ShrinkURLprotractedv3drawn%2Boutm6greatvXilXil58ShortURL9f1d16protracteddistant780151enlargedv6301URLsustainedspread%2Boutl00c38URLPie7gangling8035s08s131f8i0Ulimit0nTinyLink9elongatedlasting908deeplengthy0lanky116TraceURL7ax0m6ShrinkURLo1llastingShrinkURLCanURLm060great1TinyLink0561f19MyURL4370Fly21d2drawn%2Bout0stretchedenduring1113011026cURLvijenduringShortenURL18GetShortyShrinkr56e8y416URL7spread%2Bout7ocURLHawk5cahighDwarfurl1elongate4efcURL.co.ukz73Ulimit1RubyURLi7lnk.inDigBigdeep97protractedg58WapURL0761YepIt77esustainedremote452e461sustained9U76NanoRefjPiURL5enduring0X.seorSitelutions111stringyU76CanURL9Shrtnd9stringyBeam.toemSHurlgreatc0e011hremote162lengthenedstretchlengthy1506U76xrangy0Fly210tb3111eiURLCuttera1stringy5gangling0Shortlinksgangling10loftyc00A2Nd1MyURL1drawn%2Bouty5SmallrtURLCutterDigBig00g8Metamarkrunningre04prolonged4EasyURLfURl.ieUrlTeatoweringSnipURLjbr0191b170wextensiveMooURL1Shorl932U76spun%2Bout6tall2i0DoiopwlankyURLHawkq6EzURL921uURLHawkehcspread%2Bout11g10krunningystretching08oDecentURL16279Xil3stringy1l6321URLcutShrtndeuelongate1010lastingexpanded5ShrinkrMyURLstretching5drawn%2Bout50distant40faraway24elongate7nstretchinggreat7delongated1SnipURL301URL74e69ttallf1A2N31${i}`, - default: false, - telegraf: 'telegraf', - links: { - self: `/chronograf/v1/sources/${i}`, - }, - }, - ] - } - - return dummies - } - - formatSources = [...this.props.sources, ...this.dummySources()].map(s => ({ - ...s, - text: `${s.name} @ ${s.url}`, - })) - findSelectedSource = () => { - const {cellSource, source: defaultSource} = this.props - const sources = this.formatSources - const cellSourceID = cellSource && cellSource.id + const {source, sources} = this.props + const query = _.get(this.props.queryConfigs, 0, false) - let selected - selected = sources.find(s => s.id === cellSourceID) - - if (selected) { - return selected.text + if (!query) { + const defaultSource = sources.find(s => s.id === source.id) + return (defaultSource && defaultSource.text) || 'No source selected' } - selected = sources.find(s => s.id === defaultSource.id) - return (selected && selected.text) || 'No sources' + const selected = sources.find(s => s.links.self === query.source) + return (selected && selected.text) || 'No source selected' } render() { const { + sources, onSetBase, onSetScale, onSetLabel, - onSetCellSource, + onSetQuerySource, selectedGraphType, onSelectGraphType, onSetPrefixSuffix, @@ -104,8 +75,8 @@ class DisplayOptions extends Component { onSetYAxisBoundMax={onSetYAxisBoundMax} />
@@ -126,14 +97,13 @@ DisplayOptions.propTypes = { onSetPrefixSuffix: func.isRequired, onSetYAxisBoundMin: func.isRequired, onSetYAxisBoundMax: func.isRequired, - onSetCellSource: func.isRequired, + onSetQuerySource: func.isRequired, onSetScale: func.isRequired, onSetLabel: func.isRequired, onSetBase: func.isRequired, axes: shape({}).isRequired, queryConfigs: arrayOf(shape()).isRequired, source: shape({}).isRequired, - cellSource: shape({}), } export default DisplayOptions diff --git a/ui/src/dashboards/components/SourceSelector.js b/ui/src/dashboards/components/SourceSelector.js index 694282f0d0..5cddcf1964 100644 --- a/ui/src/dashboards/components/SourceSelector.js +++ b/ui/src/dashboards/components/SourceSelector.js @@ -1,7 +1,7 @@ import React, {PropTypes} from 'react' import Dropdown from 'shared/components/Dropdown' -const SourceSelector = ({sources = [], selected, onSetCellSource}) => +const SourceSelector = ({sources = [], selected, onSetQuerySource}) =>
InfluxDB Source Selector
menuClass="dropdown-astronaut" useAutoComplete={true} selected={selected} - onChoose={onSetCellSource} + onChoose={onSetQuerySource} toggleStyle={{width: '50%', maxWidth: '300px'}} />
@@ -25,7 +25,7 @@ const {arrayOf, func, shape, string} = PropTypes SourceSelector.propTypes = { sources: arrayOf(shape()).isRequired, - onSetCellSource: func.isRequired, + onSetQuerySource: func.isRequired, selected: string, } diff --git a/ui/src/utils/buildQueriesForGraphs.js b/ui/src/utils/buildQueriesForGraphs.js index 39ff302e5f..5cff284d57 100644 --- a/ui/src/utils/buildQueriesForGraphs.js +++ b/ui/src/utils/buildQueriesForGraphs.js @@ -8,7 +8,17 @@ const buildQueries = (proxy, queryConfigs, timeRange) => { }) const queries = statements.filter(s => s.text !== null).map(s => { - return {host: [proxy], text: s.text, id: s.id, queryConfig: s.queryConfig} + let queryProxy = '' + if (s.queryConfig.source) { + queryProxy = `${s.queryConfig.source}/proxy` + } + + return { + host: [queryProxy || proxy], + text: s.text, + id: s.id, + queryConfig: s.queryConfig, + } }) return queries From 9858d8a7a8df76383b5df49ae56f645104ebaa7a Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 18 Sep 2017 17:13:20 -0700 Subject: [PATCH 08/34] Remove dummy data --- .../components/CellEditorOverlay.js | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index 37d2686b50..192132d5ef 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -240,31 +240,7 @@ class CellEditorOverlay extends Component { } } - dummySources = () => { - let dummies = [] - for (let i = 2; i < 13; i++) { - const id = 1 + i - dummies = [ - ...dummies, - { - id, - name: `dummyFlux ${i}`, - type: 'influx', - username: '', - url: `http://9X.se3ShredURL02x6tall1sStartURL16enlargedj216stretching1fganglingeexpanded1lankydeep4434longishsustained6EzURLTightURL30URLPieShrinkrwtoweringalankyPiURLr4qSHurl0prolongedloftyprotracted00greatd0Dwarfurl83runningcUrlTea1Redirx30Dwarfurl13a1lnk.in74nu1z106p6011lanky0Shrtndenduring1URl.iebkelongateShredURLi1dlastinglengthenedU7618ShrinkrDecentURLk2longishShrtndelongateds1U76MyURLsSitelutions000toweringShoterLinka1462Fly217ooexpanded1080B6541continuedstretched0U760elongated3Shrtnd301URL4SHurlganglingx07ShoterLinkrangywYATUC1719Is.gdURLvi3ShortURLv0a8stretchingprotractedc2URLcut0ganglingUlimit51DigBig16q3Redirx1l16c0010farawayYATUC0t1stretch0remote91b0bfaraway0elongate59URLvi4lnk.in841SimURLDwarfurlr32towering701Doiop07311a5825lastingz0918TinyLinkenlargedexpanded30CanURLUlimits105d33f0y6172Sitelutions3lengthened6longishShredURLk20a17x04ShrinkURLprotractedv3drawn%2Boutm6greatvXilXil58ShortURL9f1d16protracteddistant780151enlargedv6301URLsustainedspread%2Boutl00c38URLPie7gangling8035s08s131f8i0Ulimit0nTinyLink9elongatedlasting908deeplengthy0lanky116TraceURL7ax0m6ShrinkURLo1llastingShrinkURLCanURLm060great1TinyLink0561f19MyURL4370Fly21d2drawn%2Bout0stretchedenduring1113011026cURLvijenduringShortenURL18GetShortyShrinkr56e8y416URL7spread%2Bout7ocURLHawk5cahighDwarfurl1elongate4efcURL.co.ukz73Ulimit1RubyURLi7lnk.inDigBigdeep97protractedg58WapURL0761YepIt77esustainedremote452e461sustained9U76NanoRefjPiURL5enduring0X.seorSitelutions111stringyU76CanURL9Shrtnd9stringyBeam.toemSHurlgreatc0e011hremote162lengthenedstretchlengthy1506U76xrangy0Fly210tb3111eiURLCuttera1stringy5gangling0Shortlinksgangling10loftyc00A2Nd1MyURL1drawn%2Bouty5SmallrtURLCutterDigBig00g8Metamarkrunningre04prolonged4EasyURLfURl.ieUrlTeatoweringSnipURLjbr0191b170wextensiveMooURL1Shorl932U76spun%2Bout6tall2i0DoiopwlankyURLHawkq6EzURL921uURLHawkehcspread%2Bout11g10krunningystretching08oDecentURL16279Xil3stringy1l6321URLcutShrtndeuelongate1010lastingexpanded5ShrinkrMyURLstretching5drawn%2Bout50distant40faraway24elongate7nstretchinggreat7delongated1SnipURL301URL74e69ttallf1A2N31${i}`, - default: false, - telegraf: 'telegraf', - links: { - self: `/chronograf/v1/sources/${i}`, - }, - }, - ] - } - - return dummies - } - - formatSources = [...this.props.sources, ...this.dummySources()].map(s => ({ + formatSources = this.props.sources.map(s => ({ ...s, text: `${s.name} @ ${s.url}`, })) From ebf1e67e4d22256087be671796937ef49fb4d8e8 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 18 Sep 2017 17:13:53 -0700 Subject: [PATCH 09/34] Stop cell fields being clobbered --- ui/src/dashboards/components/Dashboard.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/ui/src/dashboards/components/Dashboard.js b/ui/src/dashboards/components/Dashboard.js index b00a64ea15..c2d394917c 100644 --- a/ui/src/dashboards/components/Dashboard.js +++ b/ui/src/dashboards/components/Dashboard.js @@ -24,16 +24,11 @@ const Dashboard = ({ }) => { const cells = dashboard.cells.map(cell => { const dashboardCell = {...cell} - dashboardCell.queries = dashboardCell.queries.map( - ({label, query, queryConfig, db}) => ({ - label, - query, - queryConfig, - db, - database: db, - text: query, - }) - ) + dashboardCell.queries = dashboardCell.queries.map(q => ({ + ...q, + database: q.db, + text: q.query, + })) return dashboardCell }) From 2ddf6213b0185cfe0c7925fb3185c2ff2e434755 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 18 Sep 2017 17:14:17 -0700 Subject: [PATCH 10/34] Actually find a source --- ui/src/dashboards/components/CellEditorOverlay.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index 192132d5ef..e7951edfae 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -25,10 +25,8 @@ class CellEditorOverlay extends Component { const {cell: {name, type, queries, axes}, sources} = props - let source = [...sources, ...this.dummySources].find( - s => - s.links.self === _.get(queries, ['0', source], props.source.links.self) - ) + let source = _.get(queries, ['0', 'source'], props.source.links.self) + source = sources.find(s => s.links.self === source) source = source && source.links.self const queriesWorkingDraft = _.cloneDeep( @@ -151,6 +149,7 @@ class CellEditorOverlay extends Component { return { queryConfig: q, query, + source: q.source, } }) From 5cd7d9e26f2db4ef5b37289763427583648bfa1e Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 18 Sep 2017 17:43:22 -0700 Subject: [PATCH 11/34] Use non-default source on any cell in dashboard --- ui/src/dashboards/components/Dashboard.js | 3 +++ ui/src/dashboards/containers/DashboardPage.js | 2 +- ui/src/shared/components/LayoutRenderer.js | 6 +----- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ui/src/dashboards/components/Dashboard.js b/ui/src/dashboards/components/Dashboard.js index c2d394917c..08c8e932c7 100644 --- a/ui/src/dashboards/components/Dashboard.js +++ b/ui/src/dashboards/components/Dashboard.js @@ -7,6 +7,7 @@ import FancyScrollbar from 'shared/components/FancyScrollbar' const Dashboard = ({ source, + sources, onZoom, dashboard, onAddCell, @@ -55,6 +56,7 @@ const Dashboard = ({ timeRange={timeRange} autoRefresh={autoRefresh} source={source} + sources={sources} onPositionChange={onPositionChange} onDeleteCell={onDeleteCell} onSummonOverlayTechnologies={onSummonOverlayTechnologies} @@ -107,6 +109,7 @@ Dashboard.propTypes = { proxy: string, }).isRequired, }).isRequired, + sources: arrayOf(shape({})).isRequired, autoRefresh: number.isRequired, timeRange: shape({}).isRequired, onOpenTemplateManager: func.isRequired, diff --git a/ui/src/dashboards/containers/DashboardPage.js b/ui/src/dashboards/containers/DashboardPage.js index 0236d0ee21..60f6e8168c 100644 --- a/ui/src/dashboards/containers/DashboardPage.js +++ b/ui/src/dashboards/containers/DashboardPage.js @@ -357,6 +357,7 @@ DashboardPage.propTypes = { self: string, }), }).isRequired, + sources: arrayOf(shape({})).isRequired, params: shape({ sourceID: string.isRequired, dashboardID: string.isRequired, @@ -409,7 +410,6 @@ DashboardPage.propTypes = { status: shape(), }).isRequired, errorThrown: func, - sources: arrayOf(shape()), } const mapStateToProps = state => { diff --git a/ui/src/shared/components/LayoutRenderer.js b/ui/src/shared/components/LayoutRenderer.js index cfd76c2eb1..7c5b27b0f5 100644 --- a/ui/src/shared/components/LayoutRenderer.js +++ b/ui/src/shared/components/LayoutRenderer.js @@ -26,11 +26,6 @@ class LayoutRenderer extends Component { } } - // idea adopted from https://stackoverflow.com/questions/36862334/get-viewport-window-height-in-reactjs - updateWindowDimensions = () => { - this.setState({rowHeight: this.calculateRowHeight()}) - } - handleLayoutChange = layout => { if (!this.props.onPositionChange) { return @@ -172,6 +167,7 @@ LayoutRenderer.propTypes = { isEditable: bool, onCancelEditCell: func, onZoom: func, + sources: arrayOf(shape({})).isRequired, } export default LayoutRenderer From 32c0e6f1cf10ff42ae89cad975913631bafeaf83 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Fri, 29 Sep 2017 15:18:22 -0700 Subject: [PATCH 12/34] Handle rebase --- ui/src/shared/components/Layout.js | 20 ++++++++- ui/src/shared/components/LayoutRenderer.js | 49 ++++++++++++---------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/ui/src/shared/components/Layout.js b/ui/src/shared/components/Layout.js index 174964885d..bb42972fe8 100644 --- a/ui/src/shared/components/Layout.js +++ b/ui/src/shared/components/Layout.js @@ -4,11 +4,23 @@ import LayoutCell from 'shared/components/LayoutCell' import RefreshingGraph from 'shared/components/RefreshingGraph' import {buildQueriesForLayouts} from 'utils/influxql' +import _ from 'lodash' + +const getSource = (cell, source, sources) => { + const s = _.get(cell, ['queries', '0', 'source'], null) + if (!s) { + return source + } + + return sources.find(src => src.links.self === s) +} + const Layout = ({ host, cell, cell: {h, axes, type}, source, + sources, onZoom, templates, timeRange, @@ -41,7 +53,12 @@ const Layout = ({ autoRefresh={autoRefresh} synchronizer={synchronizer} resizeCoords={resizeCoords} - queries={buildQueriesForLayouts(cell, source, timeRange, host)} + queries={buildQueriesForLayouts( + cell, + getSource(cell, source, sources), + timeRange, + host + )} />} @@ -87,6 +104,7 @@ Layout.propTypes = { onCancelEditCell: func, resizeCoords: shape(), onZoom: func, + sources: arrayOf(shape()), } export default Layout diff --git a/ui/src/shared/components/LayoutRenderer.js b/ui/src/shared/components/LayoutRenderer.js index 7c5b27b0f5..0d7ec560be 100644 --- a/ui/src/shared/components/LayoutRenderer.js +++ b/ui/src/shared/components/LayoutRenderer.js @@ -1,6 +1,7 @@ import React, {Component, PropTypes} from 'react' import ReactGridLayout, {WidthProvider} from 'react-grid-layout' import Resizeable from 'react-component-resizable' + import _ from 'lodash' import Layout from 'src/shared/components/Layout' @@ -67,6 +68,7 @@ class LayoutRenderer extends Component { host, cells, source, + sources, onZoom, templates, timeRange, @@ -83,7 +85,7 @@ class LayoutRenderer extends Component { const isDashboard = !!this.props.onPositionChange return ( - + - {cells.map(cell => -
- -
- )} + {cells.map(cell => { + return ( +
+ +
+ ) + })}
) From 5d0670e6f26038d3d3b422925ebea1d69c89b7a2 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Fri, 29 Sep 2017 15:19:33 -0700 Subject: [PATCH 13/34] Implicitly return --- ui/src/shared/components/LayoutRenderer.js | 46 +++++++++++----------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/ui/src/shared/components/LayoutRenderer.js b/ui/src/shared/components/LayoutRenderer.js index 0d7ec560be..24466cf122 100644 --- a/ui/src/shared/components/LayoutRenderer.js +++ b/ui/src/shared/components/LayoutRenderer.js @@ -99,30 +99,28 @@ class LayoutRenderer extends Component { isDraggable={isDashboard} isResizable={isDashboard} > - {cells.map(cell => { - return ( -
- -
- ) - })} + {cells.map(cell => +
+ +
+ )}
) From a2583c820bbf71702fa1ea2233128ab53446908a Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Fri, 29 Sep 2017 16:05:06 -0700 Subject: [PATCH 14/34] Display 'No Results' when cannot connect to source To be more specific and provide more information to the user we would need to refactor how we do error handling in the app which is beyond the scope of this PR --- ui/src/shared/components/AutoRefresh.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/shared/components/AutoRefresh.js b/ui/src/shared/components/AutoRefresh.js index ccc35eb30c..d833c3ccf5 100644 --- a/ui/src/shared/components/AutoRefresh.js +++ b/ui/src/shared/components/AutoRefresh.js @@ -221,8 +221,8 @@ const AutoRefresh = ComposedComponent => { return true } - return data.every(datum => { - return datum.response.results.every(result => { + return data.every(({response}) => { + return _.get(response, 'results', []).every(result => { return ( Object.keys(result).filter(k => k !== 'statement_id').length === 0 ) From 581f1a01ca96422793cc8260a2314b181b1a360b Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Fri, 29 Sep 2017 16:41:30 -0700 Subject: [PATCH 15/34] WIP send along entire source object --- ui/src/dashboards/components/CellEditorOverlay.js | 9 ++++----- ui/src/dashboards/components/DisplayOptions.js | 2 +- ui/src/utils/buildQueriesForGraphs.js | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index e7951edfae..958dc16749 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -25,9 +25,8 @@ class CellEditorOverlay extends Component { const {cell: {name, type, queries, axes}, sources} = props - let source = _.get(queries, ['0', 'source'], props.source.links.self) - source = sources.find(s => s.links.self === source) - source = source && source.links.self + let source = _.get(queries, ['0', 'source'], null) + source = sources.find(s => s.links.self === source) || props.source const queriesWorkingDraft = _.cloneDeep( queries.map(({queryConfig}) => ({ @@ -149,7 +148,7 @@ class CellEditorOverlay extends Component { return { queryConfig: q, query, - source: q.source, + source: q.source.links.self, } }) @@ -209,7 +208,7 @@ class CellEditorOverlay extends Component { handleSetQuerySource = source => { const queriesWorkingDraft = this.state.queriesWorkingDraft.map(q => ({ ..._.cloneDeep(q), - source: source.links.self, + source, })) this.setState({queriesWorkingDraft}) diff --git a/ui/src/dashboards/components/DisplayOptions.js b/ui/src/dashboards/components/DisplayOptions.js index 923cb9b662..ae964282a4 100644 --- a/ui/src/dashboards/components/DisplayOptions.js +++ b/ui/src/dashboards/components/DisplayOptions.js @@ -43,7 +43,7 @@ class DisplayOptions extends Component { return (defaultSource && defaultSource.text) || 'No source selected' } - const selected = sources.find(s => s.links.self === query.source) + const selected = sources.find(s => s.links.self === query.source.links.self) return (selected && selected.text) || 'No source selected' } diff --git a/ui/src/utils/buildQueriesForGraphs.js b/ui/src/utils/buildQueriesForGraphs.js index 5cff284d57..7b2a1691fa 100644 --- a/ui/src/utils/buildQueriesForGraphs.js +++ b/ui/src/utils/buildQueriesForGraphs.js @@ -10,7 +10,7 @@ const buildQueries = (proxy, queryConfigs, timeRange) => { const queries = statements.filter(s => s.text !== null).map(s => { let queryProxy = '' if (s.queryConfig.source) { - queryProxy = `${s.queryConfig.source}/proxy` + queryProxy = `${s.queryConfig.source.links.proxy}` } return { From 0641b3eddabdf2d134f9e56d950ea232da4ec684 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Fri, 29 Sep 2017 17:18:40 -0700 Subject: [PATCH 16/34] Handle no queries or sources --- ui/src/dashboards/components/DisplayOptions.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/src/dashboards/components/DisplayOptions.js b/ui/src/dashboards/components/DisplayOptions.js index ae964282a4..f7382aba7d 100644 --- a/ui/src/dashboards/components/DisplayOptions.js +++ b/ui/src/dashboards/components/DisplayOptions.js @@ -38,13 +38,13 @@ class DisplayOptions extends Component { const {source, sources} = this.props const query = _.get(this.props.queryConfigs, 0, false) - if (!query) { + if (!query || !query.source) { const defaultSource = sources.find(s => s.id === source.id) - return (defaultSource && defaultSource.text) || 'No source selected' + return (defaultSource && defaultSource.text) || 'No sources' } - const selected = sources.find(s => s.links.self === query.source.links.self) - return (selected && selected.text) || 'No source selected' + const selected = sources.find(s => s.id === query.source.id) + return (selected && selected.text) || 'No sources' } render() { From f0f34da9b5e6b7990f7d5a2b24d0988a89a4e861 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 2 Oct 2017 13:47:04 -0700 Subject: [PATCH 17/34] Add souce indicator to cell If a cell is getting data from a source besides the default, it will display that sources name in the cell header --- ui/src/shared/components/Layout.js | 6 +++-- ui/src/shared/components/LayoutCell.js | 17 +++++++++------ ui/src/shared/components/LayoutCellHeader.js | 23 +++++++++++++++++--- ui/src/shared/components/LayoutRenderer.js | 2 +- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/ui/src/shared/components/Layout.js b/ui/src/shared/components/Layout.js index bb42972fe8..e7ffcdd00e 100644 --- a/ui/src/shared/components/Layout.js +++ b/ui/src/shared/components/Layout.js @@ -34,12 +34,13 @@ const Layout = ({ onSummonOverlayTechnologies, }) => {cell.isWidget ? @@ -48,6 +49,7 @@ const Layout = ({ type={type} cellHeight={h} onZoom={onZoom} + sources={sources} timeRange={timeRange} templates={templates} autoRefresh={autoRefresh} diff --git a/ui/src/shared/components/LayoutCell.js b/ui/src/shared/components/LayoutCell.js index 8b75c16058..abf7de7864 100644 --- a/ui/src/shared/components/LayoutCell.js +++ b/ui/src/shared/components/LayoutCell.js @@ -31,7 +31,7 @@ class LayoutCell extends Component { } render() { - const {cell, children, isEditable} = this.props + const {cell, children, isEditable, sources} = this.props const {isDeleting} = this.state const queries = _.get(cell, ['queries'], []) @@ -40,16 +40,18 @@ class LayoutCell extends Component {
@@ -69,7 +71,7 @@ class LayoutCell extends Component { } } -const {array, bool, func, node, number, shape, string} = PropTypes +const {arrayOf, bool, func, node, number, shape, string} = PropTypes LayoutCell.propTypes = { cell: shape({ @@ -77,8 +79,9 @@ LayoutCell.propTypes = { isEditing: bool, x: number.isRequired, y: number.isRequired, - queries: array, + queries: arrayOf(shape()), }).isRequired, + sources: arrayOf(shape()), children: node.isRequired, onDeleteCell: func, onSummonOverlayTechnologies: func, diff --git a/ui/src/shared/components/LayoutCellHeader.js b/ui/src/shared/components/LayoutCellHeader.js index 9b33401776..a37965a842 100644 --- a/ui/src/shared/components/LayoutCellHeader.js +++ b/ui/src/shared/components/LayoutCellHeader.js @@ -1,12 +1,19 @@ import React, {PropTypes} from 'react' import classnames from 'classnames' +import _ from 'lodash' import CustomTimeIndicator from 'shared/components/CustomTimeIndicator' import {NEW_DEFAULT_DASHBOARD_CELL} from 'src/dashboards/constants/index' -const LayoutCellHeader = ({queries, isEditable, cellName}) => { +const LayoutCellHeader = ( + {queries, isEditable, cellName, sources}, + {source: defaultSource} +) => { const cellNameIsDefault = cellName === NEW_DEFAULT_DASHBOARD_CELL.name + const querySource = sources.find( + s => s.links.self === _.get(queries, ['0', 'source'], null) + ) return (
{ : 'dash-graph--name' } > + {querySource && querySource.id !== defaultSource.id + ? + {querySource.name} + + : null} {cellName} {queries && queries.length ? @@ -30,12 +42,17 @@ const LayoutCellHeader = ({queries, isEditable, cellName}) => { ) } -const {array, bool, string} = PropTypes +const {arrayOf, bool, shape, string} = PropTypes + +LayoutCellHeader.contextTypes = { + source: shape({}), +} LayoutCellHeader.propTypes = { - queries: array, + queries: arrayOf(shape()), isEditable: bool, cellName: string, + sources: arrayOf(shape()), } export default LayoutCellHeader diff --git a/ui/src/shared/components/LayoutRenderer.js b/ui/src/shared/components/LayoutRenderer.js index 24466cf122..7ab90c4dd1 100644 --- a/ui/src/shared/components/LayoutRenderer.js +++ b/ui/src/shared/components/LayoutRenderer.js @@ -170,7 +170,7 @@ LayoutRenderer.propTypes = { isEditable: bool, onCancelEditCell: func, onZoom: func, - sources: arrayOf(shape({})).isRequired, + sources: arrayOf(shape({})), } export default LayoutRenderer From 18905b177598f77d468e318abe41b2b6ba059e39 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 2 Oct 2017 14:42:57 -0700 Subject: [PATCH 18/34] Get defensive with query sources --- ui/src/dashboards/components/CellEditorOverlay.js | 2 +- ui/src/shared/components/LayoutCellHeader.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index 958dc16749..4eadd853b9 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -148,7 +148,7 @@ class CellEditorOverlay extends Component { return { queryConfig: q, query, - source: q.source.links.self, + source: _.get(q, ['source', 'links', 'self'], null), } }) diff --git a/ui/src/shared/components/LayoutCellHeader.js b/ui/src/shared/components/LayoutCellHeader.js index a37965a842..6c70f531c1 100644 --- a/ui/src/shared/components/LayoutCellHeader.js +++ b/ui/src/shared/components/LayoutCellHeader.js @@ -7,7 +7,7 @@ import CustomTimeIndicator from 'shared/components/CustomTimeIndicator' import {NEW_DEFAULT_DASHBOARD_CELL} from 'src/dashboards/constants/index' const LayoutCellHeader = ( - {queries, isEditable, cellName, sources}, + {queries, isEditable, cellName, sources = []}, {source: defaultSource} ) => { const cellNameIsDefault = cellName === NEW_DEFAULT_DASHBOARD_CELL.name From f60075fdd4a1e9f3f8ec0d5933042f01be8df783 Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 2 Oct 2017 15:23:18 -0700 Subject: [PATCH 19/34] Guard againt selected source being deleted --- ui/src/shared/components/Layout.js | 49 +++++++++++++++++------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/ui/src/shared/components/Layout.js b/ui/src/shared/components/Layout.js index e7ffcdd00e..96d503e529 100644 --- a/ui/src/shared/components/Layout.js +++ b/ui/src/shared/components/Layout.js @@ -6,33 +6,36 @@ import {buildQueriesForLayouts} from 'utils/influxql' import _ from 'lodash' -const getSource = (cell, source, sources) => { +const getSource = (cell, source, sources, defaultSource) => { const s = _.get(cell, ['queries', '0', 'source'], null) if (!s) { return source } - return sources.find(src => src.links.self === s) + return sources.find(src => src.links.self === s) || defaultSource } -const Layout = ({ - host, - cell, - cell: {h, axes, type}, - source, - sources, - onZoom, - templates, - timeRange, - isEditable, - onEditCell, - autoRefresh, - onDeleteCell, - synchronizer, - resizeCoords, - onCancelEditCell, - onSummonOverlayTechnologies, -}) => +const Layout = ( + { + host, + cell, + cell: {h, axes, type}, + source, + sources, + onZoom, + templates, + timeRange, + isEditable, + onEditCell, + autoRefresh, + onDeleteCell, + synchronizer, + resizeCoords, + onCancelEditCell, + onSummonOverlayTechnologies, + }, + {source: defaultSource} +) => Date: Mon, 2 Oct 2017 15:43:05 -0700 Subject: [PATCH 20/34] Christmas came early --- ui/src/dashboards/components/Dashboard.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ui/src/dashboards/components/Dashboard.js b/ui/src/dashboards/components/Dashboard.js index 08c8e932c7..1cf622cc7c 100644 --- a/ui/src/dashboards/components/Dashboard.js +++ b/ui/src/dashboards/components/Dashboard.js @@ -50,18 +50,18 @@ const Dashboard = ({ />} {cells.length ? :

This Dashboard has no Cells

From cdbd54ce0d7badab652cde462c2a34384a3527dd Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 2 Oct 2017 15:54:08 -0700 Subject: [PATCH 21/34] Add styles for custom source indicator --- ui/src/shared/components/LayoutCellHeader.js | 12 ++++++------ ui/src/style/pages/dashboards.scss | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ui/src/shared/components/LayoutCellHeader.js b/ui/src/shared/components/LayoutCellHeader.js index 6c70f531c1..ad028e0fb3 100644 --- a/ui/src/shared/components/LayoutCellHeader.js +++ b/ui/src/shared/components/LayoutCellHeader.js @@ -15,12 +15,12 @@ const LayoutCellHeader = ( s => s.links.self === _.get(queries, ['0', 'source'], null) ) + const headingClass = `dash-graph--heading ${isEditable + ? 'dash-graph--heading-draggable' + : ''}` + return ( -
+
{querySource && querySource.id !== defaultSource.id - ? + ? {querySource.name} : null} diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index b3761ec046..a631d39317 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -170,6 +170,21 @@ $dash-graph-options-arrow: 8px; right: 2px; } +.dash-graph--custom-source { + font-style: normal; + font-family: $code-font; + color: $c-pool; + background-color: $g2-kevlar; + height: 24px; + font-size: 10px; + line-height: 24px; + border-radius: 3px; + padding: 0 7px; + position: absolute; + top: 3px; + right: 86px; +} + .dash-graph-context { z-index: 2; position: absolute; From 1027b013626c2fc5594dcac4c9bb1e3aa3a3854b Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 2 Oct 2017 17:12:30 -0700 Subject: [PATCH 22/34] Move source selector to OverlayControls This move accomplishes a few things 1) It looks nicer 2) Can take advantage of the query error handling UI 3) Gives plenty of room for the dropdown --- .../components/CellEditorOverlay.js | 25 ++++++++--- .../dashboards/components/DisplayOptions.js | 45 ++++--------------- .../dashboards/components/OverlayControls.js | 21 ++++++--- .../dashboards/components/SourceSelector.js | 29 +++++------- ui/src/shared/components/LayoutCellHeader.js | 1 - ui/src/style/chronograf.scss | 1 + .../style/components/ceo-display-options.scss | 3 -- ui/src/style/components/source-selector.scss | 11 +++++ ui/src/style/pages/overlay-technology.scss | 11 +++++ 9 files changed, 80 insertions(+), 67 deletions(-) create mode 100644 ui/src/style/components/source-selector.scss diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index 4eadd853b9..590b4eb8b5 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -243,6 +243,20 @@ class CellEditorOverlay extends Component { text: `${s.name} @ ${s.url}`, })) + findSelectedSource = () => { + const {source} = this.props + const sources = this.formatSources + const query = _.get(this.state.queriesWorkingDraft, 0, false) + + if (!query || !query.source) { + const defaultSource = sources.find(s => s.id === source.id) + return (defaultSource && defaultSource.text) || 'No sources' + } + + const selected = sources.find(s => s.id === query.source.id) + return (selected && selected.text) || 'No sources' + } + render() { const { source, @@ -293,23 +307,24 @@ class CellEditorOverlay extends Component { /> {isDisplayOptionsTabActive ? { - const {source, sources} = this.props - const query = _.get(this.props.queryConfigs, 0, false) - - if (!query || !query.source) { - const defaultSource = sources.find(s => s.id === source.id) - return (defaultSource && defaultSource.text) || 'No sources' - } - - const selected = sources.find(s => s.id === query.source.id) - return (selected && selected.text) || 'No sources' - } - render() { const { - sources, onSetBase, onSetScale, onSetLabel, - onSetQuerySource, selectedGraphType, onSelectGraphType, onSetPrefixSuffix, @@ -64,22 +46,15 @@ class DisplayOptions extends Component { return (
-
- - -
+
-

Cell Editor

+
  • - Display Options + Options
@@ -41,7 +49,7 @@ const OverlayControls = ({
-const {func, bool} = PropTypes +const {arrayOf, bool, func, shape, string} = PropTypes OverlayControls.propTypes = { onCancel: func.isRequired, @@ -49,6 +57,9 @@ OverlayControls.propTypes = { isDisplayOptionsTabActive: bool.isRequired, onClickDisplayOptions: func.isRequired, isSavable: bool, + sources: arrayOf(shape()), + onSetQuerySource: func, + selected: string, } export default OverlayControls diff --git a/ui/src/dashboards/components/SourceSelector.js b/ui/src/dashboards/components/SourceSelector.js index 5cddcf1964..36ba1ccd84 100644 --- a/ui/src/dashboards/components/SourceSelector.js +++ b/ui/src/dashboards/components/SourceSelector.js @@ -2,23 +2,18 @@ import React, {PropTypes} from 'react' import Dropdown from 'shared/components/Dropdown' const SourceSelector = ({sources = [], selected, onSetQuerySource}) => -
-
InfluxDB Source Selector
-
- - -
+
+ {sources.length > 1 + ? + : null}
const {arrayOf, func, shape, string} = PropTypes diff --git a/ui/src/shared/components/LayoutCellHeader.js b/ui/src/shared/components/LayoutCellHeader.js index ad028e0fb3..2944533892 100644 --- a/ui/src/shared/components/LayoutCellHeader.js +++ b/ui/src/shared/components/LayoutCellHeader.js @@ -1,5 +1,4 @@ import React, {PropTypes} from 'react' -import classnames from 'classnames' import _ from 'lodash' import CustomTimeIndicator from 'shared/components/CustomTimeIndicator' diff --git a/ui/src/style/chronograf.scss b/ui/src/style/chronograf.scss index d7ec2232fc..2be5b0290f 100644 --- a/ui/src/style/chronograf.scss +++ b/ui/src/style/chronograf.scss @@ -50,6 +50,7 @@ @import 'components/resizer'; @import 'components/search-widget'; @import 'components/source-indicator'; +@import 'components/source-selector'; @import 'components/tables'; // Pages diff --git a/ui/src/style/components/ceo-display-options.scss b/ui/src/style/components/ceo-display-options.scss index e0abc0a2fe..44d77270d5 100644 --- a/ui/src/style/components/ceo-display-options.scss +++ b/ui/src/style/components/ceo-display-options.scss @@ -27,9 +27,6 @@ color: $g11-sidewalk; @include no-user-select(); } -.y-axis-controls { - margin-bottom: 8px; -} .viz-type-selector { display: flex; flex-wrap: wrap; diff --git a/ui/src/style/components/source-selector.scss b/ui/src/style/components/source-selector.scss new file mode 100644 index 0000000000..87739d863a --- /dev/null +++ b/ui/src/style/components/source-selector.scss @@ -0,0 +1,11 @@ +/* + Source Selector component styles + ---------------------------------------------------------------- +*/ + +.source-selector { + display: flex; + align-items: center; + flex-wrap: nowrap; + flex: 1 0 0; +} diff --git a/ui/src/style/pages/overlay-technology.scss b/ui/src/style/pages/overlay-technology.scss index 74c7fa6e6a..8cc608ac2d 100644 --- a/ui/src/style/pages/overlay-technology.scss +++ b/ui/src/style/pages/overlay-technology.scss @@ -44,10 +44,21 @@ $overlay-z: 100; border: 0; background-color: $g2-kevlar; } + .overlay-controls .nav-tablist { + width: 200px; + + li { + white-space: nowrap; + justify-content: center; + flex: 1 0 50%; + } + } .overlay-controls--right { display: flex; align-items: center; flex-wrap: nowrap; + justify-content: flex-end; + flex: 1 0 0; .toggle { margin: 0 0 0 5px; From 7ef74d792f52c75ca53d496f4222387b6805c16b Mon Sep 17 00:00:00 2001 From: Andrew Watkins Date: Mon, 2 Oct 2017 17:27:31 -0700 Subject: [PATCH 23/34] Add sweet styles --- .../shared/components/CustomTimeIndicator.js | 2 +- ui/src/shared/components/LayoutCellHeader.js | 18 +++++---- ui/src/style/pages/dashboards.scss | 39 +++++++------------ 3 files changed, 25 insertions(+), 34 deletions(-) diff --git a/ui/src/shared/components/CustomTimeIndicator.js b/ui/src/shared/components/CustomTimeIndicator.js index baad870a6f..16fd558364 100644 --- a/ui/src/shared/components/CustomTimeIndicator.js +++ b/ui/src/shared/components/CustomTimeIndicator.js @@ -15,7 +15,7 @@ const CustomTimeIndicator = ({queries}) => { : customLower return ( - + {customTimeRange} ) diff --git a/ui/src/shared/components/LayoutCellHeader.js b/ui/src/shared/components/LayoutCellHeader.js index 2944533892..fc5b5c6a16 100644 --- a/ui/src/shared/components/LayoutCellHeader.js +++ b/ui/src/shared/components/LayoutCellHeader.js @@ -27,15 +27,17 @@ const LayoutCellHeader = ( : 'dash-graph--name' } > - {querySource && querySource.id !== defaultSource.id - ? - {querySource.name} - - : null} {cellName} - {queries && queries.length - ? - : null} +
+ {querySource && querySource.id !== defaultSource.id + ? + {querySource.name} + + : null} + {queries && queries.length + ? + : null} +
) diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index a631d39317..459396cad6 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -154,37 +154,26 @@ $dash-graph-options-arrow: 8px; .dash-graph--name.dash-graph--name__default { font-style: italic; } - -.dash-graph--custom-time { - font-style: normal; - font-family: $code-font; - color: $c-pool; - background-color: $g2-kevlar; +.dash-graph--custom-indicators { height: 24px; - font-size: 10px; - line-height: 24px; border-radius: 3px; - padding: 0 7px; position: absolute; top: 3px; - right: 2px; -} + right: 0; + display: flex; -.dash-graph--custom-source { - font-style: normal; - font-family: $code-font; - color: $c-pool; - background-color: $g2-kevlar; - height: 24px; - font-size: 10px; - line-height: 24px; - border-radius: 3px; - padding: 0 7px; - position: absolute; - top: 3px; - right: 86px; + > .custom-indicator { + font-size: 10px; + line-height: 24px; + padding: 0 7px; + font-style: normal; + font-family: $code-font; + color: $c-pool; + background-color: $g2-kevlar; + margin-right: 2px; + border-radius: 3px; + } } - .dash-graph-context { z-index: 2; position: absolute; From 4d2a6b84928bdf84759241cb5caed374bb424214 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Tue, 3 Oct 2017 11:17:39 -0700 Subject: [PATCH 24/34] Add label to SourceSelector Signed-off-by: Alex Paxton --- ui/src/dashboards/components/SourceSelector.js | 11 ++++++----- ui/src/style/components/source-selector.scss | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ui/src/dashboards/components/SourceSelector.js b/ui/src/dashboards/components/SourceSelector.js index 36ba1ccd84..a9c1953bd2 100644 --- a/ui/src/dashboards/components/SourceSelector.js +++ b/ui/src/dashboards/components/SourceSelector.js @@ -2,9 +2,10 @@ import React, {PropTypes} from 'react' import Dropdown from 'shared/components/Dropdown' const SourceSelector = ({sources = [], selected, onSetQuerySource}) => -
- {sources.length > 1 - ? 1 + ?
+

Source:

+ onChoose={onSetQuerySource} className="dropdown-240" /> - : null} -
+
+ : null const {arrayOf, func, shape, string} = PropTypes diff --git a/ui/src/style/components/source-selector.scss b/ui/src/style/components/source-selector.scss index 87739d863a..13fcc48cd3 100644 --- a/ui/src/style/components/source-selector.scss +++ b/ui/src/style/components/source-selector.scss @@ -8,4 +8,11 @@ align-items: center; flex-wrap: nowrap; flex: 1 0 0; + + h3 { + margin: 0 4px 0 0; + font-size: 17px; + color: $g13-mist; + @include no-user-select(); + } } From 02e9b63501ad8a4263d55b9dfe2af863886f3ce4 Mon Sep 17 00:00:00 2001 From: Alex Paxton Date: Tue, 3 Oct 2017 11:45:48 -0700 Subject: [PATCH 25/34] Use context to display source name, host, and port in SourceIndicator Refactor SourceIndicator into SFC Signed-off-by: Jared Scheib --- ui/src/shared/components/SourceIndicator.js | 60 +++++++++++---------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/ui/src/shared/components/SourceIndicator.js b/ui/src/shared/components/SourceIndicator.js index 1abaa5af39..65c862efe2 100644 --- a/ui/src/shared/components/SourceIndicator.js +++ b/ui/src/shared/components/SourceIndicator.js @@ -1,35 +1,37 @@ import React, {PropTypes} from 'react' import ReactTooltip from 'react-tooltip' -const SourceIndicator = React.createClass({ - propTypes: { - sourceName: PropTypes.string, - }, +const SourceIndicator = (_, {source: {name: sourceName, url}}) => { + if (!sourceName) { + return null + } + const sourceNameTooltip = `Connected to ${sourceName} @ ${url}` + return ( +
+ + +
+ ) +} - render() { - const {sourceName} = this.props - if (!sourceName) { - return null - } - const sourceNameTooltip = `Connected to ${sourceName}` - return ( -
- - -
- ) - }, -}) +const {shape, string} = PropTypes + +SourceIndicator.contextTypes = { + source: shape({ + name: string, + url: string, + }), +} export default SourceIndicator From 37c3a1948e4807003f15206162cc299a0cd98d85 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Tue, 3 Oct 2017 11:52:26 -0700 Subject: [PATCH 26/34] Remove passed-in props from all SourceIndicator instances Signed-off-by: Alex Paxton --- ui/src/admin/containers/AdminPage.js | 2 +- ui/src/alerts/containers/AlertsApp.js | 2 +- .../dashboards/components/DashboardHeader.js | 5 +--- .../dashboards/components/DashboardsHeader.js | 29 +++++++------------ ui/src/data_explorer/containers/Header.js | 8 +---- ui/src/hosts/containers/HostsPage.js | 2 +- ui/src/kapacitor/components/KapacitorRules.js | 5 ++-- ui/src/kapacitor/components/RuleHeaderSave.js | 4 +-- .../kapacitor/components/TickscriptHeader.js | 4 +-- ui/src/sources/containers/ManageSources.js | 2 +- ui/src/sources/containers/SourcePage.js | 2 +- ui/src/status/containers/StatusPage.js | 2 +- 12 files changed, 22 insertions(+), 45 deletions(-) diff --git a/ui/src/admin/containers/AdminPage.js b/ui/src/admin/containers/AdminPage.js index de4e936b96..65e448d469 100644 --- a/ui/src/admin/containers/AdminPage.js +++ b/ui/src/admin/containers/AdminPage.js @@ -154,7 +154,7 @@ class AdminPage extends Component {

Admin

- +
diff --git a/ui/src/alerts/containers/AlertsApp.js b/ui/src/alerts/containers/AlertsApp.js index 34140b11f4..16330dbabb 100644 --- a/ui/src/alerts/containers/AlertsApp.js +++ b/ui/src/alerts/containers/AlertsApp.js @@ -156,7 +156,7 @@ class AlertsApp extends Component {

Alert History

- +
- + {dashboard ?
diff --git a/ui/src/sources/containers/SourcePage.js b/ui/src/sources/containers/SourcePage.js index 0cf5d1cf68..d407203812 100644 --- a/ui/src/sources/containers/SourcePage.js +++ b/ui/src/sources/containers/SourcePage.js @@ -125,7 +125,7 @@ export const SourcePage = React.createClass({
- +
diff --git a/ui/src/status/containers/StatusPage.js b/ui/src/status/containers/StatusPage.js index 5e07241d4c..50974161de 100644 --- a/ui/src/status/containers/StatusPage.js +++ b/ui/src/status/containers/StatusPage.js @@ -56,7 +56,7 @@ class StatusPage extends Component {

Status

- +
From 9fda754042dd3a9dd571a6f6dcb74c83dc9ed466 Mon Sep 17 00:00:00 2001 From: Alex Paxton Date: Tue, 3 Oct 2017 12:16:08 -0700 Subject: [PATCH 27/34] Allow a source override on SourceIndicator Use SourceIndicator server icon with tooltip on cells Signed-off-by: Jared Scheib --- ui/src/shared/components/LayoutCellHeader.js | 5 ++--- ui/src/shared/components/SourceIndicator.js | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ui/src/shared/components/LayoutCellHeader.js b/ui/src/shared/components/LayoutCellHeader.js index fc5b5c6a16..6149c83767 100644 --- a/ui/src/shared/components/LayoutCellHeader.js +++ b/ui/src/shared/components/LayoutCellHeader.js @@ -1,6 +1,7 @@ import React, {PropTypes} from 'react' import _ from 'lodash' +import SourceIndicator from 'shared/components/SourceIndicator' import CustomTimeIndicator from 'shared/components/CustomTimeIndicator' import {NEW_DEFAULT_DASHBOARD_CELL} from 'src/dashboards/constants/index' @@ -30,9 +31,7 @@ const LayoutCellHeader = ( {cellName}
{querySource && querySource.id !== defaultSource.id - ? - {querySource.name} - + ? : null} {queries && queries.length ? diff --git a/ui/src/shared/components/SourceIndicator.js b/ui/src/shared/components/SourceIndicator.js index 65c862efe2..9263871927 100644 --- a/ui/src/shared/components/SourceIndicator.js +++ b/ui/src/shared/components/SourceIndicator.js @@ -1,11 +1,19 @@ import React, {PropTypes} from 'react' +import _ from 'lodash' import ReactTooltip from 'react-tooltip' -const SourceIndicator = (_, {source: {name: sourceName, url}}) => { +const SourceIndicator = ({sourceOverride}, {source: {name, url}}) => { + const sourceName = _.get(sourceOverride, 'name', null) + ? sourceOverride.name + : name + const sourceUrl = _.get(sourceOverride, 'url', null) + ? sourceOverride.url + : url + if (!sourceName) { return null } - const sourceNameTooltip = `Connected to ${sourceName} @ ${url}` + const sourceNameTooltip = `Connected to ${sourceName} @ ${sourceUrl}` return (
{ const {shape, string} = PropTypes +SourceIndicator.propTypes = { + sourceOverride: shape({ + name: string, + url: string, + }), +} + SourceIndicator.contextTypes = { source: shape({ name: string, From 948fc750495efefb1109877eceb9e0c346ada56d Mon Sep 17 00:00:00 2001 From: Alex Paxton Date: Tue, 3 Oct 2017 12:31:56 -0700 Subject: [PATCH 28/34] Update CSS page syntax formatting Signed-off-by: Jared Scheib --- ui/src/style/pages/dashboards.scss | 109 +++++++++++++++++++---------- 1 file changed, 72 insertions(+), 37 deletions(-) diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index 459396cad6..49ac6e70bd 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -11,22 +11,49 @@ $dash-graph-options-arrow: 8px; ------------------------------------------------------ */ @keyframes refreshingSpinnerA { - 0% { transform: translate(-50%,-50%) scale(1.75); background-color: $g7-graphite; } - 33% { transform: translate(-50%,-50%) scale(1,1); } - 66% { transform: translate(-50%,-50%) scale(1,1); } - 100% { transform: translate(-50%,-50%) scale(1,1); } + 0% { + transform: translate(-50%, -50%) scale(1.75); + background-color: $g7-graphite; + } + 33% { + transform: translate(-50%, -50%) scale(1, 1); + } + 66% { + transform: translate(-50%, -50%) scale(1, 1); + } + 100% { + transform: translate(-50%, -50%) scale(1, 1); + } } @keyframes refreshingSpinnerB { - 0% { transform: translate(-50%,-50%) scale(1,1); } - 33% { transform: translate(-50%,-50%) scale(1.75); background-color: $g7-graphite; } - 66% { transform: translate(-50%,-50%) scale(1,1); } - 100% { transform: translate(-50%,-50%) scale(1,1); } + 0% { + transform: translate(-50%, -50%) scale(1, 1); + } + 33% { + transform: translate(-50%, -50%) scale(1.75); + background-color: $g7-graphite; + } + 66% { + transform: translate(-50%, -50%) scale(1, 1); + } + 100% { + transform: translate(-50%, -50%) scale(1, 1); + } } @keyframes refreshingSpinnerC { - 0% { transform: translate(-50%,-50%) scale(1,1); } - 33% { transform: translate(-50%,-50%) scale(1,1); } - 66% { transform: translate(-50%,-50%) scale(1.75); background-color: $g7-graphite; } - 100% { transform: translate(-50%,-50%) scale(1,1); } + 0% { + transform: translate(-50%, -50%) scale(1, 1); + } + 33% { + transform: translate(-50%, -50%) scale(1, 1); + } + 66% { + transform: translate(-50%, -50%) scale(1.75); + background-color: $g7-graphite; + } + 100% { + transform: translate(-50%, -50%) scale(1, 1); + } } /* @@ -93,7 +120,6 @@ $dash-graph-options-arrow: 8px; top: 0; width: 100%; height: 100%; - } .dygraph .dygraph-child { position: absolute; @@ -124,9 +150,7 @@ $dash-graph-options-arrow: 8px; font-weight: 600; font-size: 13px; color: $g14-chromium; - transition: - color 0.25s ease, - background-color 0.25s ease; + transition: color 0.25s ease, background-color 0.25s ease; &.dash-graph--heading-draggable:hover { cursor: move; background-color: $g5-pepper; @@ -146,9 +170,7 @@ $dash-graph-options-arrow: 8px; line-height: $dash-graph-heading; width: calc(100% - 53px); padding-left: 10px; - transition: - color 0.25s ease, - background-color 0.25s ease, + transition: color 0.25s ease, background-color 0.25s ease, border-color 0.25s ease; } .dash-graph--name.dash-graph--name__default { @@ -191,9 +213,7 @@ $dash-graph-options-arrow: 8px; font-size: 12px; position: relative; color: $g11-sidewalk; - transition: - color 0.25s ease, - background-color 0.25s ease; + transition: color 0.25s ease, background-color 0.25s ease; &:hover, &.active { @@ -201,13 +221,15 @@ $dash-graph-options-arrow: 8px; color: $g20-white; background-color: $g5-pepper; } - &:first-child {margin-right: 2px;} + &:first-child { + margin-right: 2px; + } > .icon { position: absolute; top: 50%; left: 50%; - transform: translate(-50%,-50%); + transform: translate(-50%, -50%); } } .dash-graph-context--confirm { @@ -234,7 +256,7 @@ $dash-graph-options-arrow: 8px; border-bottom-color: $c-curacao; left: 50%; top: 0; - transform: translate(-50%,-100%); + transform: translate(-50%, -100%); transition: border-color 0.25s ease; } @@ -245,7 +267,6 @@ $dash-graph-options-arrow: 8px; &:hover:before { border-bottom-color: $c-dreamsicle; } - } /* Presentation Mode */ @@ -261,7 +282,7 @@ $dash-graph-options-arrow: 8px; .graph-panel__refreshing { position: absolute; top: -18px !important; - transform: translate(0,0); + transform: translate(0, 0); right: 50%; transform: translateX(50%); width: 16px; @@ -274,12 +295,24 @@ $dash-graph-options-arrow: 8px; border-radius: 50%; position: absolute; top: 50%; - transform: translate(-50%,-50%); + transform: translate(-50%, -50%); } - div:nth-child(1) {left: 0; animation: refreshingSpinnerA 0.8s cubic-bezier(0.645, 0.045, 0.355, 1) infinite; } - div:nth-child(2) {left: 50%; animation: refreshingSpinnerB 0.8s cubic-bezier(0.645, 0.045, 0.355, 1) infinite; } - div:nth-child(3) {left: 100%; animation: refreshingSpinnerC 0.8s cubic-bezier(0.645, 0.045, 0.355, 1) infinite;} + div:nth-child(1) { + left: 0; + animation: refreshingSpinnerA 0.8s cubic-bezier(0.645, 0.045, 0.355, 1) + infinite; + } + div:nth-child(2) { + left: 50%; + animation: refreshingSpinnerB 0.8s cubic-bezier(0.645, 0.045, 0.355, 1) + infinite; + } + div:nth-child(3) { + left: 100%; + animation: refreshingSpinnerC 0.8s cubic-bezier(0.645, 0.045, 0.355, 1) + infinite; + } } /* @@ -295,7 +328,7 @@ $dash-graph-options-arrow: 8px; } .react-grid-item { &.resizing { - background-color: fade-out($g3-castle,0.09); + background-color: fade-out($g3-castle, 0.09); border-color: $c-pool; border-image-slice: 3%; border-image-repeat: initial; @@ -305,13 +338,14 @@ $dash-graph-options-arrow: 8px; z-index: 3; & > .react-resizable-handle { - &:before, &:after { + &:before, + &:after { background-color: $c-comet; } } } &.react-draggable-dragging { - background-color: fade-out($g3-castle,0.09); + background-color: fade-out($g3-castle, 0.09); border-color: $c-pool; border-image-slice: 3%; border-image-repeat: initial; @@ -345,14 +379,15 @@ $dash-graph-options-arrow: 8px; } &:before { width: 20px; - transform: translate(-50%,-50%) rotate(-45deg); + transform: translate(-50%, -50%) rotate(-45deg); } &:after { width: 12px; - transform: translate(-3px,2px) rotate(-45deg); + transform: translate(-3px, 2px) rotate(-45deg); } &:hover { - &:before, &:after { + &:before, + &:after { background-color: $c-comet; } } From 33a3eea9ed18ecd592185b674bebb7d7978d4319 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Tue, 3 Oct 2017 12:32:40 -0700 Subject: [PATCH 29/34] Style SourceIndicator in LayoutCellHeader Signed-off-by: Alex Paxton --- ui/src/style/pages/dashboards.scss | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index 49ac6e70bd..f0b07700c0 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -184,7 +184,8 @@ $dash-graph-options-arrow: 8px; right: 0; display: flex; - > .custom-indicator { + > .custom-indicator, + > .source-indicator { font-size: 10px; line-height: 24px; padding: 0 7px; @@ -195,6 +196,14 @@ $dash-graph-options-arrow: 8px; margin-right: 2px; border-radius: 3px; } + > .source-indicator { + height: 24px; + + > .icon { + font-size: 12px; + margin: 0; + } + } } .dash-graph-context { z-index: 2; From 08a1af020f60b3c961408273a36fed8ce85dfe16 Mon Sep 17 00:00:00 2001 From: Alex Paxton Date: Tue, 3 Oct 2017 12:55:29 -0700 Subject: [PATCH 30/34] Dedupe and polish Tooltip styles Signed-off-by: Jared Scheib --- ui/src/shared/components/GraphTips.js | 2 +- ui/src/shared/components/SourceIndicator.js | 10 +++++++--- ui/src/style/components/react-tooltips.scss | 20 ++++++++++++------- ui/src/style/components/source-indicator.scss | 2 +- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/ui/src/shared/components/GraphTips.js b/ui/src/shared/components/GraphTips.js index 5ff4d3e638..edf0193b78 100644 --- a/ui/src/shared/components/GraphTips.js +++ b/ui/src/shared/components/GraphTips.js @@ -4,7 +4,7 @@ import ReactTooltip from 'react-tooltip' const GraphTips = React.createClass({ render() { const graphTipsText = - '

Graph Tips:

Click + Drag Zoom in (X or Y)

Shift + Click Pan Graph Window

Double Click Reset Graph Window

' + '

Graph Tips:

Click + Drag Zoom in (X or Y)

Shift + Click Pan Graph Window

Double Click Reset Graph Window

' return (
{ @@ -13,16 +15,18 @@ const SourceIndicator = ({sourceOverride}, {source: {name, url}}) => { if (!sourceName) { return null } - const sourceNameTooltip = `Connected to ${sourceName} @ ${sourceUrl}` + const sourceNameTooltip = `

Connected to Source:

${sourceName} @ ${sourceUrl}

` + const uuidTooltip = uuid.v4() + return (
Date: Tue, 3 Oct 2017 14:21:23 -0700 Subject: [PATCH 31/34] Remove source from DisplayOptions --- ui/src/dashboards/components/CellEditorOverlay.js | 1 - ui/src/dashboards/components/DisplayOptions.js | 1 - 2 files changed, 2 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index 590b4eb8b5..e9b881fc88 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -319,7 +319,6 @@ class CellEditorOverlay extends Component { {isDisplayOptionsTabActive ? Date: Tue, 3 Oct 2017 15:36:44 -0700 Subject: [PATCH 32/34] Get new dbs, rps, meas, fields etc when selecting a new source --- .../components/CellEditorOverlay.js | 15 ++++++++-- ui/src/dashboards/components/QueryMaker.js | 5 ++-- ui/src/shared/components/DatabaseList.js | 28 ++++++++++++++++++- ui/src/shared/components/FieldList.js | 24 ++++++++++------ ui/src/shared/components/MeasurementList.js | 25 +++++++++++++++-- ui/src/shared/components/SchemaExplorer.js | 7 +++++ 6 files changed, 87 insertions(+), 17 deletions(-) diff --git a/ui/src/dashboards/components/CellEditorOverlay.js b/ui/src/dashboards/components/CellEditorOverlay.js index e9b881fc88..1d5963ff7f 100644 --- a/ui/src/dashboards/components/CellEditorOverlay.js +++ b/ui/src/dashboards/components/CellEditorOverlay.js @@ -257,9 +257,20 @@ class CellEditorOverlay extends Component { return (selected && selected.text) || 'No sources' } + getSource = () => { + const {source, sources} = this.props + const query = _.get(this.state.queriesWorkingDraft, 0, false) + + if (!query || !query.source) { + return source + } + + const querySource = sources.find(s => s.id === query.source.id) + return querySource || source + } + render() { const { - source, onCancel, templates, timeRange, @@ -330,7 +341,7 @@ class CellEditorOverlay extends Component { onSetYAxisBoundMax={this.handleSetYAxisBoundMax} /> : q.rawText || buildInfluxQLQuery(q.range || TEMPLATE_RANGE, q) || '' const QueryMaker = ({ - source: {links}, + source, actions, queries, timeRange, @@ -39,7 +39,7 @@ const QueryMaker = ({ query={buildText(activeQuery)} config={activeQuery} onUpdate={rawTextBinder( - links, + source.links, activeQuery.id, actions.editRawTextAsync )} @@ -49,6 +49,7 @@ const QueryMaker = ({ query={activeQuery} actions={actions} onAddQuery={onAddQuery} + source={source} />
: } diff --git a/ui/src/shared/components/DatabaseList.js b/ui/src/shared/components/DatabaseList.js index 2c84392bfb..076cbdfdc6 100644 --- a/ui/src/shared/components/DatabaseList.js +++ b/ui/src/shared/components/DatabaseList.js @@ -14,6 +14,17 @@ const DatabaseList = React.createClass({ propTypes: { query: shape({}).isRequired, onChooseNamespace: func.isRequired, + querySource: shape({ + links: shape({ + proxy: string.isRequired, + }).isRequired, + }), + }, + + getDefaultProps() { + return { + source: null, + } }, contextTypes: { @@ -31,8 +42,23 @@ const DatabaseList = React.createClass({ }, componentDidMount() { + this.getDbRp() + }, + + componentDidUpdate(prevProps) { + if (_.isEqual(prevProps.querySource, this.props.querySource)) { + return + } + + this.getDbRp() + }, + + getDbRp() { const {source} = this.context - const proxy = source.links.proxy + const {querySource} = this.props + const proxy = + _.get(querySource, ['links', 'proxy'], null) || source.links.proxy + showDatabases(proxy).then(resp => { const {errors, databases} = showDatabasesParser(resp.data) if (errors.length) { diff --git a/ui/src/shared/components/FieldList.js b/ui/src/shared/components/FieldList.js index 79607635c7..918cdf994d 100644 --- a/ui/src/shared/components/FieldList.js +++ b/ui/src/shared/components/FieldList.js @@ -1,4 +1,5 @@ import React, {PropTypes, Component} from 'react' +import _ from 'lodash' import FieldListItem from 'src/data_explorer/components/FieldListItem' import GroupByTimeDropdown from 'src/data_explorer/components/GroupByTimeDropdown' @@ -26,7 +27,8 @@ class FieldList extends Component { } componentDidUpdate(prevProps) { - const {database, measurement, retentionPolicy} = this.props.query + const {querySource, query} = this.props + const {database, measurement, retentionPolicy} = query const { database: prevDB, measurement: prevMeas, @@ -39,7 +41,8 @@ class FieldList extends Component { if ( database === prevDB && measurement === prevMeas && - retentionPolicy === prevRP + retentionPolicy === prevRP && + _.isEqual(prevProps.querySource, querySource) ) { return } @@ -58,14 +61,12 @@ class FieldList extends Component { _getFields = () => { const {database, measurement, retentionPolicy} = this.props.query const {source} = this.context - const proxySource = source.links.proxy + const {querySource} = this.props - showFieldKeys( - proxySource, - database, - measurement, - retentionPolicy - ).then(resp => { + const proxy = + _.get(querySource, ['links', 'proxy'], null) || source.links.proxy + + showFieldKeys(proxy, database, measurement, retentionPolicy).then(resp => { const {errors, fieldSets} = showFieldKeysParser(resp.data) if (errors.length) { console.error('Error parsing fields keys: ', errors) @@ -171,6 +172,11 @@ FieldList.propTypes = { applyFuncsToField: func.isRequired, isKapacitorRule: bool, isInDataExplorer: bool, + querySource: shape({ + links: shape({ + proxy: string.isRequired, + }).isRequired, + }), } export default FieldList diff --git a/ui/src/shared/components/MeasurementList.js b/ui/src/shared/components/MeasurementList.js index 5b9b993a3a..8b87abc0d9 100644 --- a/ui/src/shared/components/MeasurementList.js +++ b/ui/src/shared/components/MeasurementList.js @@ -1,5 +1,6 @@ import React, {PropTypes} from 'react' import classnames from 'classnames' +import _ from 'lodash' import {showMeasurements} from 'shared/apis/metaQuery' import showMeasurementsParser from 'shared/parsing/showMeasurements' @@ -19,6 +20,11 @@ const MeasurementList = React.createClass({ onChooseTag: func.isRequired, onToggleTagAcceptance: func.isRequired, onGroupByTag: func.isRequired, + querySource: shape({ + links: shape({ + proxy: string.isRequired, + }).isRequired, + }), }, contextTypes: { @@ -36,6 +42,12 @@ const MeasurementList = React.createClass({ } }, + getDefaultProps() { + return { + querySource: null, + } + }, + componentDidMount() { if (!this.props.query.database) { return @@ -45,13 +57,16 @@ const MeasurementList = React.createClass({ }, componentDidUpdate(prevProps) { - const {query} = this.props + const {query, querySource} = this.props if (!query.database) { return } - if (prevProps.query.database === query.database) { + if ( + prevProps.query.database === query.database && + _.isEqual(prevProps.querySource, querySource) + ) { return } @@ -181,7 +196,11 @@ const MeasurementList = React.createClass({ _getMeasurements() { const {source} = this.context - const proxy = source.links.proxy + const {querySource} = this.props + + const proxy = + _.get(querySource, ['links', 'proxy'], null) || source.links.proxy + showMeasurements(proxy, this.props.query.database).then(resp => { const {errors, measurementSets} = showMeasurementsParser(resp.data) if (errors.length) { diff --git a/ui/src/shared/components/SchemaExplorer.js b/ui/src/shared/components/SchemaExplorer.js index 2572952e61..ebf5cfac33 100644 --- a/ui/src/shared/components/SchemaExplorer.js +++ b/ui/src/shared/components/SchemaExplorer.js @@ -9,6 +9,7 @@ const actionBinder = (id, action) => item => action(id, item) const SchemaExplorer = ({ query, query: {id}, + source, actions: { chooseTag, groupByTag, @@ -24,17 +25,22 @@ const SchemaExplorer = ({
Date: Tue, 3 Oct 2017 15:45:06 -0700 Subject: [PATCH 33/34] Remove source indicator from cell header --- ui/src/shared/components/Layout.js | 1 - ui/src/shared/components/LayoutCell.js | 5 +---- ui/src/shared/components/LayoutCellHeader.js | 18 +----------------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/ui/src/shared/components/Layout.js b/ui/src/shared/components/Layout.js index 96d503e529..b1f3970e5c 100644 --- a/ui/src/shared/components/Layout.js +++ b/ui/src/shared/components/Layout.js @@ -38,7 +38,6 @@ const Layout = ( ) => @@ -81,7 +79,6 @@ LayoutCell.propTypes = { y: number.isRequired, queries: arrayOf(shape()), }).isRequired, - sources: arrayOf(shape()), children: node.isRequired, onDeleteCell: func, onSummonOverlayTechnologies: func, diff --git a/ui/src/shared/components/LayoutCellHeader.js b/ui/src/shared/components/LayoutCellHeader.js index 6149c83767..01300cc77a 100644 --- a/ui/src/shared/components/LayoutCellHeader.js +++ b/ui/src/shared/components/LayoutCellHeader.js @@ -1,19 +1,11 @@ import React, {PropTypes} from 'react' -import _ from 'lodash' -import SourceIndicator from 'shared/components/SourceIndicator' import CustomTimeIndicator from 'shared/components/CustomTimeIndicator' import {NEW_DEFAULT_DASHBOARD_CELL} from 'src/dashboards/constants/index' -const LayoutCellHeader = ( - {queries, isEditable, cellName, sources = []}, - {source: defaultSource} -) => { +const LayoutCellHeader = ({queries, isEditable, cellName}) => { const cellNameIsDefault = cellName === NEW_DEFAULT_DASHBOARD_CELL.name - const querySource = sources.find( - s => s.links.self === _.get(queries, ['0', 'source'], null) - ) const headingClass = `dash-graph--heading ${isEditable ? 'dash-graph--heading-draggable' @@ -30,9 +22,6 @@ const LayoutCellHeader = ( > {cellName}
- {querySource && querySource.id !== defaultSource.id - ? - : null} {queries && queries.length ? : null} @@ -44,15 +33,10 @@ const LayoutCellHeader = ( const {arrayOf, bool, shape, string} = PropTypes -LayoutCellHeader.contextTypes = { - source: shape({}), -} - LayoutCellHeader.propTypes = { queries: arrayOf(shape()), isEditable: bool, cellName: string, - sources: arrayOf(shape()), } export default LayoutCellHeader From d30143377ac623d4f08b0f9db2e3ef4a433b96ac Mon Sep 17 00:00:00 2001 From: deniz kusefoglu Date: Tue, 3 Oct 2017 15:55:57 -0700 Subject: [PATCH 34/34] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b42c6a497..fb9ba1b6bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ 1.[#2015](https://github.com/influxdata/chronograf/pull/2015): Chronograf shows real status for windows hosts when metrics are saved in non-default db - thank you, @ar7z1! 1.[#2019](https://github.com/influxdata/chronograf/pull/2006): Fix false error warning for duplicate kapacitor name 1.[#2018](https://github.com/influxdata/chronograf/pull/2018): Fix unresponsive display options and query builder in dashboards +1.[#1996](https://github.com/influxdata/chronograf/pull/1996): Able to switch InfluxDB sources on a per graph basis ### Features 1. [#1885](https://github.com/influxdata/chronograf/pull/1885): Add `fill` options to data explorer and dashboard queries