Convert TickscriptEditor to TypesScript and add initial test
parent
646da4919e
commit
21754a10f9
|
@ -0,0 +1,2 @@
|
|||
export const pingKapacitorVersion = jest.fn(() => Promise.resolve('2.0'))
|
||||
export const getLogStreamByRuleID = jest.fn(() => Promise.resolve())
|
|
@ -1,6 +1,7 @@
|
|||
import {kapacitor} from 'mocks/dummy'
|
||||
|
||||
export const getKapacitor = jest.fn(() => Promise.resolve(kapacitor))
|
||||
export const getActiveKapacitor = jest.fn(() => Promise.resolve(kapacitor))
|
||||
export const createKapacitor = jest.fn(() => Promise.resolve({data: kapacitor}))
|
||||
export const updateKapacitor = jest.fn(() => Promise.resolve({data: kapacitor}))
|
||||
export const pingKapacitor = jest.fn(() => Promise.resolve())
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"@types/prop-types": "^15.5.2",
|
||||
"@types/react": "^16.0.38",
|
||||
"@types/react-router": "3",
|
||||
"@types/text-encoding": "^0.0.32",
|
||||
"autoprefixer": "^6.3.1",
|
||||
"babel-core": "^6.5.1",
|
||||
"babel-eslint": "6.1.2",
|
||||
|
|
|
@ -1,28 +1,88 @@
|
|||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import React, {PureComponent} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import uuid from 'uuid'
|
||||
|
||||
import Tickscript from 'src/kapacitor/components/Tickscript'
|
||||
import * as kapactiorActionCreators from 'src/kapacitor/actions/view'
|
||||
import * as errorActionCreators from 'shared/actions/errors'
|
||||
import * as errorActionCreators from 'src/shared/actions/errors'
|
||||
import {getActiveKapacitor} from 'src/shared/apis'
|
||||
import {getLogStreamByRuleID, pingKapacitorVersion} from 'src/kapacitor/apis'
|
||||
import {notify as notifyAction} from 'shared/actions/notifications'
|
||||
import {notify as notifyAction} from 'src/shared/actions/notifications'
|
||||
|
||||
import {Source, Kapacitor, Task, AlertRule} from 'src/types'
|
||||
|
||||
import {
|
||||
notifyTickscriptLoggingUnavailable,
|
||||
notifyTickscriptLoggingError,
|
||||
notifyKapacitorNotFound,
|
||||
} from 'shared/copy/notifications'
|
||||
} from 'src/shared/copy/notifications'
|
||||
|
||||
class TickscriptPage extends Component {
|
||||
interface ErrorActions {
|
||||
errorThrown: (notify: string | object) => void
|
||||
}
|
||||
|
||||
interface Router {
|
||||
push: (path: string) => void
|
||||
}
|
||||
|
||||
interface KapacitorActions {
|
||||
updateTask: (
|
||||
kapacitor: Kapacitor,
|
||||
task: Task,
|
||||
ruleID: string,
|
||||
router: Router,
|
||||
sourceID: string
|
||||
) => void
|
||||
createTask: (
|
||||
kapacitor: Kapacitor,
|
||||
task: Task,
|
||||
router: Router,
|
||||
sourceID: string
|
||||
) => void
|
||||
getRule: (kapacitor: Kapacitor, ruleID: string) => void
|
||||
}
|
||||
|
||||
interface Params {
|
||||
ruleID: string
|
||||
}
|
||||
|
||||
interface Props {
|
||||
source: Source
|
||||
errorActions: ErrorActions
|
||||
kapacitorActions: KapacitorActions
|
||||
router: Router
|
||||
params: Params
|
||||
rules: AlertRule[]
|
||||
notify: any
|
||||
}
|
||||
|
||||
interface State {
|
||||
kapacitor: Kapacitor
|
||||
task: Task
|
||||
consoleMessage: string
|
||||
isEditingID: boolean
|
||||
logs: object[]
|
||||
areLogsVisible: boolean
|
||||
areLogsEnabled: boolean
|
||||
failStr: string
|
||||
unsavedChanges: boolean
|
||||
}
|
||||
|
||||
export class TickscriptPage extends PureComponent<Props, State> {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
kapacitor: {},
|
||||
kapacitor: {
|
||||
id: '',
|
||||
url: '',
|
||||
name: '',
|
||||
active: false,
|
||||
insecureSkipVerify: false,
|
||||
links: {
|
||||
self: '',
|
||||
},
|
||||
},
|
||||
task: {
|
||||
id: '',
|
||||
name: '',
|
||||
|
@ -34,13 +94,143 @@ class TickscriptPage extends Component {
|
|||
consoleMessage: '',
|
||||
isEditingID: true,
|
||||
logs: [],
|
||||
areLogsEnabled: false,
|
||||
failStr: '',
|
||||
areLogsVisible: false,
|
||||
areLogsEnabled: false,
|
||||
unsavedChanges: false,
|
||||
}
|
||||
}
|
||||
|
||||
fetchChunkedLogs = async (kapacitor, ruleID) => {
|
||||
public async componentDidMount() {
|
||||
const {
|
||||
source,
|
||||
errorActions,
|
||||
kapacitorActions,
|
||||
params: {ruleID},
|
||||
} = this.props
|
||||
|
||||
const kapacitor = await getActiveKapacitor(source)
|
||||
if (!kapacitor) {
|
||||
errorActions.errorThrown(notifyKapacitorNotFound())
|
||||
}
|
||||
|
||||
if (this._isEditing()) {
|
||||
await kapacitorActions.getRule(kapacitor, ruleID)
|
||||
const {id, name, tickscript, dbrps, type} = this.props.rules.find(
|
||||
r => r.id === ruleID
|
||||
)
|
||||
|
||||
this.setState({task: {tickscript, dbrps, type, status, name, id}})
|
||||
}
|
||||
|
||||
this.fetchChunkedLogs(kapacitor, ruleID)
|
||||
|
||||
this.setState({kapacitor})
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.setState({
|
||||
areLogsEnabled: false,
|
||||
})
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {
|
||||
task,
|
||||
logs,
|
||||
areLogsVisible,
|
||||
areLogsEnabled,
|
||||
unsavedChanges,
|
||||
consoleMessage,
|
||||
} = this.state
|
||||
|
||||
return (
|
||||
<Tickscript
|
||||
task={task}
|
||||
logs={logs}
|
||||
onSave={this.handleSave}
|
||||
onExit={this.handleExit}
|
||||
unsavedChanges={unsavedChanges}
|
||||
areLogsVisible={areLogsVisible}
|
||||
areLogsEnabled={areLogsEnabled}
|
||||
consoleMessage={consoleMessage}
|
||||
onChangeID={this.handleChangeID}
|
||||
onChangeType={this.handleChangeType}
|
||||
isNewTickscript={!this._isEditing()}
|
||||
onSelectDbrps={this.handleSelectDbrps}
|
||||
onChangeScript={this.handleChangeScript}
|
||||
onToggleLogsVisibility={this.handleToggleLogsVisibility}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
private handleSave = async () => {
|
||||
const {kapacitor, task} = this.state
|
||||
const {
|
||||
source: {id: sourceID},
|
||||
router,
|
||||
kapacitorActions: {createTask, updateTask},
|
||||
params: {ruleID},
|
||||
} = this.props
|
||||
|
||||
let response
|
||||
|
||||
try {
|
||||
if (this._isEditing()) {
|
||||
response = await updateTask(kapacitor, task, ruleID, router, sourceID)
|
||||
} else {
|
||||
response = await createTask(kapacitor, task, router, sourceID)
|
||||
router.push(`/sources/${sourceID}/tickscript/${response.id}`)
|
||||
}
|
||||
if (response.code) {
|
||||
this.setState({unsavedChanges: true, consoleMessage: response.message})
|
||||
} else {
|
||||
this.setState({unsavedChanges: false, consoleMessage: ''})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
private handleExit = () => {
|
||||
const {source: {id: sourceID}, router} = this.props
|
||||
|
||||
return router.push(`/sources/${sourceID}/alert-rules`)
|
||||
}
|
||||
|
||||
private handleChangeScript = tickscript => {
|
||||
this.setState({
|
||||
task: {...this.state.task, tickscript},
|
||||
unsavedChanges: true,
|
||||
})
|
||||
}
|
||||
|
||||
private handleSelectDbrps = dbrps => {
|
||||
this.setState({task: {...this.state.task, dbrps}, unsavedChanges: true})
|
||||
}
|
||||
|
||||
private handleChangeType = type => () => {
|
||||
this.setState({task: {...this.state.task, type}, unsavedChanges: true})
|
||||
}
|
||||
|
||||
private handleChangeID = e => {
|
||||
this.setState({
|
||||
task: {...this.state.task, id: e.target.value},
|
||||
unsavedChanges: true,
|
||||
})
|
||||
}
|
||||
|
||||
private handleToggleLogsVisibility = () => {
|
||||
this.setState({areLogsVisible: !this.state.areLogsVisible})
|
||||
}
|
||||
|
||||
private _isEditing() {
|
||||
const {params} = this.props
|
||||
return params.ruleID && params.ruleID !== 'new'
|
||||
}
|
||||
|
||||
private fetchChunkedLogs = async (kapacitor, ruleID) => {
|
||||
const {notify} = this.props
|
||||
|
||||
try {
|
||||
|
@ -110,7 +300,7 @@ class TickscriptPage extends Component {
|
|||
failStr,
|
||||
})
|
||||
} catch (err) {
|
||||
console.warn(err, failStr)
|
||||
console.warn(err, failStr) // tslint:disable-line
|
||||
this.setState({
|
||||
logs: [...logs, ...this.state.logs],
|
||||
failStr,
|
||||
|
@ -119,165 +309,10 @@ class TickscriptPage extends Component {
|
|||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
notify(notifyTickscriptLoggingError()(error))
|
||||
notify(notifyTickscriptLoggingError(error))
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const {
|
||||
source,
|
||||
errorActions,
|
||||
kapacitorActions,
|
||||
params: {ruleID},
|
||||
} = this.props
|
||||
|
||||
const kapacitor = await getActiveKapacitor(source)
|
||||
if (!kapacitor) {
|
||||
errorActions.errorThrown(notifyKapacitorNotFound())
|
||||
}
|
||||
|
||||
if (this._isEditing()) {
|
||||
await kapacitorActions.getRule(kapacitor, ruleID)
|
||||
const {id, name, tickscript, dbrps, type} = this.props.rules.find(
|
||||
r => r.id === ruleID
|
||||
)
|
||||
|
||||
this.setState({task: {tickscript, dbrps, type, status, name, id}})
|
||||
}
|
||||
|
||||
this.fetchChunkedLogs(kapacitor, ruleID)
|
||||
|
||||
this.setState({kapacitor})
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.setState({
|
||||
areLogsEnabled: false,
|
||||
})
|
||||
}
|
||||
|
||||
handleSave = async () => {
|
||||
const {kapacitor, task} = this.state
|
||||
const {
|
||||
source: {id: sourceID},
|
||||
router,
|
||||
kapacitorActions: {createTask, updateTask},
|
||||
params: {ruleID},
|
||||
} = this.props
|
||||
|
||||
let response
|
||||
|
||||
try {
|
||||
if (this._isEditing()) {
|
||||
response = await updateTask(kapacitor, task, ruleID, router, sourceID)
|
||||
} else {
|
||||
response = await createTask(kapacitor, task, router, sourceID)
|
||||
router.push(`/sources/${sourceID}/tickscript/${response.id}`)
|
||||
}
|
||||
if (response.code) {
|
||||
this.setState({unsavedChanges: true, consoleMessage: response.message})
|
||||
} else {
|
||||
this.setState({unsavedChanges: false, consoleMessage: ''})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
handleExit = () => {
|
||||
const {source: {id: sourceID}, router} = this.props
|
||||
|
||||
return router.push(`/sources/${sourceID}/alert-rules`)
|
||||
}
|
||||
|
||||
handleChangeScript = tickscript => {
|
||||
this.setState({
|
||||
task: {...this.state.task, tickscript},
|
||||
unsavedChanges: true,
|
||||
})
|
||||
}
|
||||
|
||||
handleSelectDbrps = dbrps => {
|
||||
this.setState({task: {...this.state.task, dbrps}, unsavedChanges: true})
|
||||
}
|
||||
|
||||
handleChangeType = type => () => {
|
||||
this.setState({task: {...this.state.task, type}, unsavedChanges: true})
|
||||
}
|
||||
|
||||
handleChangeID = e => {
|
||||
this.setState({
|
||||
task: {...this.state.task, id: e.target.value},
|
||||
unsavedChanges: true,
|
||||
})
|
||||
}
|
||||
|
||||
handleToggleLogsVisibility = () => {
|
||||
this.setState({areLogsVisible: !this.state.areLogsVisible})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {source} = this.props
|
||||
const {
|
||||
task,
|
||||
logs,
|
||||
areLogsVisible,
|
||||
areLogsEnabled,
|
||||
unsavedChanges,
|
||||
consoleMessage,
|
||||
} = this.state
|
||||
|
||||
return (
|
||||
<Tickscript
|
||||
task={task}
|
||||
logs={logs}
|
||||
source={source}
|
||||
consoleMessage={consoleMessage}
|
||||
onSave={this.handleSave}
|
||||
unsavedChanges={unsavedChanges}
|
||||
onExit={this.handleExit}
|
||||
isNewTickscript={!this._isEditing()}
|
||||
onSelectDbrps={this.handleSelectDbrps}
|
||||
onChangeScript={this.handleChangeScript}
|
||||
onChangeType={this.handleChangeType}
|
||||
onChangeID={this.handleChangeID}
|
||||
areLogsVisible={areLogsVisible}
|
||||
areLogsEnabled={areLogsEnabled}
|
||||
onToggleLogsVisibility={this.handleToggleLogsVisibility}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
_isEditing() {
|
||||
const {params} = this.props
|
||||
return params.ruleID && params.ruleID !== 'new'
|
||||
}
|
||||
}
|
||||
|
||||
const {arrayOf, func, shape, string} = PropTypes
|
||||
|
||||
TickscriptPage.propTypes = {
|
||||
source: shape({
|
||||
name: string,
|
||||
}),
|
||||
errorActions: shape({
|
||||
errorThrown: func.isRequired,
|
||||
}).isRequired,
|
||||
kapacitorActions: shape({
|
||||
updateTask: func.isRequired,
|
||||
createTask: func.isRequired,
|
||||
getRule: func.isRequired,
|
||||
}),
|
||||
router: shape({
|
||||
push: func.isRequired,
|
||||
}).isRequired,
|
||||
params: shape({
|
||||
ruleID: string,
|
||||
}).isRequired,
|
||||
rules: arrayOf(shape()),
|
||||
notify: func.isRequired,
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
|
@ -1,6 +1,6 @@
|
|||
import {AuthLinks, Organization, Role, User, Me} from './auth'
|
||||
import {AlertRule, Kapacitor} from './kapacitor'
|
||||
import {Query, QueryConfig, TimeRange} from './query'
|
||||
import {AlertRule, Kapacitor, Task} from './kapacitor'
|
||||
import {Source} from './sources'
|
||||
import {DropdownAction, DropdownItem} from './shared'
|
||||
|
||||
|
@ -18,4 +18,5 @@ export {
|
|||
DropdownAction,
|
||||
DropdownItem,
|
||||
TimeRange,
|
||||
Task,
|
||||
}
|
||||
|
|
|
@ -34,6 +34,15 @@ export interface AlertRule {
|
|||
'last-enabled'?: string
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
id: string
|
||||
name: string
|
||||
status: string
|
||||
tickscript: string
|
||||
dbrps: DBRP[]
|
||||
type: string
|
||||
}
|
||||
|
||||
type TICKScript = string
|
||||
|
||||
// AlertNodes defines all possible kapacitor interactions with an alert.
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import React from 'react'
|
||||
import {shallow} from 'enzyme'
|
||||
import {TickscriptPage} from 'src/kapacitor/containers/TickscriptPage'
|
||||
import {source} from 'test/resources'
|
||||
|
||||
jest.mock('src/shared/apis', () => require('mocks/shared/apis'))
|
||||
jest.mock('src/kapacitor/apis', () => require('mocks/kapacitor/apis'))
|
||||
|
||||
const setup = () => {
|
||||
const props = {
|
||||
source,
|
||||
errorActions: {
|
||||
errorThrown: () => {},
|
||||
},
|
||||
kapacitorActions: {
|
||||
updateTask: () => {},
|
||||
createTask: () => {},
|
||||
getRule: () => {},
|
||||
},
|
||||
router: {
|
||||
push: () => {},
|
||||
},
|
||||
params: {
|
||||
ruleID: '',
|
||||
},
|
||||
rules: [],
|
||||
notify: () => {},
|
||||
}
|
||||
const wrapper = shallow(<TickscriptPage {...props} />)
|
||||
|
||||
return {
|
||||
wrapper,
|
||||
}
|
||||
}
|
||||
|
||||
describe('Kapacitor.Containers.TickscriptPage', () => {
|
||||
describe('rendering', () => {
|
||||
it('renders without errors', () => {
|
||||
const {wrapper} = setup()
|
||||
expect(wrapper.exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -8,7 +8,8 @@
|
|||
"react",
|
||||
"prop-types",
|
||||
"jest",
|
||||
"react-router"
|
||||
"react-router",
|
||||
"text-encoding"
|
||||
],
|
||||
"target": "es6",
|
||||
"module": "es2015",
|
||||
|
|
|
@ -72,6 +72,10 @@
|
|||
version "16.0.40"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.40.tgz#caabc2296886f40b67f6fc80f0f3464476461df9"
|
||||
|
||||
"@types/text-encoding@^0.0.32":
|
||||
version "0.0.32"
|
||||
resolved "https://registry.yarnpkg.com/@types/text-encoding/-/text-encoding-0.0.32.tgz#52289b320a406850b14f08f48b475ca021218048"
|
||||
|
||||
abab@^1.0.3, abab@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
|
||||
|
|
Loading…
Reference in New Issue