Feat/current check to time machine (#14662)

* Move current check to TimeMachine alerting

* Unify RemoveButton actions in to  ConvertFromCheckView

* Unify AddCheckDialog actions

* Switch saveCurrentCheck to saveCheckFromTimeMachine

* Remove current check from checks reducer

* Change getCurrentCheck to getCheckForTimeMachine

* Get Check along with view in EditcheckEO

* Tidy imports

* Import Actions With on...

* fix module name

* Remove check fixtures
pull/14663/head
Deniz Kusefoglu 2019-08-14 17:37:33 -07:00 committed by GitHub
parent 54c9537bfc
commit e637e1e140
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 284 additions and 263 deletions

View File

@ -15,19 +15,16 @@ import {
notify,
Action as NotificationAction,
} from 'src/shared/actions/notifications'
import {Action as TimeMachineAction} from 'src/timeMachine/actions'
import {setCheckStatus, setTimeMachineCheck} from 'src/timeMachine/actions'
// Types
import {RemoteDataState} from '@influxdata/clockface'
import {Check, GetState, CheckType} from 'src/types'
import {Check, GetState, RemoteDataState} from 'src/types'
export type Action =
| ReturnType<typeof setAllChecks>
| ReturnType<typeof setCheck>
| ReturnType<typeof removeCheck>
| ReturnType<typeof setCurrentCheck>
| ReturnType<typeof setCurrentCheckStatus>
| ReturnType<typeof updateCurrentCheck>
| ReturnType<typeof changeCurrentCheckType>
export const setAllChecks = (status: RemoteDataState, checks?: Check[]) => ({
type: 'SET_ALL_CHECKS' as 'SET_ALL_CHECKS',
@ -44,29 +41,6 @@ export const removeCheck = (checkID: string) => ({
payload: {checkID},
})
export const setCurrentCheck = (
status: RemoteDataState,
check: Partial<Check>
) => ({
type: 'SET_CURRENT_CHECK' as 'SET_CURRENT_CHECK',
payload: {status, check},
})
export const setCurrentCheckStatus = (status: RemoteDataState) => ({
type: 'SET_CURRENT_CHECK_STATUS' as 'SET_CURRENT_CHECK_STATUS',
payload: {status},
})
export const updateCurrentCheck = (checkUpdate: Partial<Check>) => ({
type: 'UPDATE_CURRENT_CHECK' as 'UPDATE_CURRENT_CHECK',
payload: {status, checkUpdate},
})
export const changeCurrentCheckType = (type: CheckType) => ({
type: 'CHANGE_CURRENT_CHECK_TYPE' as 'CHANGE_CURRENT_CHECK_TYPE',
payload: {status, type},
})
export const getChecks = () => async (
dispatch: Dispatch<Action | NotificationAction>
// getState: GetState
@ -94,11 +68,11 @@ export const getChecks = () => async (
}
}
export const getCurrentCheck = (checkID: string) => async (
dispatch: Dispatch<Action | NotificationAction>
export const getCheckForTimeMachine = (checkID: string) => async (
dispatch: Dispatch<TimeMachineAction | NotificationAction>
) => {
try {
dispatch(setCurrentCheckStatus(RemoteDataState.Loading))
dispatch(setCheckStatus(RemoteDataState.Loading))
const resp = await api.getCheck({checkID})
@ -106,30 +80,30 @@ export const getCurrentCheck = (checkID: string) => async (
throw new Error(resp.data.message)
}
dispatch(setCurrentCheck(RemoteDataState.Done, resp.data))
dispatch(setTimeMachineCheck(RemoteDataState.Done, resp.data))
} catch (e) {
console.error(e)
dispatch(setCurrentCheckStatus(RemoteDataState.Error))
dispatch(setCheckStatus(RemoteDataState.Error))
dispatch(notify(copy.getCheckFailed(e.message)))
}
}
export const saveCurrentCheck = () => async (
export const saveCheckFromTimeMachine = () => async (
dispatch: Dispatch<Action | NotificationAction>,
getState: GetState
) => {
try {
const state = getState()
const {
checks: {
current: {check},
},
orgs: {
org: {id: orgID},
},
} = state
const {draftQueries} = getActiveTimeMachine(state)
const {
draftQueries,
alerting: {check},
} = getActiveTimeMachine(state)
const checkWithOrg = {...check, query: draftQueries[0], orgID} as Check

View File

@ -13,13 +13,12 @@ import {createView} from 'src/shared/utils/view'
import {getActiveTimeMachine} from 'src/timeMachine/selectors'
// Actions
import {updateCheck, getCheckForTimeMachine} from 'src/alerting/actions/checks'
import {
updateCheck,
setCurrentCheck,
updateCurrentCheck,
getCurrentCheck,
} from 'src/alerting/actions/checks'
import {setActiveTimeMachine} from 'src/timeMachine/actions'
setActiveTimeMachine,
setTimeMachineCheck,
updateTimeMachineCheck,
} from 'src/timeMachine/actions'
// Types
import {
@ -32,11 +31,11 @@ import {
} from 'src/types'
interface DispatchProps {
updateCheck: typeof updateCheck
setCurrentCheck: typeof setCurrentCheck
getCurrentCheck: typeof getCurrentCheck
updateCurrentCheck: typeof updateCurrentCheck
onUpdateCheck: typeof updateCheck
onGetCheckForTimeMachine: typeof getCheckForTimeMachine
onUpdateTimeMachineCheck: typeof updateTimeMachineCheck
onSetActiveTimeMachine: typeof setActiveTimeMachine
onSetTimeMachineCheck: typeof setTimeMachineCheck
}
interface StateProps {
@ -49,11 +48,13 @@ interface StateProps {
type Props = WithRouterProps & DispatchProps & StateProps
const EditCheckEditorOverlay: FunctionComponent<Props> = ({
onUpdateCheck,
onGetCheckForTimeMachine,
onUpdateTimeMachineCheck,
onSetActiveTimeMachine,
onSetTimeMachineCheck,
activeTimeMachineID,
getCurrentCheck,
checkStatus,
updateCheck,
router,
params: {checkID, orgID},
query,
@ -69,22 +70,22 @@ const EditCheckEditorOverlay: FunctionComponent<Props> = ({
isViewingRawData: false,
})
} else {
getCurrentCheck(checkID)
onGetCheckForTimeMachine(checkID)
}
}, [check, checkID])
const handleUpdateName = (name: string) => {
updateCurrentCheck({name})
onUpdateTimeMachineCheck({name})
}
const handleClose = () => {
setCurrentCheck(RemoteDataState.NotStarted, null)
onSetTimeMachineCheck(RemoteDataState.NotStarted, null)
router.push(`/orgs/${orgID}/alerting`)
}
const handleSave = () => {
// todo: update view when check has own view
updateCheck({...check, query})
onUpdateCheck({...check, query})
handleClose()
}
@ -126,23 +127,23 @@ const EditCheckEditorOverlay: FunctionComponent<Props> = ({
const mstp = (state: AppState): StateProps => {
const {
checks: {
current: {check, status: checkStatus},
},
timeMachines: {activeTimeMachineID},
} = state
const {draftQueries} = getActiveTimeMachine(state)
const {
draftQueries,
alerting: {check, checkStatus},
} = getActiveTimeMachine(state)
return {check, checkStatus, activeTimeMachineID, query: draftQueries[0]}
}
const mdtp: DispatchProps = {
updateCheck: updateCheck,
setCurrentCheck: setCurrentCheck,
updateCurrentCheck: updateCurrentCheck,
onUpdateCheck: updateCheck,
onSetTimeMachineCheck: setTimeMachineCheck,
onUpdateTimeMachineCheck: updateTimeMachineCheck,
onSetActiveTimeMachine: setActiveTimeMachine,
getCurrentCheck: getCurrentCheck,
onGetCheckForTimeMachine: getCheckForTimeMachine,
}
export default connect<StateProps, DispatchProps, {}>(

View File

@ -11,14 +11,17 @@ import TimeMachine from 'src/timeMachine/components/TimeMachine'
// Actions
import {
updateCheck,
setCurrentCheck,
updateCurrentCheck,
saveCurrentCheck,
saveCheckFromTimeMachine,
} from 'src/alerting/actions/checks'
import {setActiveTimeMachine} from 'src/timeMachine/actions'
import {
setActiveTimeMachine,
updateTimeMachineCheck,
setTimeMachineCheck,
} from 'src/timeMachine/actions'
// Utils
import {createView} from 'src/shared/utils/view'
import {getActiveTimeMachine} from 'src/timeMachine/selectors'
// Types
import {Check, AppState, RemoteDataState, CheckViewProperties} from 'src/types'
@ -26,44 +29,47 @@ import {DEFAULT_THRESHOLD_CHECK} from 'src/alerting/constants'
interface DispatchProps {
updateCheck: typeof updateCheck
setCurrentCheck: typeof setCurrentCheck
updateCurrentCheck: typeof updateCurrentCheck
setTimeMachineCheck: typeof setTimeMachineCheck
updateTimeMachineCheck: typeof updateTimeMachineCheck
onSetActiveTimeMachine: typeof setActiveTimeMachine
saveCurrentCheck: typeof saveCurrentCheck
saveCheckFromTimeMachine: typeof saveCheckFromTimeMachine
}
interface StateProps {
check: Partial<Check>
status: RemoteDataState
checkStatus: RemoteDataState
}
type Props = DispatchProps & StateProps & WithRouterProps
const NewCheckOverlay: FunctionComponent<Props> = ({
onSetActiveTimeMachine,
updateCurrentCheck,
setCurrentCheck,
saveCurrentCheck,
updateTimeMachineCheck,
setTimeMachineCheck,
saveCheckFromTimeMachine,
params,
router,
status,
checkStatus,
check,
}) => {
useEffect(() => {
setCurrentCheck(RemoteDataState.Done, DEFAULT_THRESHOLD_CHECK)
const view = createView<CheckViewProperties>('check')
onSetActiveTimeMachine('alerting', {
view,
activeTab: 'queries',
alerting: {
checkStatus: RemoteDataState.Done,
check: DEFAULT_THRESHOLD_CHECK,
},
})
}, [])
const handleUpdateName = (name: string) => {
updateCurrentCheck({name})
updateTimeMachineCheck({name})
}
const handleClose = () => {
setCurrentCheck(RemoteDataState.NotStarted, null)
setTimeMachineCheck(RemoteDataState.NotStarted, null)
router.push(`/orgs/${params.orgID}/alerting`)
}
@ -71,7 +77,7 @@ const NewCheckOverlay: FunctionComponent<Props> = ({
// todo: when check has own view
// save view as view
// put view.id on check.viewID
saveCurrentCheck()
saveCheckFromTimeMachine()
handleClose()
}
@ -80,7 +86,7 @@ const NewCheckOverlay: FunctionComponent<Props> = ({
<div className="veo">
<SpinnerContainer
spinnerComponent={<TechnoSpinner />}
loading={status || RemoteDataState.Loading}
loading={checkStatus || RemoteDataState.Loading}
>
<CheckEOHeader
key={check && check.name}
@ -100,20 +106,18 @@ const NewCheckOverlay: FunctionComponent<Props> = ({
const mstp = (state: AppState): StateProps => {
const {
checks: {
current: {check, status},
},
} = state
alerting: {check, checkStatus},
} = getActiveTimeMachine(state)
return {check, status}
return {check, checkStatus}
}
const mdtp: DispatchProps = {
updateCheck: updateCheck,
setCurrentCheck: setCurrentCheck,
updateCurrentCheck: updateCurrentCheck,
setTimeMachineCheck: setTimeMachineCheck,
updateTimeMachineCheck: updateTimeMachineCheck,
onSetActiveTimeMachine: setActiveTimeMachine,
saveCurrentCheck: saveCurrentCheck,
saveCheckFromTimeMachine: saveCheckFromTimeMachine,
}
export default connect<StateProps, DispatchProps, {}>(

View File

@ -16,10 +16,10 @@ import {
import {Input} from '@influxdata/clockface'
// Actions
import {
updateCurrentCheck,
changeCurrentCheckType,
} from 'src/alerting/actions/checks'
import {updateTimeMachineCheck, changeCheckType} from 'src/timeMachine/actions'
//Selectors
import {getActiveTimeMachine} from 'src/timeMachine/selectors'
// Types
import {Check, AppState, CheckType} from 'src/types'
@ -30,8 +30,8 @@ import {
} from 'src/alerting/constants'
interface DispatchProps {
updateCurrentCheck: typeof updateCurrentCheck
changeCurrentCheckType: typeof changeCurrentCheckType
updateTimeMachineCheck: typeof updateTimeMachineCheck
changeCheckType: typeof changeCheckType
}
interface StateProps {
@ -41,30 +41,34 @@ interface StateProps {
type Props = DispatchProps & StateProps
const CheckMetaCard: FC<Props> = ({
updateCurrentCheck,
changeCurrentCheckType,
updateTimeMachineCheck,
changeCheckType,
check,
}) => {
const handleChangeType = (type: CheckType) => {
changeCurrentCheckType(type)
changeCheckType(type)
}
const handleChangeName = (e: React.ChangeEvent<HTMLInputElement>) => {
updateCurrentCheck({name: e.target.value})
updateTimeMachineCheck({name: e.target.value})
}
const handleChangeMessage = (e: ChangeEvent<HTMLTextAreaElement>) => {
const statusMessageTemplate = e.target.value
updateCurrentCheck({statusMessageTemplate})
updateTimeMachineCheck({statusMessageTemplate})
}
const handleChangeSchedule = (scheduleType: 'cron' | 'every') => {
if (scheduleType == 'cron' && !check.cron) {
updateCurrentCheck({cron: DEFAULT_CHECK_CRON, every: null, offset: null})
updateTimeMachineCheck({
cron: DEFAULT_CHECK_CRON,
every: null,
offset: null,
})
return
}
if (scheduleType == 'every' && !check.every) {
updateCurrentCheck({
updateTimeMachineCheck({
every: DEFAULT_CHECK_EVERY,
offset: DEFAULT_CHECK_OFFSET,
cron: null,
@ -216,17 +220,15 @@ const CheckMetaCard: FC<Props> = ({
const mstp = (state: AppState): StateProps => {
const {
checks: {
current: {check},
},
} = state
alerting: {check},
} = getActiveTimeMachine(state)
return {check}
}
const mdtp: DispatchProps = {
updateCurrentCheck: updateCurrentCheck,
changeCurrentCheckType: changeCurrentCheckType,
updateTimeMachineCheck: updateTimeMachineCheck,
changeCheckType: changeCheckType,
}
export default connect<StateProps, DispatchProps, {}>(

View File

@ -7,29 +7,16 @@ import {Button} from '@influxdata/clockface'
// Actions
import {convertFromCheckView} from 'src/timeMachine/actions'
import {setCurrentCheck} from 'src/alerting/actions/checks'
//Types
import {RemoteDataState} from 'src/types'
interface DispatchProps {
onConvertFromCheckView: typeof convertFromCheckView
onSetCurrentCheck: typeof setCurrentCheck
}
type Props = DispatchProps
const RemoveButton: FunctionComponent<Props> = ({
onSetCurrentCheck,
onConvertFromCheckView,
}) => {
const RemoveButton: FunctionComponent<Props> = ({onConvertFromCheckView}) => {
const handleClick = () => {
onConvertFromCheckView()
// TODO: Move the current check state into the time machine reducer, then
// handle this state transition as part `CONVERT_FROM_CHECK_VIEW`
// transition
onSetCurrentCheck(RemoteDataState.NotStarted, null)
}
return (
@ -43,7 +30,6 @@ const RemoveButton: FunctionComponent<Props> = ({
const mdtp: DispatchProps = {
onConvertFromCheckView: convertFromCheckView,
onSetCurrentCheck: setCurrentCheck,
}
export default connect<{}, DispatchProps, {}>(

View File

@ -1,10 +1,5 @@
import checksReducer, {defaultChecksState} from 'src/alerting/reducers/checks'
import {
setAllChecks,
setCheck,
setCurrentCheck,
removeCheck,
} from 'src/alerting/actions/checks'
import {setAllChecks, setCheck, removeCheck} from 'src/alerting/actions/checks'
import {RemoteDataState} from 'src/types'
import {CHECK_FIXTURE_1, CHECK_FIXTURE_2} from 'src/alerting/constants'
@ -70,23 +65,6 @@ describe('checksReducer', () => {
list: [],
}
expect(actual).toEqual(expected)
})
})
describe('setCurrentCheck', () => {
it('sets current check and status.', () => {
const initialState = defaultChecksState
const actual = checksReducer(
initialState,
setCurrentCheck(RemoteDataState.Done, CHECK_FIXTURE_1)
)
const expected = {
...defaultChecksState,
current: {status: RemoteDataState.Done, check: CHECK_FIXTURE_1},
}
expect(actual).toEqual(expected)
})
})

View File

@ -1,22 +1,18 @@
// Libraries
import {produce} from 'immer'
import {omit} from 'lodash'
// Types
import {RemoteDataState, Check, ThresholdCheck, DeadmanCheck} from 'src/types'
import {RemoteDataState, Check} from 'src/types'
import {Action} from 'src/alerting/actions/checks'
import {DEFAULT_THRESHOLD_CHECK, DEFAULT_DEADMAN_CHECK} from '../constants'
export interface ChecksState {
status: RemoteDataState
list: Check[]
current: {status: RemoteDataState; check: Partial<Check>}
}
export const defaultChecksState: ChecksState = {
status: RemoteDataState.NotStarted,
list: [],
current: {status: RemoteDataState.NotStarted, check: null},
}
export default (
@ -48,37 +44,5 @@ export default (
const {checkID} = action.payload
draftState.list = draftState.list.filter(c => c.id != checkID)
return
case 'SET_CURRENT_CHECK':
draftState.current.status = action.payload.status
draftState.current.check = action.payload.check
return
case 'SET_CURRENT_CHECK_STATUS':
draftState.current.status = action.payload.status
return
case 'UPDATE_CURRENT_CHECK':
draftState.current.check = {
...draftState.current.check,
...action.payload.checkUpdate,
} as Check
return
case 'CHANGE_CURRENT_CHECK_TYPE':
const exCheck = draftState.current.check
if (action.payload.type == 'deadman') {
draftState.current.check = {
...DEFAULT_DEADMAN_CHECK,
...omit(exCheck, ['thresholds', 'type']),
} as DeadmanCheck
}
if (action.payload.type == 'threshold') {
draftState.current.check = {
...DEFAULT_THRESHOLD_CHECK,
...omit(exCheck, ['timeSince', 'reportZero', 'level', 'type']),
} as ThresholdCheck
}
return
}
})

View File

@ -0,0 +1,6 @@
import {AppState, Check} from 'src/types'
export const getCheck = (state: AppState, id: string): Check => {
const checksList = state.checks.list
return checksList.find(c => c.id === id)
}

View File

@ -1,19 +1,29 @@
// Utils
import {getView as getViewFromState} from 'src/dashboards/selectors'
import {getCheck as getCheckFromState} from 'src/alerting/selectors'
// APIs
import {
getView as getViewAJAX,
updateView as updateViewAJAX,
} from 'src/dashboards/apis/'
import * as api from 'src/client'
// Constants
import * as copy from 'src/shared/copy/notifications'
// Actions
import {
notify,
Action as NotificationAction,
} from 'src/shared/actions/notifications'
import {setActiveTimeMachine} from 'src/timeMachine/actions'
// Types
import {RemoteDataState, QueryView} from 'src/types'
import {RemoteDataState, QueryView, GetState} from 'src/types'
import {Dispatch} from 'redux'
import {View} from 'src/types'
import {Action as TimeMachineAction} from 'src/timeMachine/actions'
import {Action as CheckAction} from 'src/alerting/actions/checks'
// Actions
import {setActiveTimeMachine} from 'src/timeMachine/actions'
import {setCurrentCheck} from 'src/alerting/actions/checks'
import {TimeMachineID} from 'src/types'
export type Action = SetViewAction | SetViewsAction | ResetViewsAction
@ -96,17 +106,40 @@ export const getViewForTimeMachine = (
cellID: string,
timeMachineID: TimeMachineID
) => async (
dispatch: Dispatch<Action | TimeMachineAction | CheckAction>
dispatch: Dispatch<Action | TimeMachineAction | NotificationAction>,
getState: GetState
): Promise<void> => {
const state = getState()
dispatch(setView(cellID, null, RemoteDataState.Loading))
try {
const view = (await getViewAJAX(dashboardID, cellID)) as QueryView
if (view.properties.type === 'check') {
dispatch(setCurrentCheck(RemoteDataState.Done, view.properties.check))
let view = getViewFromState(state, cellID) as QueryView
if (!view) {
view = (await getViewAJAX(dashboardID, cellID)) as QueryView
}
dispatch(setView(cellID, view, RemoteDataState.Done))
dispatch(setActiveTimeMachine(timeMachineID, {view}))
} catch {
if (view.properties.type !== 'check') {
dispatch(setActiveTimeMachine(timeMachineID, {view}))
} else {
let check = getCheckFromState(state, view.properties.checkID)
if (!check) {
const resp = await api.getCheck({checkID: view.properties.checkID})
if (resp.status !== 200) {
throw new Error(resp.data.message)
}
check = resp.data
}
dispatch(
setActiveTimeMachine(timeMachineID, {
view,
alerting: {check, checkStatus: RemoteDataState.Done},
})
)
}
} catch (e) {
dispatch(notify(copy.getVieworCheckFailed(e.message)))
dispatch(setView(cellID, null, RemoteDataState.Error))
}
}

View File

@ -10,14 +10,12 @@ import TimeMachine from 'src/timeMachine/components/TimeMachine'
import VEOHeader from 'src/dashboards/components/VEOHeader'
// Actions
import {setActiveTimeMachine} from 'src/timeMachine/actions'
import {saveCurrentCheck} from 'src/alerting/actions/checks'
import {saveCheckFromTimeMachine} from 'src/alerting/actions/checks'
import {setName} from 'src/timeMachine/actions'
import {saveVEOView} from 'src/dashboards/actions'
import {setView, getViewForTimeMachine} from 'src/dashboards/actions/views'
import {getViewForTimeMachine} from 'src/dashboards/actions/views'
// Utils
import {getView} from 'src/dashboards/selectors'
import {getActiveTimeMachine} from 'src/timeMachine/selectors'
// Types
@ -25,11 +23,9 @@ import {AppState, RemoteDataState, QueryView, TimeMachineID} from 'src/types'
import {executeQueries} from 'src/timeMachine/actions/queries'
interface DispatchProps {
onSetActiveTimeMachine: typeof setActiveTimeMachine
saveCurrentCheck: typeof saveCurrentCheck
saveCheckFromTimeMachine: typeof saveCheckFromTimeMachine
onSetName: typeof setName
onSaveView: typeof saveVEOView
setView: typeof setView
executeQueries: typeof executeQueries
getViewForTimeMachine: typeof getViewForTimeMachine
}
@ -37,18 +33,15 @@ interface DispatchProps {
interface StateProps {
view: QueryView | null
activeTimeMachineID: TimeMachineID
draftView: QueryView
}
type Props = DispatchProps & StateProps & WithRouterProps
const EditViewVEO: FunctionComponent<Props> = ({
onSetActiveTimeMachine,
getViewForTimeMachine,
activeTimeMachineID,
saveCurrentCheck,
saveCheckFromTimeMachine,
executeQueries,
draftView,
onSaveView,
onSetName,
params: {orgID, cellID, dashboardID},
@ -56,12 +49,8 @@ const EditViewVEO: FunctionComponent<Props> = ({
view,
}) => {
useEffect(() => {
if (view) {
onSetActiveTimeMachine('veo', {view})
} else {
getViewForTimeMachine(dashboardID, cellID, 'veo')
}
}, [view, orgID, cellID, dashboardID])
getViewForTimeMachine(dashboardID, cellID, 'veo')
}, [cellID, dashboardID])
useEffect(() => {
executeQueries()
@ -74,14 +63,14 @@ const EditViewVEO: FunctionComponent<Props> = ({
const handleSave = () => {
try {
onSaveView(dashboardID)
if (draftView.properties.type === 'check') {
saveCurrentCheck()
if (view.properties.type === 'check') {
saveCheckFromTimeMachine()
}
handleClose()
} catch (e) {}
}
const viewMatchesRoute = get(draftView, 'id', null) === cellID
const viewMatchesRoute = get(view, 'id', null) === cellID
let loadingState = RemoteDataState.Loading
if (activeTimeMachineID === 'veo' && viewMatchesRoute) {
@ -111,21 +100,18 @@ const EditViewVEO: FunctionComponent<Props> = ({
)
}
const mstp = (state: AppState, {params: {cellID}}): StateProps => {
const mstp = (state: AppState): StateProps => {
const {activeTimeMachineID} = state.timeMachines
const view = getView(state, cellID) as QueryView
const {view: draftView} = getActiveTimeMachine(state)
const {view} = getActiveTimeMachine(state)
return {view, draftView, activeTimeMachineID}
return {view, activeTimeMachineID}
}
const mdtp: DispatchProps = {
onSetName: setName,
setView: setView,
onSaveView: saveVEOView,
onSetActiveTimeMachine: setActiveTimeMachine,
saveCurrentCheck: saveCurrentCheck,
saveCheckFromTimeMachine: saveCheckFromTimeMachine,
executeQueries: executeQueries,
getViewForTimeMachine: getViewForTimeMachine,
}

View File

@ -10,7 +10,7 @@ import TimeMachine from 'src/timeMachine/components/TimeMachine'
import VEOHeader from 'src/dashboards/components/VEOHeader'
// Actions
import {saveCurrentCheck} from 'src/alerting/actions/checks'
import {saveCheckFromTimeMachine} from 'src/alerting/actions/checks'
import {setActiveTimeMachine} from 'src/timeMachine/actions'
import {setName} from 'src/timeMachine/actions'
import {saveVEOView} from 'src/dashboards/actions'
@ -30,7 +30,7 @@ import {
interface DispatchProps {
onSetActiveTimeMachine: typeof setActiveTimeMachine
saveCurrentCheck: typeof saveCurrentCheck
saveCheckFromTimeMachine: typeof saveCheckFromTimeMachine
onSetName: typeof setName
onSaveView: typeof saveVEOView
}
@ -45,7 +45,7 @@ type Props = DispatchProps & StateProps & WithRouterProps
const NewViewVEO: FunctionComponent<Props> = ({
onSetActiveTimeMachine,
activeTimeMachineID,
saveCurrentCheck,
saveCheckFromTimeMachine,
onSaveView,
onSetName,
params: {orgID, dashboardID},
@ -66,7 +66,7 @@ const NewViewVEO: FunctionComponent<Props> = ({
onSaveView(dashboardID)
if (view.properties.type === 'check') {
saveCurrentCheck()
saveCheckFromTimeMachine()
}
handleClose()
@ -112,7 +112,7 @@ const mstp = (state: AppState): StateProps => {
const mdtp: DispatchProps = {
onSetName: setName,
onSaveView: saveVEOView,
saveCurrentCheck: saveCurrentCheck,
saveCheckFromTimeMachine: saveCheckFromTimeMachine,
onSetActiveTimeMachine: setActiveTimeMachine,
}

View File

@ -25,13 +25,13 @@ import {
Check,
Threshold,
} from 'src/types'
import {updateCurrentCheck} from 'src/alerting/actions/checks'
import {updateTimeMachineCheck} from 'src/timeMachine/actions'
const X_COLUMN = '_time'
const Y_COLUMN = '_value'
interface DispatchProps {
updateCurrentCheck: typeof updateCurrentCheck
updateTimeMachineCheck: typeof updateTimeMachineCheck
}
interface OwnProps {
@ -47,7 +47,7 @@ interface OwnProps {
type Props = OwnProps & DispatchProps
const CheckPlot: FunctionComponent<Props> = ({
updateCurrentCheck,
updateTimeMachineCheck,
table,
check,
fluxGroupKeyUnion,
@ -61,8 +61,8 @@ const CheckPlot: FunctionComponent<Props> = ({
thresholds = check.thresholds
}
const updateCheckThresholds = (thresholds: Threshold[]) => {
updateCurrentCheck({thresholds})
const updateTimeMachineCheckThresholds = (thresholds: Threshold[]) => {
updateTimeMachineCheck({thresholds})
}
const [yDomain, onSetYDomain, onResetYDomain] = useVisDomainSettings(
@ -128,7 +128,7 @@ const CheckPlot: FunctionComponent<Props> = ({
<ThresholdMarkers
key="custom"
thresholds={thresholds}
onSetThresholds={updateCheckThresholds}
onSetThresholds={updateTimeMachineCheckThresholds}
yScale={yScale}
yDomain={yDomain}
/>
@ -146,7 +146,7 @@ const CheckPlot: FunctionComponent<Props> = ({
}
const mdtp: DispatchProps = {
updateCurrentCheck: updateCurrentCheck,
updateTimeMachineCheck: updateTimeMachineCheck,
}
export default connect<{}, DispatchProps, {}>(

View File

@ -794,3 +794,8 @@ export const deleteRuleFailed = (message: string): Notification => ({
...defaultErrorNotification,
message: `Failed to delete notification rule: ${message}`,
})
export const getVieworCheckFailed = (message: string): Notification => ({
...defaultErrorNotification,
message: `Failed to load resources for cell: ${message}`,
})

View File

@ -21,9 +21,12 @@ import {
TimeMachineTab,
AutoRefresh,
TimeMachineID,
Check,
CheckType,
} from 'src/types'
import {Color} from 'src/types/colors'
import {HistogramPosition} from '@influxdata/giraffe'
import {RemoteDataState} from '@influxdata/clockface'
export type Action =
| QueryBuilderAction
@ -77,6 +80,10 @@ export type Action =
| ReturnType<typeof convertFromCheckView>
| ReturnType<typeof toggleAlertingPanel>
| ReturnType<typeof toggleVisOptions>
| ReturnType<typeof setCheckStatus>
| ReturnType<typeof setTimeMachineCheck>
| ReturnType<typeof updateTimeMachineCheck>
| ReturnType<typeof changeCheckType>
interface SetActiveTimeMachineAction {
type: 'SET_ACTIVE_TIME_MACHINE'
@ -613,3 +620,26 @@ export const convertFromCheckView = () => ({
export const toggleAlertingPanel = () => ({
type: 'TOGGLE_ALERTING_PANEL' as 'TOGGLE_ALERTING_PANEL',
})
export const setCheckStatus = (checkStatus: RemoteDataState) => ({
type: 'SET_TIMEMACHINE_CHECK_STATUS' as 'SET_TIMEMACHINE_CHECK_STATUS',
payload: {checkStatus},
})
export const setTimeMachineCheck = (
checkStatus: RemoteDataState,
check: Partial<Check>
) => ({
type: 'SET_TIMEMACHINE_CHECK' as 'SET_TIMEMACHINE_CHECK',
payload: {checkStatus, check},
})
export const updateTimeMachineCheck = (checkUpdate: Partial<Check>) => ({
type: 'UPDATE_TIMEMACHINE_CHECK' as 'UPDATE_TIMEMACHINE_CHECK',
payload: {checkUpdate},
})
export const changeCheckType = (toType: CheckType) => ({
type: 'CHANGE_TIMEMACHINE_CHECK_TYPE' as 'CHANGE_TIMEMACHINE_CHECK_TYPE',
payload: {toType},
})

View File

@ -5,36 +5,23 @@ import {Link} from 'react-router'
import {Button, ComponentColor, IconFont} from '@influxdata/clockface'
// Actions
import {setCurrentCheck} from 'src/alerting/actions/checks'
import {convertToCheckView} from 'src/timeMachine/actions'
// Constants
import {DEFAULT_THRESHOLD_CHECK} from 'src/alerting/constants'
// Types
import {AppState, RemoteDataState} from 'src/types'
import {AppState} from 'src/types'
interface StateProps {
orgID: string
}
interface DispatchProps {
onSetCurrentCheck: typeof setCurrentCheck
onConvertToCheckView: typeof convertToCheckView
}
type Props = StateProps & DispatchProps
const AddCheckDialog: FC<Props> = ({
orgID,
onSetCurrentCheck,
onConvertToCheckView,
}) => {
const AddCheckDialog: FC<Props> = ({orgID, onConvertToCheckView}) => {
const handleClick = () => {
// TODO: Move the current check state into the time machine reducer, then
// handle this state transition as part `CONVERT_TO_CHECK_VIEW` transition
onSetCurrentCheck(RemoteDataState.Done, DEFAULT_THRESHOLD_CHECK)
onConvertToCheckView()
}
@ -60,7 +47,6 @@ const mstp = (state: AppState): StateProps => {
}
const mdtp = {
onSetCurrentCheck: setCurrentCheck,
onConvertToCheckView: convertToCheckView,
}

View File

@ -121,14 +121,9 @@ const mstp = (state: AppState): StateProps => {
isViewingRawData,
view: {properties: viewProperties},
queryResults: {status: loading, errorMessage, isInitialFetch, files},
alerting: {check},
} = getActiveTimeMachine(state)
const {
checks: {
current: {check},
},
} = state
const giraffeResult = getVisTable(state)
const xColumn = getXColumnSelection(state)
const yColumn = getYColumnSelection(state)

View File

@ -1,7 +1,6 @@
// Libraries
import {get, cloneDeep, isNumber} from 'lodash'
import {omit, map, get, cloneDeep, isNumber} from 'lodash'
import {produce} from 'immer'
import _ from 'lodash'
// Utils
import {createView, defaultViewQuery} from 'src/shared/utils/view'
@ -13,9 +12,20 @@ import {
THRESHOLD_TYPE_TEXT,
THRESHOLD_TYPE_BG,
} from 'src/shared/constants/thresholds'
import {
DEFAULT_THRESHOLD_CHECK,
DEFAULT_DEADMAN_CHECK,
} from 'src/alerting/constants'
// Types
import {TimeRange, View, AutoRefresh} from 'src/types'
import {
TimeRange,
View,
AutoRefresh,
Check,
DeadmanCheck,
ThresholdCheck,
} from 'src/types'
import {
ViewType,
DashboardDraftQuery,
@ -53,8 +63,14 @@ interface QueryResultsState {
errorMessage: string
}
interface AlertingState {
check: Partial<Check>
checkStatus: RemoteDataState
}
export interface TimeMachineState {
view: QueryView
alerting: AlertingState
timeRange: TimeRange
autoRefresh: AutoRefresh
draftQueries: DashboardDraftQuery[]
@ -79,6 +95,10 @@ export const initialStateHelper = (): TimeMachineState => ({
timeRange: {lower: 'now() - 1h'},
autoRefresh: AUTOREFRESH_DEFAULT,
view: createView(),
alerting: {
check: DEFAULT_THRESHOLD_CHECK,
checkStatus: RemoteDataState.NotStarted,
},
draftQueries: [{...defaultViewQuery(), hidden: false}],
isViewingRawData: false,
isViewingVisOptions: false,
@ -120,7 +140,7 @@ export const timeMachinesReducer = (
const {activeTimeMachineID, initialState} = action.payload
const activeTimeMachine = state.timeMachines[activeTimeMachineID]
const view = initialState.view || activeTimeMachine.view
const draftQueries = _.map(cloneDeep(view.properties.queries), q => ({
const draftQueries = map(cloneDeep(view.properties.queries), q => ({
...q,
hidden: false,
}))
@ -817,13 +837,26 @@ export const timeMachineReducer = (
case 'CONVERT_TO_CHECK_VIEW': {
const view = convertView(state.view, 'check')
return {...state, view, activeTab: 'alerting'}
return {
...state,
view,
activeTab: 'alerting',
alerting: {
checkStatus: RemoteDataState.Done,
check: DEFAULT_THRESHOLD_CHECK,
},
}
}
case 'CONVERT_FROM_CHECK_VIEW': {
const view = convertView(state.view, 'xy')
return {...state, view, activeTab: 'queries'}
return {
...state,
view,
activeTab: 'queries',
alerting: {checkStatus: RemoteDataState.NotStarted, check: null},
}
}
case 'TOGGLE_ALERTING_PANEL': {
@ -838,6 +871,44 @@ export const timeMachineReducer = (
return {...state, activeTab: 'queries'}
}
}
case 'SET_TIMEMACHINE_CHECK_STATUS': {
const {checkStatus} = action.payload
return {...state, alerting: {...state.alerting, checkStatus}}
}
case 'SET_TIMEMACHINE_CHECK':
const alerting = {
check: action.payload.check,
checkStatus: action.payload.checkStatus,
}
return {...state, alerting}
case 'UPDATE_TIMEMACHINE_CHECK':
const updatedCheck = {
...state.alerting.check,
...action.payload.checkUpdate,
} as Partial<Check>
return {...state, alerting: {...state.alerting, check: updatedCheck}}
case 'CHANGE_TIMEMACHINE_CHECK_TYPE':
return produce(state, draftState => {
const exCheck = draftState.alerting.check
if (action.payload.toType == 'deadman') {
draftState.alerting.check = {
...DEFAULT_DEADMAN_CHECK,
...omit(exCheck, ['thresholds', 'type']),
} as DeadmanCheck
}
if (action.payload.toType == 'threshold') {
draftState.alerting.check = {
...DEFAULT_THRESHOLD_CHECK,
...omit(exCheck, ['timeSince', 'reportZero', 'level', 'type']),
} as ThresholdCheck
}
})
}
return state
@ -881,7 +952,7 @@ const updateCorrectColors = (
const view: any = state.view
const colors = view.properties.colors
if (_.get(update, '0.type', '') === 'scale') {
if (get(update, '0.type', '') === 'scale') {
return [...colors.filter(c => c.type !== 'scale'), ...update]
}
return [...colors.filter(c => c.type === 'scale'), ...update]