Skip to content

Commit 6ee9585

Browse files
subirjollySubir Jolly
andauthored
feat: show subscription statuses in ui (#5060)
* feat: show subscriptions in ui * chore: remove unnecessary fluff * chore: add overlay * style: fix ts issue * chore: change error display flow * chore: convert to bool * chore: update oats generation for oss subscriptionsRoutes * chore: update messages to be subtle * chore: add missing sass file * chore: add tests * chore: update per review * chore: fixing test * chore: update test to wait for statuses * chore: update assertion * style: fix style issue Co-authored-by: Subir Jolly <sjolly@influxdata.com>
1 parent c579666 commit 6ee9585

File tree

12 files changed

+507
-75
lines changed

12 files changed

+507
-75
lines changed

cypress/e2e/cloud/subscriptions.test.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ describe('Subscriptions', () => {
2424
cy.intercept('GET', `/api/v2private/broker/subs*`).as(
2525
'GetSubscriptions'
2626
)
27+
cy.intercept('GET', '/api/v2private/broker/subs/statuses', []).as(
28+
'GetStatuses'
29+
)
2730
})
2831
})
2932
})
@@ -104,11 +107,18 @@ describe('Subscriptions', () => {
104107

105108
// subscriptions list view
106109
cy.get('.subscriptions-list').should('be.visible')
110+
cy.wait('@GetStatuses')
107111
cy.getByTestID('subscription-card')
108112
.should('be.visible')
109113
.should('have.length', 2)
110-
111-
// Search for subscription1 name(partial match)
114+
cy.getByTestID('subscription-card')
115+
.children()
116+
.getByTestID('copy-subscription--component')
117+
.should('be.visible')
118+
cy.getByTestID('subscription-card')
119+
.children()
120+
.getByTestID(`subscription-notifications--label No Notifications`)
121+
.should('be.visible')
112122
cy.getByTestID('search-widget')
113123
.clear()
114124
.type('my ')
@@ -161,9 +171,10 @@ describe('Subscriptions', () => {
161171

162172
it('should create, update, stop, start and delete LP subscription', () => {
163173
let subscription = 'My Subscription'
174+
// subscriptions list view
164175
createBasicLPSubscription(subscription)
176+
cy.wait('@GetStatuses')
165177

166-
// subscriptions list view
167178
cy.get('.subscriptions-list').should('be.visible')
168179
cy.get('.cf-resource-card').should('be.visible')
169180
cy.get('.cf-resource-card').should('have.length', 1)
@@ -195,6 +206,10 @@ describe('Subscriptions', () => {
195206
cy.getByTestID('update-sub-form--edit')
196207
.should('be.visible')
197208
.click()
209+
210+
cy.getByTestID(`subscription-notifications--label No Notification`).should(
211+
'not.exist'
212+
)
198213
subscription = 'My Edited Subscription'
199214
cy.getByTestID('update-broker-form--name').should('be.visible')
200215
cy.getByTestID('update-broker-form--name')

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@
5454
"cy:dev-oss": "source ../monitor-ci/.env && CYPRESS_dexUrl=OSS CYPRESS_baseUrl=https://$INGRESS_HOST:$PORT_HTTPS cypress open --config testFiles='{oss,shared}/**/*.*'",
5555
"generate": "export SHA=8cfd00c5b9d7781b510d27304557d323dca0a9c6 && export REMOTE=https://raw.githubusercontent.com/influxdata/openapi/${SHA}/ && yarn generate-meta",
5656
"generate-local": "export REMOTE=../openapi/ && yarn generate-meta",
57+
"generate-local-cloud": "export REMOTE=../openapi/ && yarn generate-meta-cloud",
5758
"generate-meta": "if [ -z \"${CLOUD_URL}\" ]; then yarn generate-meta-oss; else yarn generate-meta-cloud; fi",
58-
"generate-meta-oss": "yarn oss-api && yarn notebooks && yarn unity && yarn annotations-oss && yarn pinned && yarn mapsd-oss && yarn uiproxyd-oss && yarn cloudPriv && yarn fluxdocs && yarn subscriptions-oss",
59+
"generate-meta-oss": "yarn oss-api && yarn notebooks && yarn unity && yarn annotations-oss && yarn pinned && yarn mapsd-oss && yarn uiproxyd-oss && yarn cloudPriv && yarn fluxdocs && yarn subscriptions",
5960
"generate-meta-cloud": "yarn cloud-api && yarn notebooks && yarn unity && yarn annotations && yarn cloudPriv && yarn pinned && yarn mapsd && yarn uiproxyd && yarn fluxdocs && yarn subscriptions",
6061
"oss": "oats ${REMOTE}contracts/oss-diff.yml > ./src/client/ossRoutes.ts",
6162
"cloud": "oats ${REMOTE}contracts/cloud-diff.yml > ./src/client/cloudRoutes.ts",
@@ -72,7 +73,6 @@
7273
"uiproxyd-oss": "touch ./src/client/uiproxydRoutes.ts",
7374
"uiproxyd": "oats ${REMOTE}contracts/priv/uiproxyd.yml > ./src/client/uiproxydRoutes.ts",
7475
"subscriptions": "oats ${REMOTE}contracts/priv/nifid.yml > ./src/client/subscriptionsRoutes.ts",
75-
"subscriptions-oss": "touch ./src/client/subscriptionsRoutes.ts",
7676
"pinned": "oats ${REMOTE}contracts/priv/pinneditemsd.yml > ./src/client/pinnedItemRoutes.ts",
7777
"fluxdocs": "oats ${REMOTE}contracts/priv/fluxdocsd.yml > ./src/client/fluxdocsdRoutes.ts",
7878
"telegraf-plugins:update": "node src/writeData/utils/updateTelegrafPlugins.mjs"

src/shared/copy/notifications/categories/subscriptions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ export const subscriptionsGetFail = (): Notification => ({
2222
message: `Failed to get Subscriptions, please try again.`,
2323
})
2424

25+
export const subscriptionStatusesGetFail = (): Notification => ({
26+
...defaultErrorNotification,
27+
message: `Failed to get Subscription Statuses, please try again.`,
28+
})
29+
2530
export const subscriptionsDeleteFail = (): Notification => ({
2631
...defaultErrorNotification,
2732
message: `Failed to delete the Subscription, please try again.`,

src/types/subscriptions.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ export interface Subscription {
3636
notebookID?: string
3737
}
3838

39+
export interface SubscriptionStatus {
40+
isActive?: boolean
41+
processors?: any
42+
processGroupID?: string
43+
id: string
44+
}
45+
3946
export interface JsonSpec {
4047
path?: string
4148
name?: string
Lines changed: 102 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Libraries
2-
import React, {FC} from 'react'
2+
import React, {FC, useCallback, useContext, useState} from 'react'
33

44
// Components
55
import {
@@ -14,80 +14,118 @@ import {
1414
ReflessPopover,
1515
PopoverPosition,
1616
PopoverInteraction,
17+
Label,
18+
InfluxColors,
1719
} from '@influxdata/clockface'
1820

1921
// Types
2022
import {Subscription} from 'src/types/subscriptions'
23+
import {SubscriptionListContext} from '../context/subscription.list'
24+
import SubscriptionErrorsOverlay from './SubscriptionErrorsOverlay'
2125

2226
interface Props {
2327
currentSubscription: Subscription
2428
setStatus: (any) => void
2529
}
2630

27-
const StatusHeader: FC<Props> = ({currentSubscription, setStatus}) => (
28-
<FlexBox>
29-
<Heading
30-
element={HeadingElement.H3}
31-
weight={FontWeight.Regular}
32-
className="subscription-details-page__status"
33-
>
34-
Status:
35-
<span
36-
className={
37-
currentSubscription &&
38-
`subscription-details-page__status--${currentSubscription.status}`
39-
}
40-
>
41-
{currentSubscription && currentSubscription.status}
42-
</span>
43-
</Heading>
44-
{!(
45-
currentSubscription.status === 'VALIDATING' ||
46-
currentSubscription.status === 'INVALID'
47-
) &&
48-
(currentSubscription.status !== 'ERRORED' ? (
49-
<Button
50-
text={currentSubscription.status === 'RUNNING' ? 'stop' : 'start'}
51-
color={
52-
currentSubscription.status === 'RUNNING'
53-
? ComponentColor.Danger
54-
: ComponentColor.Success
55-
}
56-
onClick={() => {
57-
if (currentSubscription.status === 'RUNNING') {
58-
setStatus(false)
59-
} else {
60-
setStatus(true)
61-
}
62-
}}
63-
type={ButtonType.Submit}
64-
testID="subscription-details-page--status-button"
65-
status={
66-
currentSubscription.status === 'ERRORED'
67-
? ComponentStatus.Disabled
68-
: ComponentStatus.Default
69-
}
70-
className="subscription-details-page__status--button"
71-
/>
72-
) : (
73-
<ReflessPopover
74-
position={PopoverPosition.Below}
75-
showEvent={PopoverInteraction.Hover}
76-
hideEvent={PopoverInteraction.Hover}
77-
style={{width: 'max-content'}}
78-
contents={() => <>cannot start flow in errored state</>}
31+
const StatusHeader: FC<Props> = ({currentSubscription, setStatus}) => {
32+
const {bulletins: allBulletins} = useContext(SubscriptionListContext)
33+
const bulletins = allBulletins?.[currentSubscription.id] ?? []
34+
const [isOverlayVisible, setIsOverlayVisible] = useState<boolean>(false)
35+
36+
const handleShowNotifications = useCallback(() => {
37+
setIsOverlayVisible(true)
38+
}, [setIsOverlayVisible])
39+
40+
return (
41+
<>
42+
<FlexBox>
43+
<Heading
44+
element={HeadingElement.H3}
45+
weight={FontWeight.Regular}
46+
className="subscription-details-page__status"
7947
>
80-
<Button
81-
text="start"
82-
color={ComponentColor.Success}
83-
type={ButtonType.Submit}
84-
testID="subscription-details-page--status-button"
85-
status={ComponentStatus.Disabled}
86-
className="subscription-details-page__status--button"
48+
Status:
49+
<span
50+
className={
51+
currentSubscription &&
52+
`subscription-details-page__status--${currentSubscription.status}`
53+
}
54+
>
55+
{currentSubscription && currentSubscription.status}
56+
</span>
57+
</Heading>
58+
{!(
59+
currentSubscription.status === 'VALIDATING' ||
60+
currentSubscription.status === 'INVALID'
61+
) &&
62+
(currentSubscription.status !== 'ERRORED' ? (
63+
<Button
64+
text={currentSubscription.status === 'RUNNING' ? 'stop' : 'start'}
65+
color={
66+
currentSubscription.status === 'RUNNING'
67+
? ComponentColor.Danger
68+
: ComponentColor.Success
69+
}
70+
onClick={() => {
71+
if (currentSubscription.status === 'RUNNING') {
72+
setStatus(false)
73+
} else {
74+
setStatus(true)
75+
}
76+
}}
77+
type={ButtonType.Submit}
78+
testID="subscription-details-page--status-button"
79+
status={
80+
currentSubscription.status === 'ERRORED'
81+
? ComponentStatus.Disabled
82+
: ComponentStatus.Default
83+
}
84+
className="subscription-details-page__status--button"
85+
/>
86+
) : (
87+
<ReflessPopover
88+
position={PopoverPosition.Below}
89+
showEvent={PopoverInteraction.Hover}
90+
hideEvent={PopoverInteraction.Hover}
91+
style={{width: 'max-content'}}
92+
contents={() => <>cannot start flow in errored state</>}
93+
>
94+
<Button
95+
text="start"
96+
color={ComponentColor.Success}
97+
type={ButtonType.Submit}
98+
testID="subscription-details-page--status-button"
99+
status={ComponentStatus.Disabled}
100+
className="subscription-details-page__status--button"
101+
/>
102+
</ReflessPopover>
103+
))}
104+
{!!bulletins.length && (
105+
<Label
106+
id="tid"
107+
key="tkey"
108+
name={`${bulletins.length} Notification${
109+
bulletins.length === 1 ? '' : 's'
110+
}`}
111+
color={InfluxColors.Grey25}
112+
description={`${bulletins.length} Notification${
113+
bulletins.length === 1 ? '' : 's'
114+
}`}
115+
onClick={handleShowNotifications}
116+
testID="subscription-notifications--label"
87117
/>
88-
</ReflessPopover>
89-
))}
90-
</FlexBox>
91-
)
118+
)}
119+
</FlexBox>
120+
121+
{isOverlayVisible && (
122+
<SubscriptionErrorsOverlay
123+
bulletins={bulletins}
124+
handleClose={() => setIsOverlayVisible(false)}
125+
/>
126+
)}
127+
</>
128+
)
129+
}
92130

93131
export default StatusHeader
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
@import '@influxdata/clockface/dist/variables.scss';
2+
.copy-subscription-id {
3+
transition: color 0.25s ease;
4+
5+
&:hover {
6+
cursor: pointer;
7+
color: $c-pool;
8+
}
9+
}
10+
11+
.copy-subscription-id--helper {
12+
color: $cf-grey-75;
13+
transition: opacity 0.25s ease;
14+
opacity: 0;
15+
display: inline-block;
16+
margin-left: $cf-space-2xs;
17+
}
18+
19+
.copy-subscription-id:hover .copy-subscription-id--helper {
20+
opacity: 1;
21+
}

0 commit comments

Comments
 (0)