Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): add mqtt eol overlay and alert banner #6835

Merged
merged 3 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1535,8 +1535,8 @@ export const createTaskFromEmpty = (

export const disableClickThroughAnnouncement = () => {
const announcementState = {
announcementID: 'payg-pricing-increase-announcement',
display: false,
mqttEolClickThroughAnnouncement: 'dismissed',
pricingClickThroughAnnouncement: 'dismissed',
}

window.localStorage.setItem(
Expand Down
89 changes: 59 additions & 30 deletions src/homepageExperience/ClickThroughAnnouncementHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,84 @@ import {selectCurrentIdentity} from 'src/identity/selectors'

// Utils
import {showOverlay, dismissOverlay} from 'src/overlays/actions/overlays'
import {isFlagEnabled} from 'src/shared/utils/featureFlag'
import {event} from 'src/cloud/utils/reporting'

export enum AnnouncementID {
MqttEol = 'mqttEolClickThroughAnnouncement',
PriceIncrease = 'pricingClickThroughAnnouncement',
}

enum AnnouncementState {
Dismissed = 'dismissed',
Display = 'display',
}

export const ClickThroughAnnouncementHandler: FC = () => {
const dispatch = useDispatch()
const {account} = useSelector(selectCurrentIdentity)

const [announcementState, setAnnouncementState] = useLocalStorageState(
'clickThroughAnnouncement',
{
announcementID: '',
display: true,
}
{}
)

const setCurrentAnnouncement = (announcementID: string): void => {
if (announcementState['announcementID'] !== announcementID) {
setAnnouncementState({
announcementID: announcementID,
display: true,
})
const initAnnouncement = (announcementID: string): void => {
if (!announcementState[announcementID]) {
setAnnouncementState(prevState => ({
...prevState,
[announcementID]: AnnouncementState.Display,
}))
}
}

const handleDismissAnnouncement = (): void => {
setAnnouncementState(prevState => ({
...prevState,
display: false,
}))
const handleDismissAnnouncement = (announcementID: string): void => {
dismissOverlay()
event(`${announcementID}.dismissed`)
setTimeout(() => {
setAnnouncementState(prevState => ({
...prevState,
[announcementID]: AnnouncementState.Dismissed,
}))
}, 1000)
}

const handleDisplayAnnouncement = (announcementID: string): void => {
initAnnouncement(announcementID)

if (announcementState[announcementID] === AnnouncementState.Display) {
const overlayParams = {
announcementID,
}
dispatch(
showOverlay('click-through-announcement', overlayParams, () =>
handleDismissAnnouncement(announcementID)
)
)
}
}

useEffect(() => {
// Current Announcement: PAYG Pricing Increase
// Audience: Pay As You Go & Direct Signups
// MQTT Audience: Cloud users with MQTT feature flag enabled
const isMqttAudience = isFlagEnabled('subscriptionsUI')

// PAYG Pricing Increase Audience: Pay As You Go & Direct Signups
const isPaygAccount = account.type === 'pay_as_you_go'
const isDirectSignup = account.billingProvider === 'zuora'
const isTargetAudience = isPaygAccount && isDirectSignup
const isPriceIncreaseAudience = isPaygAccount && isDirectSignup

if (isTargetAudience) {
setCurrentAnnouncement('payg-pricing-increase-announcement')

if (announcementState['display']) {
dispatch(
showOverlay(
'click-through-announcement',
null,
handleDismissAnnouncement
)
)
}
// Sequentially display announcements in order of priority
if (
isMqttAudience &&
announcementState[AnnouncementID.MqttEol] !== AnnouncementState.Dismissed
) {
handleDisplayAnnouncement(AnnouncementID.MqttEol)
} else if (
isPriceIncreaseAudience &&
announcementState[AnnouncementID.PriceIncrease] !==
AnnouncementState.Dismissed
) {
handleDisplayAnnouncement(AnnouncementID.PriceIncrease)
}
}, [announcementState])

Expand Down
111 changes: 37 additions & 74 deletions src/me/components/ClickThroughAnnouncementOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,107 +1,70 @@
// Libraries
import React, {useEffect} from 'react'
import React, {FC, useEffect} from 'react'
import {useSelector} from 'react-redux'

// Components
import {Overlay, Button, ComponentColor} from '@influxdata/clockface'
import {SafeBlankLink} from 'src/utils/SafeBlankLink'
import {Overlay} from '@influxdata/clockface'
import {PaygPriceIncreaseAnnouncement} from 'src/me/components/announcements/PaygPriceIncreaseAnnouncement'
import {MqttEolAnnouncement} from 'src/me/components/announcements/MqttEolAnnouncement'

// Utils
import {event} from 'src/cloud/utils/reporting'
import {AnnouncementID} from 'src/homepageExperience/ClickThroughAnnouncementHandler'

// Selectors
import {selectCurrentOrg, selectUser} from 'src/identity/selectors'
import {getOverlayParams} from 'src/overlays/selectors'

interface ClickThroughAnnouncementOverlayProps {
onClose: () => void
}

export const ClickThroughAnnouncementOverlay: React.FC<
export const ClickThroughAnnouncementOverlay: FC<
ClickThroughAnnouncementOverlayProps
> = ({onClose}) => {
const {announcementID} = useSelector(getOverlayParams)

useEffect(() => {
event(`pricingClickThroughAnnouncement.displayed`)
event(`${announcementID}.displayed`)
}, [])

const org = useSelector(selectCurrentOrg)
const user = useSelector(selectUser)

const encodedSubject = encodeURI('PAYG Pricing Increase')
const encodedBody = encodeURI(`User ID: ${user.email}
Org ID: ${org.id}

Please describe your inquiry here.`)

const handlePricingAnnouncementClick = () => {
event(`pricingClickThroughAnnouncement.details.clicked`)
const handleDetailsClick = () => {
event(`${announcementID}.details.clicked`)
}

const handleContactUsClick = () => {
event(`pricingClickThroughAnnouncement.contactUs.clicked`)
event(`${announcementID}.contactUs.clicked`)
}

const handleAcknowledgeClick = () => {
event(`pricingClickThroughAnnouncement.acknowledge.clicked`)
event(`${announcementID}.acknowledge.clicked`)
onClose()
}

const announcementContents = (): JSX.Element => {
switch (announcementID) {
case AnnouncementID.PriceIncrease:
return (
<PaygPriceIncreaseAnnouncement
handleAcknowledgeClick={handleAcknowledgeClick}
handleContactUsClick={handleContactUsClick}
handleDetailsClick={handleDetailsClick}
/>
)
case AnnouncementID.MqttEol:
return (
<MqttEolAnnouncement
handleAcknowledgeClick={handleAcknowledgeClick}
handleDetailsClick={handleDetailsClick}
/>
)
default:
return null
}
}

return (
<Overlay visible={true}>
<Overlay.Container>
<Overlay.Header title="Notice: Your Plan Pricing is Changing" />
<Overlay.Body>
<p>
Starting on <strong>December 1, 2023</strong> there will be an
increase in to your usage-based pricing.
</p>
<p>
Your monthly charges will continue to be based on your actual
consumption of the four billable usage vectors: Data In, Query
Count, Storage and Data Out. This is unchanged. However, unit
pricing for two of these vectors will be increased beginning{' '}
<strong>December 1, 2023</strong>:
</p>
<ul>
<li>
Data In will increase from $0.002 to $0.0025 per MB ingested
</li>
<li>
Query Count will increase from $0.01 to $0.012 per 100 executed
</li>
</ul>
<p>
This increase to your total monthly charges will depend on the
specific distribution of your workload across the billable vectors.
Most customers will experience an increase between 14% - 24%.
</p>
<p>
Please feel free to{' '}
<SafeBlankLink
href={`mailto:[email protected]?
&subject=${encodedSubject}
&body=${encodedBody}`}
onClick={handleContactUsClick}
>
contact us
</SafeBlankLink>{' '}
with questions or refer to our website for{' '}
<SafeBlankLink
href="https://www.influxdata.com/influxdb-pricing"
onClick={handlePricingAnnouncementClick}
>
additional information
</SafeBlankLink>
.
</p>
</Overlay.Body>
<Overlay.Footer>
<Button
text="Acknowledge"
color={ComponentColor.Primary}
onClick={handleAcknowledgeClick}
/>
</Overlay.Footer>
</Overlay.Container>
<Overlay.Container>{announcementContents()}</Overlay.Container>
</Overlay>
)
}
Loading
Loading