diff --git a/chronograf.go b/chronograf.go index e3f5416514..57f7812ce9 100644 --- a/chronograf.go +++ b/chronograf.go @@ -194,7 +194,6 @@ type TemplateQuery struct { RP string `json:"rp,omitempty"` // RP is a retention policy and optional; if empty will not be used. Measurement string `json:"measurement"` // Measurement is the optinally selected measurement for the query TagKey string `json:"tagKey"` // TagKey is the optionally selected tag key for the query - FieldKey string `json:"fieldKey"` // FieldKey is the optionally selected field key for the query } // Response is the result of a query against a TimeSeries diff --git a/ui/spec/dashboards/reducers/uiSpec.js b/ui/spec/dashboards/reducers/uiSpec.js index 8abdc39f16..40e96c5526 100644 --- a/ui/spec/dashboards/reducers/uiSpec.js +++ b/ui/spec/dashboards/reducers/uiSpec.js @@ -10,8 +10,8 @@ import { editDashboardCell, renameDashboardCell, syncDashboardCell, - editTemplate, - templateSelected, + templateVariableEdited, + templateVariableSelected, } from 'src/dashboards/actions' let state @@ -174,17 +174,23 @@ describe('DataExplorer.Reducers.UI', () => { } const expected = {...tempVar, ...updates} - const actual = reducer(state, editTemplate(dash.id, tempVar.id, updates)) + const actual = reducer( + state, + templateVariableEdited(dash.id, tempVar.id, updates) + ) expect(actual.dashboards[0].templates[0]).to.deep.equal(expected) }) it('can select a different template variable', () => { const dash = _.cloneDeep(d1) state = { - dashboards: [dash] + dashboards: [dash], } const value = dash.templates[0].values[2].value - const actual = reducer({dashboards}, templateSelected(dash.id, dash.templates[0].id, [{value}])) + const actual = reducer( + {dashboards}, + templateVariableSelected(dash.id, dash.templates[0].id, [{value}]) + ) expect(actual.dashboards[0].templates[0].values[0].selected).to.equal(false) expect(actual.dashboards[0].templates[0].values[1].selected).to.equal(false) diff --git a/ui/src/dashboards/actions/index.js b/ui/src/dashboards/actions/index.js index fa63c23d95..f847bb6582 100644 --- a/ui/src/dashboards/actions/index.js +++ b/ui/src/dashboards/actions/index.js @@ -113,7 +113,7 @@ export const editCellQueryStatus = (queryID, status) => ({ }, }) -export const templateSelected = (dashboardID, templateID, values) => ({ +export const templateVariableSelected = (dashboardID, templateID, values) => ({ type: TEMPLATE_VARIABLE_SELECTED, payload: { dashboardID, @@ -122,8 +122,8 @@ export const templateSelected = (dashboardID, templateID, values) => ({ }, }) -export const editTemplate = (dashboardID, templateID, updates) => ({ - type: 'EDIT_TEMPLATE', +export const templateVariableEdited = (dashboardID, templateID, updates) => ({ + type: 'TEMPLATE_VARIABLE_EDITED', payload: { dashboardID, templateID, diff --git a/ui/src/dashboards/components/DatabaseDropdown.js b/ui/src/dashboards/components/DatabaseDropdown.js index 3dfed80984..abc319c2c3 100644 --- a/ui/src/dashboards/components/DatabaseDropdown.js +++ b/ui/src/dashboards/components/DatabaseDropdown.js @@ -28,13 +28,19 @@ class DatabaseDropdown extends Component { render() { const {databases} = this.state - const {database, onSelectDatabase} = this.props + const {database, onSelectDatabase, onStartEdit} = this.props + + // :( + if (!database) { + this.componentDidMount() + } return ( ({text}))} - selected={database} + selected={database || 'Loading...'} onChoose={onSelectDatabase} + onClick={() => onStartEdit(null)} /> ) } @@ -53,6 +59,7 @@ DatabaseDropdown.contextTypes = { DatabaseDropdown.propTypes = { database: string, onSelectDatabase: func.isRequired, + onStartEdit: func.isRequired, } export default DatabaseDropdown diff --git a/ui/src/dashboards/components/MeasurementDropdown.js b/ui/src/dashboards/components/MeasurementDropdown.js index ce18ae0973..d111d34e25 100644 --- a/ui/src/dashboards/components/MeasurementDropdown.js +++ b/ui/src/dashboards/components/MeasurementDropdown.js @@ -29,12 +29,13 @@ class MeasurementDropdown extends Component { render() { const {measurements} = this.state - const {measurement, onSelectMeasurement} = this.props + const {measurement, onSelectMeasurement, onStartEdit} = this.props return ( ({text}))} selected={measurement || 'Select Measurement'} onChoose={onSelectMeasurement} + onClick={() => onStartEdit(null)} /> ) } @@ -71,6 +72,7 @@ MeasurementDropdown.propTypes = { database: string.isRequired, measurement: string, onSelectMeasurement: func.isRequired, + onStartEdit: func.isRequired, } export default MeasurementDropdown diff --git a/ui/src/dashboards/components/TagKeyDropdown.js b/ui/src/dashboards/components/TagKeyDropdown.js index cab6ce9001..2838806686 100644 --- a/ui/src/dashboards/components/TagKeyDropdown.js +++ b/ui/src/dashboards/components/TagKeyDropdown.js @@ -31,12 +31,13 @@ class TagKeyDropdown extends Component { render() { const {tagKeys} = this.state - const {tagKey, onSelectTagKey} = this.props + const {tagKey, onSelectTagKey, onStartEdit} = this.props return ( ({text}))} selected={tagKey || 'Select Tag Key'} onChoose={onSelectTagKey} + onClick={() => onStartEdit(null)} /> ) } @@ -69,6 +70,7 @@ TagKeyDropdown.propTypes = { measurement: string.isRequired, tagKey: string, onSelectTagKey: func.isRequired, + onStartEdit: func.isRequired, } export default TagKeyDropdown diff --git a/ui/src/dashboards/components/TemplateQueryBuilder.js b/ui/src/dashboards/components/TemplateQueryBuilder.js index 2aa238c584..af85b066c3 100644 --- a/ui/src/dashboards/components/TemplateQueryBuilder.js +++ b/ui/src/dashboards/components/TemplateQueryBuilder.js @@ -11,6 +11,7 @@ const TemplateQueryBuilder = ({ onSelectDatabase, onSelectMeasurement, onSelectTagKey, + onStartEdit, }) => { switch (selectedType) { case 'csv': @@ -24,17 +25,19 @@ const TemplateQueryBuilder = ({ ) - case 'fields': + case 'fieldKeys': case 'tagKeys': return (
- SHOW {selectedType === 'fields' ? 'FIELD' : 'TAG'} KEYS ON + SHOW {selectedType === 'fieldKeys' ? 'FIELD' : 'TAG'} KEYS ON FROM {selectedDatabase @@ -42,8 +45,9 @@ const TemplateQueryBuilder = ({ database={selectedDatabase} measurement={selectedMeasurement} onSelectMeasurement={onSelectMeasurement} + onStartEdit={onStartEdit} /> - : 'Pick a DB'} + :
No database selected
}
) case 'tagValues': @@ -53,6 +57,7 @@ const TemplateQueryBuilder = ({ FROM {selectedDatabase @@ -60,6 +65,7 @@ const TemplateQueryBuilder = ({ database={selectedDatabase} measurement={selectedMeasurement} onSelectMeasurement={onSelectMeasurement} + onStartEdit={onStartEdit} /> : 'Pick a DB'} WITH KEY = @@ -69,6 +75,7 @@ const TemplateQueryBuilder = ({ measurement={selectedMeasurement} tagKey={selectedTagKey} onSelectTagKey={onSelectTagKey} + onStartEdit={onStartEdit} /> : 'Pick a Tag Key'} @@ -85,6 +92,7 @@ TemplateQueryBuilder.propTypes = { onSelectDatabase: func.isRequired, onSelectMeasurement: func.isRequired, onSelectTagKey: func.isRequired, + onStartEdit: func.isRequired, selectedMeasurement: string, selectedDatabase: string, selectedTagKey: string, diff --git a/ui/src/dashboards/components/TemplateVariableManager.js b/ui/src/dashboards/components/TemplateVariableManager.js index a76c6a4675..43c93ec450 100644 --- a/ui/src/dashboards/components/TemplateVariableManager.js +++ b/ui/src/dashboards/components/TemplateVariableManager.js @@ -10,8 +10,7 @@ const TemplateVariableManager = ({onClose, templates}) => ( Template Variables
- - + ( -
+
t.type === selectedType).text - } + onClick={() => onStartEdit(null)} + selected={TEMPLATE_TYPES.find(t => t.type === selectedType).text} className={'template-variable--dropdown'} />
@@ -56,6 +66,7 @@ const TemplateVariableRow = ({ selectedMeasurement={selectedMeasurement} selectedTagKey={selectedTagKey} onSelectTagKey={onSelectTagKey} + onStartEdit={onStartEdit} />
@@ -70,7 +81,7 @@ const TemplateVariableRow = ({ @@ -122,31 +133,65 @@ class RowWrapper extends Component { this.handleSelectMeasurement = ::this.handleSelectMeasurement this.handleSelectTagKey = ::this.handleSelectTagKey this.handleStartEdit = ::this.handleStartEdit - this.handleEndEdit = ::this.handleEndEdit + this.handleCancelEdit = ::this.handleCancelEdit } - handleSubmit(e) { - e.preventDefault() - // const tempVar = e.target.tempVar.value - // const label = e.target.label.value + handleSubmit( + { + selectedDatabase: database, + selectedMeasurement: measurement, + selectedTagKey: tagKey, + selectedType: type, + }, + id + ) { + return e => { + e.preventDefault() - // updateTempVarsAsync({tempVar, label}) + const label = e.target.label.value + const tempVar = e.target.tempVar.value + + console.log({ + id, + type, + label, + tempVar, + query: { + db: database, + measurement, + tagKey, + }, + }) + // updateTempVarsAsync({tempVar, label}) + } } handleClickOutside() { this.setState({isEditing: false}) } - handleEndEdit() { - this.setState({isEditing: false}) - } - handleStartEdit(name) { this.setState({isEditing: true, autoFocusTarget: name}) } + handleCancelEdit() { + const {template: {type, query: {db, measurement, tagKey}}} = this.props + this.setState({ + selectedType: type, + selectedDatabase: db, + selectedMeasurement: measurement, + selectedKey: tagKey, + isEditing: false, + }) + } + handleSelectType(item) { - this.setState({selectedType: item.type}) + this.setState({ + selectedType: item.type, + selectedDatabase: null, + selectedMeasurement: null, + selectedKey: null, + }) } handleSelectDatabase(item) { @@ -184,7 +229,7 @@ class RowWrapper extends Component { onSelectMeasurement={this.handleSelectMeasurement} onSelectTagKey={this.handleSelectTagKey} onStartEdit={this.handleStartEdit} - onEndEdit={this.handleEndEdit} + onCancelEdit={this.handleCancelEdit} autoFocusTarget={autoFocusTarget} onSubmit={this.handleSubmit} /> @@ -224,7 +269,7 @@ TemplateVariableRow.propTypes = { onSelectDatabase: func.isRequired, onSelectTagKey: func.isRequired, onStartEdit: func.isRequired, - onEndEdit: func.isRequired, + onCancelEdit: func.isRequired, } TableInput.propTypes = { diff --git a/ui/src/dashboards/constants/index.js b/ui/src/dashboards/constants/index.js index d506344221..9661d2b2b6 100644 --- a/ui/src/dashboards/constants/index.js +++ b/ui/src/dashboards/constants/index.js @@ -27,7 +27,7 @@ export const NEW_DASHBOARD = { cells: [NEW_DEFAULT_DASHBOARD_CELL], } -export const TEMPLATE_VARIABLE_TYPES = [ +export const TEMPLATE_TYPES = [ { text: 'CSV', type: 'csv', @@ -41,8 +41,8 @@ export const TEMPLATE_VARIABLE_TYPES = [ type: 'measurements', }, { - text: 'Fields', - type: 'fields', + text: 'Field Keys', + type: 'fieldKeys', }, { text: 'Tag Keys', @@ -53,3 +53,30 @@ export const TEMPLATE_VARIABLE_TYPES = [ type: 'tagValues', }, ] + +export const TEMPLATE_VARIABLE_TYPES = [ + { + text: 'CSV', + type: 'csv', + }, + { + text: 'Database', + type: 'database', + }, + { + text: 'Measurement', + type: 'measurement', + }, + { + text: 'Field Key', + type: 'fieldKey', + }, + { + text: 'Tag Key', + type: 'tagKey', + }, + { + text: 'Tag Value', + type: 'tagValue', + }, +] diff --git a/ui/src/dashboards/containers/DashboardPage.js b/ui/src/dashboards/containers/DashboardPage.js index 0fa6597c0f..194dec0e2b 100644 --- a/ui/src/dashboards/containers/DashboardPage.js +++ b/ui/src/dashboards/containers/DashboardPage.js @@ -146,13 +146,22 @@ class DashboardPage extends Component { handleSelectTemplate(templateID, values) { const {params: {dashboardID}} = this.props - this.props.dashboardActions.templateSelected( + this.props.dashboardActions.templateVariableSelected( +dashboardID, templateID, values ) } + handleEditTemplate(templateVariableID, updates) { + const {params: {dashboardID}} = this.props + this.props.dashboardActions.templateVariableEdited( + +dashboardID, + templateVariableID, + updates + ) + } + getActiveDashboard() { const {params: {dashboardID}, dashboards} = this.props return dashboards.find(d => d.id === +dashboardID) @@ -248,6 +257,7 @@ class DashboardPage extends Component { onOpenTemplateManager={this.handleOpenTemplateManager} onSummonOverlayTechnologies={this.handleSummonOverlayTechnologies} onSelectTemplate={this.handleSelectTemplate} + onEditTemplate={this.handleEditTemplate} /> : null}
diff --git a/ui/src/shared/components/Dropdown.js b/ui/src/shared/components/Dropdown.js index 8d18c6a55f..047ae41c28 100644 --- a/ui/src/shared/components/Dropdown.js +++ b/ui/src/shared/components/Dropdown.js @@ -2,19 +2,17 @@ import React, {PropTypes} from 'react' import classnames from 'classnames' import OnClickOutside from 'shared/components/OnClickOutside' -const { - arrayOf, - shape, - string, - func, -} = PropTypes +const {arrayOf, shape, string, func} = PropTypes const Dropdown = React.createClass({ propTypes: { - items: arrayOf(shape({ - text: string.isRequired, - })).isRequired, + items: arrayOf( + shape({ + text: string.isRequired, + }) + ).isRequired, onChoose: func.isRequired, + onClick: func, selected: string.isRequired, iconName: string, className: string, @@ -40,6 +38,9 @@ const Dropdown = React.createClass({ if (e) { e.stopPropagation() } + if (this.props.onClick) { + this.props.onClick(e) + } this.setState({isOpen: !this.state.isOpen}) }, handleAction(e, action, item) { @@ -53,31 +54,42 @@ const Dropdown = React.createClass({ return (
- {iconName ? : null} + {iconName + ? + : null} {selected}
- {self.state.isOpen ? - + {self.state.isOpen + ? : null}
)