diff --git a/ui/package.json b/ui/package.json index fafc50b5ef..118a738d8b 100644 --- a/ui/package.json +++ b/ui/package.json @@ -103,7 +103,7 @@ "react": "^15.0.2", "react-addons-shallow-compare": "^15.0.2", "react-addons-update": "^15.1.0", - "react-codemirror": "^1.0.0", + "react-codemirror": "^0.2.6", "react-custom-scrollbars": "^4.1.1", "react-dimensions": "^1.2.0", "react-dom": "^15.0.2", diff --git a/ui/src/kapacitor/actions/view/index.js b/ui/src/kapacitor/actions/view/index.js index 8bf2dd62a2..120e536c2f 100644 --- a/ui/src/kapacitor/actions/view/index.js +++ b/ui/src/kapacitor/actions/view/index.js @@ -3,7 +3,7 @@ import {getActiveKapacitor} from 'shared/apis' import {publishNotification} from 'shared/actions/notifications' import { getRules, - getRule, + getRule as getRuleAJAX, deleteRule as deleteRuleAPI, updateRuleStatus as updateRuleStatusAPI, createTask as createTaskAJAX, @@ -13,7 +13,7 @@ import {errorThrown} from 'shared/actions/errors' export function fetchRule(source, ruleID) { return dispatch => { getActiveKapacitor(source).then(kapacitor => { - getRule(kapacitor, ruleID).then(({data: rule}) => { + getRuleAJAX(kapacitor, ruleID).then(({data: rule}) => { dispatch({ type: 'LOAD_RULE', payload: { @@ -32,6 +32,29 @@ export function fetchRule(source, ruleID) { } } +export const getRule = (kapacitor, ruleID) => async dispatch => { + try { + const {data: rule} = await getRuleAJAX(kapacitor, ruleID) + + dispatch({ + type: 'LOAD_RULE', + payload: { + rule: {...rule, queryID: rule.query.id}, + }, + }) + + dispatch({ + type: 'LOAD_KAPACITOR_QUERY', + payload: { + query: rule.query, + }, + }) + } catch (error) { + console.error(error) + throw error + } +} + export function loadDefaultRule() { return dispatch => { const queryID = uuid.v4() diff --git a/ui/src/kapacitor/apis/index.js b/ui/src/kapacitor/apis/index.js index 9f636026e9..0968ab3a69 100644 --- a/ui/src/kapacitor/apis/index.js +++ b/ui/src/kapacitor/apis/index.js @@ -26,11 +26,16 @@ export const getRules = kapacitor => { }) } -export const getRule = (kapacitor, ruleID) => { - return AJAX({ - method: 'GET', - url: `${kapacitor.links.rules}/${ruleID}`, - }) +export const getRule = async (kapacitor, ruleID) => { + try { + return await AJAX({ + method: 'GET', + url: `${kapacitor.links.rules}/${ruleID}`, + }) + } catch (error) { + console.error(error) + throw error + } } export const editRule = rule => { @@ -57,7 +62,7 @@ export const updateRuleStatus = (rule, status) => { } // tickscript contains script, dbsrps, id, and type -export const createTask = async (kapacitor, {id, dbsrps, script, type}) => { +export const createTask = async (kapacitor, {id, dbrps, script, type}) => { try { return await AJAX({ method: 'POST', @@ -65,7 +70,7 @@ export const createTask = async (kapacitor, {id, dbsrps, script, type}) => { data: { id, type, - dbsrps, + dbrps, script, }, }) diff --git a/ui/src/kapacitor/components/KapacitorRulesTable.js b/ui/src/kapacitor/components/KapacitorRulesTable.js index 87587b914a..19abaa6a1e 100644 --- a/ui/src/kapacitor/components/KapacitorRulesTable.js +++ b/ui/src/kapacitor/components/KapacitorRulesTable.js @@ -18,7 +18,7 @@ const KapacitorRulesTable = ({ onDelete, onReadTickscript, onChangeRuleStatus, -}) => +}) => ( <div className="panel-body"> <table className="table v-center"> <thead> @@ -47,8 +47,9 @@ const KapacitorRulesTable = ({ </tbody> </table> </div> +) -const RuleRow = ({rule, source, onRead, onDelete, onChangeRuleStatus}) => +const RuleRow = ({rule, source, onRead, onDelete, onChangeRuleStatus}) => ( <tr key={rule.id}> <td style={{width: colName}} className="monotype"> <RuleTitle rule={rule} source={source} /> @@ -78,6 +79,12 @@ const RuleRow = ({rule, source, onRead, onDelete, onChangeRuleStatus}) => </div> </td> <td style={{width: colActions}} className="text-right table-cell-nowrap"> + <Link + className="btn btn-primary btn-xs" + to={`/sources/${source.id}/tickscript/${rule.id}`} + > + Edit TICKscript + </Link> <button className="btn btn-info btn-xs" onClick={() => onRead(rule)}> View TICKscript </button> @@ -86,6 +93,7 @@ const RuleRow = ({rule, source, onRead, onDelete, onChangeRuleStatus}) => </button> </td> </tr> +) const RuleTitle = ({rule: {id, name, query}, source}) => { // no queryConfig means the rule was manually created outside of Chronograf diff --git a/ui/src/kapacitor/containers/TickscriptPage.js b/ui/src/kapacitor/containers/TickscriptPage.js index 6d7e64ae9b..0b4a8c4fbe 100644 --- a/ui/src/kapacitor/containers/TickscriptPage.js +++ b/ui/src/kapacitor/containers/TickscriptPage.js @@ -4,8 +4,8 @@ import {bindActionCreators} from 'redux' import Tickscript from 'src/kapacitor/components/Tickscript' import * as kapactiorActionCreators from 'src/kapacitor/actions/view' +import * as errorActionCreators from 'shared/actions/errors' import {getActiveKapacitor} from 'src/shared/apis' -import {errorThrown as errorAction} from 'shared/actions/errors' class TickscriptPage extends Component { constructor(props) { @@ -16,7 +16,7 @@ class TickscriptPage extends Component { id: 'testing', status: 'enabled', script: '', - dbsrps: [ + dbrps: [ { db: '_internal', rp: 'monitor', @@ -29,11 +29,24 @@ class TickscriptPage extends Component { } async componentDidMount() { - const {source, errorThrown} = this.props - const kapacitor = await getActiveKapacitor(source) + const { + source, + errorActions, + kapacitorActions, + params: {ruleID}, + } = this.props + const kapacitor = await getActiveKapacitor(source) if (!kapacitor) { - errorThrown('We could not find a configured Kapacitor for this source') + errorActions.errorThrown( + 'We could not find a configured Kapacitor for this source' + ) + } + + if (this.isEditing()) { + await kapacitorActions.getRule(kapacitor, ruleID) + const activeRule = this.props.rules.find(r => r.id === ruleID) + this.setState({task: {...this.state.task, script: activeRule.tickscript}}) } this.setState({kapacitor}) @@ -41,7 +54,7 @@ class TickscriptPage extends Component { async handleSave() { const {kapacitor, task} = this.state - const {source, router, kapactiorActions: {createTask}} = this.props + const {source, router, kapacitorActions: {createTask}} = this.props const response = await createTask(kapacitor, task) if (response && response.error) { @@ -69,30 +82,44 @@ class TickscriptPage extends Component { /> ) } + + isEditing() { + const {params} = this.props + return params.ruleID && params.ruleID !== 'new' + } } -const {func, shape, string} = PropTypes +const {arrayOf, func, shape, string} = PropTypes TickscriptPage.propTypes = { source: shape({ name: string, }), - errorThrown: func.isRequired, - kapactiorActions: shape({ + errorActions: shape({ + errorThrown: func.isRequired, + }).isRequired, + kapacitorActions: shape({ createTask: func.isRequired, + getRule: func.isRequired, }), router: shape({ push: func.isRequired, }).isRequired, + params: shape({ + ruleID: string.isRequired, + }).isRequired, + rules: arrayOf(shape()), } -const mapStateToProps = () => { - return {} +const mapStateToProps = state => { + return { + rules: Object.values(state.rules), + } } const mapDispatchToProps = dispatch => ({ - errorThrown: bindActionCreators(errorAction, dispatch), - kapactiorActions: bindActionCreators(kapactiorActionCreators, dispatch), + kapacitorActions: bindActionCreators(kapactiorActionCreators, dispatch), + errorActions: bindActionCreators(errorActionCreators, dispatch), }) export default connect(mapStateToProps, mapDispatchToProps)(TickscriptPage) diff --git a/ui/yarn.lock b/ui/yarn.lock index 4979380f4a..f51b6ae6f7 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1772,7 +1772,7 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -codemirror@^5.18.2: +codemirror@^5.13.4: version "5.27.4" resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.27.4.tgz#0e817c839bfea9959dd16cd48ae14acc0e43c3b6" @@ -4301,7 +4301,7 @@ lodash.debounce@^3.1.1: dependencies: lodash._getnative "^3.0.0" -lodash.debounce@^4.0.8: +lodash.debounce@^4.0.4: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -4365,10 +4365,6 @@ lodash.isequal@^4.0.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.4.0.tgz#6295768e98e14dc15ce8d362ef6340db82852031" -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - lodash.keys@^3.0.0, lodash.keys@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" @@ -5709,7 +5705,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8: +prop-types@^15.5.6, prop-types@^15.5.8: version "15.5.8" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.8.tgz#6b7b2e141083be38c8595aa51fc55775c7199394" dependencies: @@ -5823,16 +5819,13 @@ react-addons-update@^15.1.0: version "15.4.1" resolved "https://registry.yarnpkg.com/react-addons-update/-/react-addons-update-15.4.1.tgz#00c07f45243aa9715e1706bbfd1f23d3d8d80bd1" -react-codemirror@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/react-codemirror/-/react-codemirror-1.0.0.tgz#91467b53b1f5d80d916a2fd0b4c7adb85a9001ba" +react-codemirror@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/react-codemirror/-/react-codemirror-0.2.6.tgz#e71e35717ce6effae68df1dbf2b5a75b84a44f84" dependencies: - classnames "^2.2.5" - codemirror "^5.18.2" - create-react-class "^15.5.1" - lodash.debounce "^4.0.8" - lodash.isequal "^4.5.0" - prop-types "^15.5.4" + classnames "^2.2.3" + codemirror "^5.13.4" + lodash.debounce "^4.0.4" react-custom-scrollbars@^4.1.1: version "4.1.1"