Skip to content

Commit

Permalink
feat(ui): add mqtt eol overlay and alert banner
Browse files Browse the repository at this point in the history
  • Loading branch information
mavarius committed Nov 1, 2023
1 parent 5ca2e71 commit 3bcafec
Show file tree
Hide file tree
Showing 8 changed files with 389 additions and 106 deletions.
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
80 changes: 50 additions & 30 deletions src/homepageExperience/ClickThroughAnnouncementHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,75 @@ 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 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]: 'display',
}))
}
}

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

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

if (announcementState[announcementID] === '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 mqttAnnouncementID = 'mqttEolClickThroughAnnouncement'
const isMqttAudience = isFlagEnabled('subscriptionsUI')

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

if (isTargetAudience) {
setCurrentAnnouncement('payg-pricing-increase-announcement')
const isPriceIncreaseAudience = isPaygAccount && isDirectSignup

if (announcementState['display']) {
dispatch(
showOverlay(
'click-through-announcement',
null,
handleDismissAnnouncement
)
)
}
// Sequentially display announcements in order of priority
if (
isMqttAudience &&
announcementState[mqttAnnouncementID] !== 'dismissed'
) {
handleDisplayAnnouncement(mqttAnnouncementID)
} else if (
isPriceIncreaseAudience &&
announcementState[priceIncreaseAnnouncementID] !== 'dismissed'
) {
handleDisplayAnnouncement(priceIncreaseAnnouncementID)
}
}, [announcementState])

Expand Down
110 changes: 36 additions & 74 deletions src/me/components/ClickThroughAnnouncementOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,107 +1,69 @@
// 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'

// 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 'pricingClickThroughAnnouncement':
return (
<PaygPriceIncreaseAnnouncement
handleAcknowledgeClick={handleAcknowledgeClick}
handleContactUsClick={handleContactUsClick}
handleDetailsClick={handleDetailsClick}
/>
)
case 'mqttEolClickThroughAnnouncement':
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

0 comments on commit 3bcafec

Please sign in to comment.