Skip to content

Commit 942eb75

Browse files
authored
fix(3629): cannot create rules from deactive endpoints (#3832)
* 3629: use overlay controller to create new rule, remove older connector pattern in favor of new selector pattern, create selectors to fetch needed state, make selector for only activeEndpoints (the bug). follow resource state pattern in selector.
1 parent 1a78eb8 commit 942eb75

File tree

8 files changed

+67
-105
lines changed

8 files changed

+67
-105
lines changed

src/alerting/components/AlertingIndex.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import GetAssetLimits from 'src/cloud/components/GetAssetLimits'
1717
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
1818
import GetResources from 'src/resources/components/GetResources'
1919
import EditCheckEO from 'src/checks/components/EditCheckEO'
20-
import NewRuleOverlay from 'src/notifications/rules/components/NewRuleOverlay'
2120
import EditRuleOverlay from 'src/notifications/rules/components/EditRuleOverlay'
2221
import NewEndpointOverlay from 'src/notifications/endpoints/components/NewEndpointOverlay'
2322
import EditEndpointOverlay from 'src/notifications/endpoints/components/EditEndpointOverlay'
@@ -168,7 +167,6 @@ const AlertingIndex: FunctionComponent = () => {
168167
path={`${alertsPath}/checks/:checkID/edit`}
169168
component={EditCheckEO}
170169
/>
171-
<Route path={`${alertsPath}/rules/new`} component={NewRuleOverlay} />
172170
<Route
173171
path={`${alertsPath}/rules/:ruleID/edit`}
174172
component={EditRuleOverlay}

src/notifications/endpoints/selectors/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,16 @@ export const sortEndpointsByName = (
1313
endpoints.sort((a, b) =>
1414
a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1
1515
)
16+
17+
export const getAllActiveEndpoints = (
18+
state: AppState
19+
): NotificationEndpoint[] => {
20+
const endpoints = state.resources.endpoints.allIDs.reduce(
21+
(acc, id) =>
22+
state.resources.endpoints.byID[id]?.activeStatus == 'active'
23+
? acc.concat([state.resources.endpoints.byID[id]])
24+
: acc,
25+
[]
26+
)
27+
return !!endpoints.length ? sortEndpointsByName(endpoints) : []
28+
}
Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
// Libraries
2-
import React, {useMemo, FC} from 'react'
3-
import {withRouter, RouteComponentProps} from 'react-router-dom'
4-
import {connect, ConnectedProps} from 'react-redux'
2+
import React, {useMemo, FC, useContext} from 'react'
3+
import {useDispatch, useSelector} from 'react-redux'
54

6-
// Actions
5+
// Actions, Selectors
76
import {createRule} from 'src/notifications/rules/actions/thunks'
7+
import {getOrg} from 'src/organizations/selectors'
8+
9+
// Contexts
10+
import {OverlayContext} from 'src/overlays/components/OverlayController'
811

912
// Components
1013
import RuleOverlayContents from 'src/notifications/rules/components/RuleOverlayContents'
@@ -17,24 +20,14 @@ import {initRuleDraft} from 'src/notifications/rules/utils'
1720
// Types
1821
import {NotificationRuleDraft} from 'src/types'
1922

20-
type ReduxProps = ConnectedProps<typeof connector>
21-
type Props = RouteComponentProps<{orgID: string}> & ReduxProps
22-
23-
const NewRuleOverlay: FC<Props> = ({
24-
match: {
25-
params: {orgID},
26-
},
27-
history,
28-
onCreateRule,
29-
}) => {
30-
const handleDismiss = () => {
31-
history.push(`/orgs/${orgID}/alerting`)
32-
}
23+
const NewRuleOverlay: FC = () => {
24+
const dispatch = useDispatch()
25+
const {onClose} = useContext(OverlayContext)
26+
const orgID = useSelector(getOrg)?.id
3327

3428
const handleCreateRule = async (rule: NotificationRuleDraft) => {
35-
await onCreateRule(rule)
36-
37-
handleDismiss()
29+
await dispatch(createRule(rule))
30+
onClose()
3831
}
3932

4033
const initialState = useMemo(() => initRuleDraft(orgID), [orgID])
@@ -45,7 +38,7 @@ const NewRuleOverlay: FC<Props> = ({
4538
<Overlay.Container maxWidth={800}>
4639
<Overlay.Header
4740
title="Create a Notification Rule"
48-
onDismiss={handleDismiss}
41+
onDismiss={onClose}
4942
testID="dismiss-overlay"
5043
/>
5144
<Overlay.Body>
@@ -60,10 +53,4 @@ const NewRuleOverlay: FC<Props> = ({
6053
)
6154
}
6255

63-
const mdtp = {
64-
onCreateRule: createRule,
65-
}
66-
67-
const connector = connect(null, mdtp)
68-
69-
export default connector(withRouter(NewRuleOverlay))
56+
export default NewRuleOverlay

src/notifications/rules/components/RuleMessage.tsx

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Libraries
22
import React, {FC, useEffect} from 'react'
3-
import {connect} from 'react-redux'
3+
import {useSelector} from 'react-redux'
44

55
// Components
66
import {
@@ -16,29 +16,19 @@ import RuleMessageContents from 'src/notifications/rules/components/RuleMessageC
1616

1717
// Utils
1818
import {getRuleVariantDefaults} from 'src/notifications/rules/utils'
19-
import {getAll} from 'src/resources/selectors'
19+
import {getAllActiveEndpoints} from 'src/notifications/endpoints/selectors'
2020
import {useRuleDispatch} from './RuleOverlayProvider'
2121

2222
// Types
23-
import {
24-
NotificationEndpoint,
25-
NotificationRuleDraft,
26-
AppState,
27-
ResourceType,
28-
} from 'src/types'
29-
30-
interface StateProps {
31-
endpoints: NotificationEndpoint[]
32-
}
23+
import {NotificationRuleDraft} from 'src/types'
3324

34-
interface OwnProps {
25+
interface Props {
3526
rule: NotificationRuleDraft
3627
}
3728

38-
type Props = OwnProps & StateProps
39-
40-
const RuleMessage: FC<Props> = ({endpoints, rule}) => {
29+
const RuleMessage: FC<Props> = ({rule}) => {
4130
const dispatch = useRuleDispatch()
31+
const endpoints = useSelector(getAllActiveEndpoints)
4232

4333
const onSelectEndpoint = endpointID => {
4434
dispatch({
@@ -80,15 +70,4 @@ const RuleMessage: FC<Props> = ({endpoints, rule}) => {
8070
)
8171
}
8272

83-
const mstp = (state: AppState) => {
84-
const endpoints = getAll<NotificationEndpoint>(
85-
state,
86-
ResourceType.NotificationEndpoints
87-
)
88-
89-
return {
90-
endpoints,
91-
}
92-
}
93-
94-
export default connect(mstp)(RuleMessage)
73+
export default RuleMessage

src/notifications/rules/components/RulesColumn.tsx

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
// Libraries
22
import React, {FunctionComponent} from 'react'
3-
import {connect} from 'react-redux'
4-
import {withRouter, RouteComponentProps} from 'react-router-dom'
3+
import {useDispatch, useSelector} from 'react-redux'
54

65
// Types
7-
import {
8-
NotificationEndpoint,
9-
NotificationRuleDraft,
10-
AppState,
11-
ResourceType,
12-
} from 'src/types'
6+
import {ResourceType} from 'src/types'
137

148
// Components
159
import {
@@ -20,34 +14,30 @@ import {
2014
} from '@influxdata/clockface'
2115
import NotificationRuleCards from 'src/notifications/rules/components/RuleCards'
2216
import AlertsColumn from 'src/alerting/components/AlertsColumn'
17+
import {showOverlay, dismissOverlay} from 'src/overlays/actions/overlays'
2318

2419
// Constants
2520
import {DOCS_URL_VERSION} from 'src/shared/constants/fluxFunctions'
2621

2722
// Selectors
28-
import {getAll} from 'src/resources/selectors'
23+
import {getAllActiveEndpoints} from 'src/notifications/endpoints/selectors'
24+
import {getAllRules} from 'src/notifications/rules/selectors'
2925

30-
interface OwnProps {
31-
tabIndex: number
32-
}
26+
// Utils
27+
import {event} from 'src/cloud/utils/reporting'
3328

34-
interface StateProps {
35-
rules: NotificationRuleDraft[]
36-
endpoints: NotificationEndpoint[]
29+
interface Props {
30+
tabIndex: number
3731
}
3832

39-
type Props = OwnProps & StateProps & RouteComponentProps<{orgID: string}>
33+
const NotificationRulesColumn: FunctionComponent<Props> = ({tabIndex}) => {
34+
const dispatch = useDispatch()
35+
const endpoints = useSelector(getAllActiveEndpoints)
36+
const rules = useSelector(getAllRules)
4037

41-
const NotificationRulesColumn: FunctionComponent<Props> = ({
42-
rules,
43-
history,
44-
match,
45-
endpoints,
46-
tabIndex,
47-
}) => {
4838
const handleOpenOverlay = () => {
49-
const newRuleRoute = `/orgs/${match.params.orgID}/alerting/rules/new`
50-
history.push(newRuleRoute)
39+
event('Create Notification Rule opened')
40+
dispatch(showOverlay('create-rule', null, () => dispatch(dismissOverlay())))
5141
}
5242

5343
const tooltipContents = (
@@ -106,21 +96,4 @@ const NotificationRulesColumn: FunctionComponent<Props> = ({
10696
)
10797
}
10898

109-
const mstp = (state: AppState) => {
110-
const rules = getAll<NotificationRuleDraft>(
111-
state,
112-
ResourceType.NotificationRules
113-
)
114-
115-
const endpoints = getAll<NotificationEndpoint>(
116-
state,
117-
ResourceType.NotificationEndpoints
118-
)
119-
120-
return {rules, endpoints}
121-
}
122-
123-
export default connect<StateProps>(
124-
mstp,
125-
null
126-
)(withRouter(NotificationRulesColumn))
99+
export default NotificationRulesColumn
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {AppState, NotificationRuleDraft} from 'src/types'
1+
import {AppState, ResourceType, NotificationRuleDraft} from 'src/types'
2+
import {getAll} from 'src/resources/selectors'
23

34
export const getRuleIDs = (state: AppState): {[x: string]: boolean} => {
45
return state.resources.rules.allIDs.reduce(
@@ -7,7 +8,13 @@ export const getRuleIDs = (state: AppState): {[x: string]: boolean} => {
78
)
89
}
910

10-
export const sortRulesByName = (
11-
rules: NotificationRuleDraft[]
12-
): NotificationRuleDraft[] =>
11+
export const sortRulesByName = <T extends {name: string}>(rules: T[]): T[] =>
1312
rules.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1))
13+
14+
export const getAllRules = (state: AppState) => {
15+
const rules = getAll<NotificationRuleDraft>(
16+
state,
17+
ResourceType.NotificationRules
18+
)
19+
return !!rules.length ? sortRulesByName(rules) : []
20+
}

src/overlays/components/OverlayController.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import AutoRefreshOverlay from 'src/dashboards/components/AutoRefreshOverlay'
3535
import CellCloneOverlay from 'src/shared/components/cells/CellCloneOverlay'
3636
import CustomApiTokenOverlay from 'src/authorizations/components/CustomApiTokenOverlay'
3737
import DisplayTokenOverlay from 'src/authorizations/components/DisplayTokenOverlay'
38+
import NewRuleOverlay from 'src/notifications/rules/components/NewRuleOverlay'
3839
import CreateSecretOverlay from 'src/secrets/components/CreateSecret/CreateSecretOverlay'
3940

4041
// Actions
@@ -132,6 +133,9 @@ export const OverlayController: FunctionComponent = () => {
132133
case 'cell-copy-overlay':
133134
activeOverlay.current = <CellCloneOverlay />
134135
break
136+
case 'create-rule':
137+
activeOverlay.current = <NewRuleOverlay />
138+
break
135139
case 'create-secret':
136140
activeOverlay.current = <CreateSecretOverlay />
137141
break

src/overlays/reducers/overlays.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export type OverlayID =
2727
| 'toggle-auto-refresh'
2828
| 'cell-copy-overlay'
2929
| 'bucket-schema-show'
30+
| 'create-rule'
3031
| 'create-secret'
3132

3233
export interface OverlayState {

0 commit comments

Comments
 (0)