feat(ui): redesign asset & rate limit alerts (#19032)

* feat(ui): update rate limit alert

* feat(ui): update to clockface 2.3.0

* feat(ui): update limit alert components

* feat(ui): add home page limit alert

* feat(ui): replace alert page limit alerts

* feat(ui): relace load data limit alerts

* feat(ui): replace dashboards limit alerts

* feat(ui): replace data explorer limit alerts

* feat(ui): replace tasks limit alerts

* feat(ui): replace settings limit alerts

* fix(ui): prettier

* feat(ui): update changelog

* fix(ui): update clockface to 2.3.1 and fix tests

* fix(ui): change test id
pull/19055/head
Daniel Campbell 2020-07-23 15:29:57 -07:00 committed by GitHub
parent 17391d6924
commit 4df52d0cb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 284 additions and 311 deletions

View File

@ -21,6 +21,7 @@
1. [19029](https://github.com/influxdata/influxdb/pull/19029): Navigating away from a dashboard cancels all pending queries
1. [19003](https://github.com/influxdata/influxdb/pull/19003): Upgrade to Flux v0.74.0
1. [19040](https://github.com/influxdata/influxdb/pull/19040): Drop the REPL command from influx CLI
1. [19032](https://github.com/influxdata/influxdb/pull/19032): Redesign asset & rate limit alerts
### Bug Fixes

View File

@ -802,12 +802,12 @@ describe('DataExplorer', () => {
cy.getByTestID('raw-data--toggle').click()
cy.get('.time-machine--view').within(() => {
cy.get('.cf-dapper-scrollbars--thumb-y') // TODO(zoe): replace with test ids https://github.com/influxdata/clockface/issues/507
cy.getByTestID('rawdata-table--scrollbar--thumb-y')
.trigger('mousedown', {force: true})
.trigger('mousemove', {clientY: 5000})
.trigger('mouseup')
cy.get('.cf-dapper-scrollbars--thumb-x') // TODO(zoe): replace with test ids https://github.com/influxdata/clockface/issues/507
cy.getByTestID('rawdata-table--scrollbar--thumb-x')
.trigger('mousedown', {force: true})
.trigger('mousemove', {clientX: 1000})
.trigger('mouseup')
@ -831,7 +831,7 @@ describe('DataExplorer', () => {
cy.getByTestID(`view-type--table`).click()
cy.get('.time-machine--view').within(() => {
cy.get('.cf-dapper-scrollbars--thumb-y') // TODO(zoe): replace with test ids https://github.com/influxdata/clockface/issues/507
cy.getByTestID('dapper-scrollbars--thumb-y')
.trigger('mousedown', {force: true})
.trigger('mousemove', {clientY: 5000})
.trigger('mouseup')

View File

@ -133,7 +133,7 @@
"webpack-merge": "^4.2.1"
},
"dependencies": {
"@influxdata/clockface": "2.2.0",
"@influxdata/clockface": "2.3.1",
"@influxdata/flux": "^0.5.1",
"@influxdata/flux-lsp-browser": "^0.5.11",
"@influxdata/giraffe": "0.23.0",
@ -198,4 +198,4 @@
"use-persisted-state": "^0.3.0",
"webpack-bundle-analyzer": "^3.6.0"
}
}
}

View File

@ -9,7 +9,7 @@ import EventTable from 'src/eventViewer/components/EventTable'
import AlertHistoryControls from 'src/alerting/components/AlertHistoryControls'
import AlertHistoryQueryParams from 'src/alerting/components/AlertHistoryQueryParams'
import GetResources from 'src/resources/components/GetResources'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
// Constants
import {
@ -80,7 +80,7 @@ const AlertHistoryIndex: FC<Props> = ({
title="Check Statuses"
testID="alert-history-title"
/>
<CloudUpgradeButton />
<RateLimitAlert />
</Page.Header>
<Page.ControlBar fullWidth={true}>
<AlertHistoryQueryParams

View File

@ -1,6 +1,5 @@
// Libraries
import React, {FunctionComponent, useState} from 'react'
import {connect} from 'react-redux'
import {Switch, Route} from 'react-router-dom'
//Components
@ -9,9 +8,8 @@ import ChecksColumn from 'src/checks/components/ChecksColumn'
import RulesColumn from 'src/notifications/rules/components/RulesColumn'
import EndpointsColumn from 'src/notifications/endpoints/components/EndpointsColumn'
import GetAssetLimits from 'src/cloud/components/GetAssetLimits'
import AssetLimitAlert from 'src/cloud/components/AssetLimitAlert'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
import GetResources from 'src/resources/components/GetResources'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
import NewThresholdCheckEO from 'src/checks/components/NewThresholdCheckEO'
import NewDeadmanCheckEO from 'src/checks/components/NewDeadmanCheckEO'
import EditCheckEO from 'src/checks/components/EditCheckEO'
@ -22,28 +20,15 @@ import EditEndpointOverlay from 'src/notifications/endpoints/components/EditEndp
// Utils
import {pageTitleSuffixer} from 'src/shared/utils/pageTitles'
import {
extractMonitoringLimitStatus,
extractLimitedMonitoringResources,
} from 'src/cloud/utils/limits'
// Types
import {AppState, ResourceType} from 'src/types'
import {LimitStatus} from 'src/cloud/actions/limits'
import {ResourceType} from 'src/types'
const alertsPath = '/orgs/:orgID/alerting'
interface StateProps {
limitStatus: LimitStatus
limitedResources: string
}
type ActiveColumn = 'checks' | 'endpoints' | 'rules'
const AlertingIndex: FunctionComponent<StateProps> = ({
limitStatus,
limitedResources,
}) => {
const AlertingIndex: FunctionComponent = () => {
const [activeColumn, setActiveColumn] = useState<ActiveColumn>('checks')
const pageContentsClassName = `alerting-index alerting-index__${activeColumn}`
@ -57,7 +42,7 @@ const AlertingIndex: FunctionComponent<StateProps> = ({
<Page titleTag={pageTitleSuffixer(['Alerts'])}>
<Page.Header fullWidth={true} testID="alerts-page--header">
<Page.Title title="Alerts" />
<CloudUpgradeButton />
<RateLimitAlert />
</Page.Header>
<Page.Contents
fullWidth={true}
@ -66,11 +51,6 @@ const AlertingIndex: FunctionComponent<StateProps> = ({
>
<GetResources resources={[ResourceType.Labels, ResourceType.Buckets]}>
<GetAssetLimits>
<AssetLimitAlert
resourceName={limitedResources}
limitStatus={limitStatus}
className="load-data--asset-alert"
/>
<SelectGroup
className="alerting-index--selector"
shape={ButtonShape.StretchToFit}
@ -152,11 +132,4 @@ const AlertingIndex: FunctionComponent<StateProps> = ({
)
}
const mstp = ({cloud: {limits}}: AppState) => {
return {
limitStatus: extractMonitoringLimitStatus(limits),
limitedResources: extractLimitedMonitoringResources(limits),
}
}
export default connect(mstp)(AlertingIndex)
export default AlertingIndex

View File

@ -1,8 +1,10 @@
// Libraries
import React, {FC, ReactChild, useState} from 'react'
import {connect} from 'react-redux'
// Types
import {ResourceType} from 'src/types'
import {AppState, ResourceType} from 'src/types'
import {LimitStatus} from 'src/cloud/actions/limits'
// Components
import {
@ -17,13 +19,17 @@ import {
QuestionMarkTooltip,
ComponentColor,
} from '@influxdata/clockface'
import AssetLimitAlert from 'src/cloud/components/AssetLimitAlert'
// Utils
import {extractMonitoringLimitStatus} from 'src/cloud/utils/limits'
type ColumnTypes =
| ResourceType.NotificationRules
| ResourceType.NotificationEndpoints
| ResourceType.Checks
interface Props {
interface OwnProps {
type: ColumnTypes
title: string
createButton: JSX.Element
@ -31,10 +37,15 @@ interface Props {
children: (searchTerm: string) => ReactChild
}
const AlertsColumnHeader: FC<Props> = ({
interface StateProps {
limitStatus: LimitStatus
}
const AlertsColumnHeader: FC<OwnProps & StateProps> = ({
type,
children,
title,
limitStatus,
createButton,
questionMarkTooltipContents,
}) => {
@ -75,11 +86,20 @@ const AlertsColumnHeader: FC<Props> = ({
autoHide={true}
style={{width: '100%', height: '100%'}}
>
<div className="alerting-index--list">{children(searchTerm)}</div>
<div className="alerting-index--list">
{children(searchTerm)}
<AssetLimitAlert resourceName={title} limitStatus={limitStatus} />
</div>
</DapperScrollbars>
</div>
</Panel>
)
}
export default AlertsColumnHeader
const mstp = ({cloud: {limits}}: AppState) => {
return {
limitStatus: extractMonitoringLimitStatus(limits),
}
}
export default connect(mstp)(AlertsColumnHeader)

View File

@ -102,11 +102,6 @@ class BucketsTab extends PureComponent<Props, State> {
return (
<>
<AssetLimitAlert
resourceName="buckets"
limitStatus={limitStatus}
className="load-data--asset-alert"
/>
<TabbedPageHeader
childrenLeft={leftHeaderItems}
childrenRight={rightHeaderItems}
@ -136,6 +131,11 @@ class BucketsTab extends PureComponent<Props, State> {
/>
)}
</FilterBuckets>
<AssetLimitAlert
resourceName="buckets"
limitStatus={limitStatus}
className="load-data--asset-alert"
/>
</Grid.Column>
<Grid.Column
widthXS={Columns.Twelve}

View File

@ -11,22 +11,15 @@ import BucketsTab from 'src/buckets/components/BucketsTab'
import GetResources from 'src/resources/components/GetResources'
import GetAssetLimits from 'src/cloud/components/GetAssetLimits'
import LimitChecker from 'src/cloud/components/LimitChecker'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
import LineProtocolWizard from 'src/dataLoaders/components/lineProtocolWizard/LineProtocolWizard'
import CollectorsWizard from 'src/dataLoaders/components/collectorsWizard/CollectorsWizard'
import UpdateBucketOverlay from 'src/buckets/components/UpdateBucketOverlay'
import RenameBucketOverlay from 'src/buckets/components/RenameBucketOverlay'
import CreateScraperOverlay from 'src/scrapers/components/CreateScraperOverlay'
import DeleteDataOverlay from 'src/shared/components/DeleteDataOverlay'
import {
FlexBox,
FlexDirection,
JustifyContent,
Page,
} from '@influxdata/clockface'
import {Page} from '@influxdata/clockface'
// Utils
import {extractRateLimitResources} from 'src/cloud/utils/limits'
import {pageTitleSuffixer} from 'src/shared/utils/pageTitles'
import {getOrg} from 'src/organizations/selectors'
@ -38,7 +31,6 @@ import {AppState, Organization, ResourceType} from 'src/types'
interface StateProps {
org: Organization
limitedResources: string[]
}
const bucketsPath = `/${ORGS}/${ORG_ID}/load-data/${BUCKETS}/${BUCKET_ID}`
@ -53,14 +45,6 @@ class BucketsIndex extends Component<StateProps> {
<Page titleTag={pageTitleSuffixer(['Buckets', 'Load Data'])}>
<LimitChecker>
<LoadDataHeader />
<FlexBox
direction={FlexDirection.Row}
justifyContent={JustifyContent.Center}
>
{this.isCardinalityExceeded && (
<RateLimitAlert className="load-data--rate-alert" />
)}
</FlexBox>
<LoadDataTabbedPage activeTab="buckets" orgID={org.id}>
<GetResources
resources={[
@ -102,22 +86,12 @@ class BucketsIndex extends Component<StateProps> {
</>
)
}
private get isCardinalityExceeded(): boolean {
const {limitedResources} = this.props
return limitedResources.includes('cardinality')
}
}
const mstp = (state: AppState) => {
const {
cloud: {limits},
} = state
const org = getOrg(state)
const limitedResources = extractRateLimitResources(limits)
return {org, limitedResources}
return {org}
}
export default connect<StateProps, {}, {}>(mstp, null)(BucketsIndex)

View File

@ -1,63 +1,61 @@
// Libraries
import React, {PureComponent} from 'react'
import React, {FC} from 'react'
// Components
import {
FlexBox,
FlexDirection,
AlignItems,
ComponentSize,
IconFont,
ComponentColor,
Alert,
JustifyContent,
Gradients,
InfluxColors,
GradientBox,
Panel,
Heading,
HeadingElement,
AlignItems,
} from '@influxdata/clockface'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
// Constants
import {CLOUD} from 'src/shared/constants'
// Types
import {LimitStatus} from 'src/cloud/actions/limits'
import CheckoutButton from 'src/cloud/components/CheckoutButton'
interface Props {
resourceName: string
limitStatus: LimitStatus
resourceName: string
className?: string
}
export default class AssetLimitAlert extends PureComponent<Props> {
public render() {
const {limitStatus, resourceName, className} = this.props
if (CLOUD && limitStatus === LimitStatus.EXCEEDED) {
return (
<FlexBox
direction={FlexDirection.Column}
alignItems={AlignItems.Center}
margin={ComponentSize.Large}
stretchToFitWidth={true}
className={className}
>
<Alert icon={IconFont.Cloud} color={ComponentColor.Primary}>
const AssetLimitAlert: FC<Props> = ({limitStatus, resourceName, className}) => {
if (CLOUD && limitStatus === LimitStatus.EXCEEDED) {
return (
<GradientBox
borderGradient={Gradients.MiyazakiSky}
borderColor={InfluxColors.Raven}
className={className}
>
<Panel backgroundColor={InfluxColors.Raven} className="asset-alert">
<Panel.Header>
<Heading element={HeadingElement.H4}>
Need more {resourceName}?
</Heading>
</Panel.Header>
<Panel.Body className="asset-alert--contents">
<FlexBox
alignItems={AlignItems.Center}
direction={FlexDirection.Row}
justifyContent={JustifyContent.SpaceBetween}
margin={ComponentSize.Medium}
justifyContent={JustifyContent.FlexEnd}
alignItems={AlignItems.FlexEnd}
stretchToFitHeight={true}
>
<div>
{`Hey there, looks like you have reached the maximum number of
${resourceName} you can create as part of your plan.`}
<br />
</div>
<CheckoutButton />
<CloudUpgradeButton buttonText={`Get more ${resourceName}`} />
</FlexBox>
</Alert>
</FlexBox>
)
}
return null
</Panel.Body>
</Panel>
</GradientBox>
)
}
return null
}
export default AssetLimitAlert

View File

@ -1,42 +0,0 @@
import React, {FunctionComponent} from 'react'
// Components
import {FeatureFlag} from 'src/shared/utils/featureFlag'
import {
Button,
ComponentColor,
ComponentSize,
FlexBox,
FlexDirection,
JustifyContent,
} from '@influxdata/clockface'
// Constants
import {CLOUD_CHECKOUT_PATH, CLOUD_URL} from 'src/shared/constants'
const CheckoutButton: FunctionComponent<{}> = () => {
const checkoutURL = `${CLOUD_URL}${CLOUD_CHECKOUT_PATH}`
const onClick = () => {
window.open(checkoutURL, '_self')
}
return (
<FeatureFlag name="cloudBilling">
<FlexBox
direction={FlexDirection.Row}
justifyContent={JustifyContent.SpaceAround}
margin={ComponentSize.Small}
>
<div>Want to remove these limits?</div>
<Button
color={ComponentColor.Primary}
onClick={onClick}
text="Upgrade Now"
size={ComponentSize.Small}
/>
</FlexBox>
</FeatureFlag>
)
}
export default CheckoutButton

View File

@ -1,6 +1,7 @@
// Libraries
import React, {PureComponent} from 'react'
import React, {FC} from 'react'
import {connect} from 'react-redux'
import classnames from 'classnames'
// Components
import {
@ -9,10 +10,12 @@ import {
AlignItems,
ComponentSize,
IconFont,
ComponentColor,
Alert,
JustifyContent,
Gradients,
InfluxColors,
BannerPanel,
} from '@influxdata/clockface'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
// Utils
import {
@ -26,7 +29,6 @@ import {CLOUD} from 'src/shared/constants'
// Types
import {AppState} from 'src/types'
import {LimitStatus} from 'src/cloud/actions/limits'
import CheckoutButton from 'src/cloud/components/CheckoutButton'
interface StateProps {
resources: string[]
@ -37,65 +39,58 @@ interface OwnProps {
}
type Props = StateProps & OwnProps
class RateLimitAlert extends PureComponent<Props> {
public render() {
const {status, className} = this.props
const RateLimitAlert: FC<Props> = ({status, className, resources}) => {
const rateLimitAlertClass = classnames('rate-alert', {
[`${className}`]: className,
})
if (CLOUD && status === LimitStatus.EXCEEDED) {
return (
<FlexBox
direction={FlexDirection.Column}
alignItems={AlignItems.Center}
margin={ComponentSize.Large}
stretchToFitWidth={true}
className={className}
if (
CLOUD &&
status === LimitStatus.EXCEEDED &&
resources.includes('cardinality')
) {
return (
<FlexBox
direction={FlexDirection.Column}
alignItems={AlignItems.Center}
margin={ComponentSize.Large}
className={rateLimitAlertClass}
>
<BannerPanel
size={ComponentSize.ExtraSmall}
gradient={Gradients.PolarExpress}
icon={IconFont.Cloud}
hideMobileIcon={true}
textColor={InfluxColors.Yeti}
>
<Alert icon={IconFont.Cloud} color={ComponentColor.Primary}>
<div className="rate-alert--content">
<span>
You've reached the maximum{' '}
<a
href="https://v2.docs.influxdata.com/v2.0/reference/glossary/#series-cardinality"
target="_blank"
>
series cardinality
</a>{' '}
available in your plan. Need to write more data?
</span>
<FlexBox
alignItems={AlignItems.Center}
direction={FlexDirection.Row}
justifyContent={JustifyContent.SpaceBetween}
margin={ComponentSize.Medium}
justifyContent={JustifyContent.Center}
className="rate-alert--button"
>
<div>
{this.message}
<br />
</div>
<CheckoutButton />
<CloudUpgradeButton />
</FlexBox>
</Alert>
</FlexBox>
)
}
return null
</div>
</BannerPanel>
</FlexBox>
)
}
private get message(): string {
return `Hey there, it looks like you have exceeded your plan's ${this.resourceName} limits.${this.additionalMessage}`
if (CLOUD) {
return <CloudUpgradeButton />
}
private get additionalMessage(): string {
if (this.props.resources.includes('cardinality')) {
return ' Your writes will be rejected until resolved.'
}
return ''
}
private get resourceName(): string {
const {resources} = this.props
const renamedResources = resources.map(resource => {
if (resource === 'cardinality') {
return 'total series'
}
return resource
})
return renamedResources.join(' and ')
}
return null
}
const mstp = (state: AppState) => {

View File

@ -62,7 +62,7 @@ class DashboardPage extends Component<Props> {
autoRefresh={autoRefresh}
onManualRefresh={onManualRefresh}
/>
<RateLimitAlert className="dashboard--rate-alert" />
<RateLimitAlert />
<VariablesControlBar />
<DashboardComponent manualRefresh={manualRefresh} />
</HoverTimeProvider>

View File

@ -1,19 +1,29 @@
// Libraries
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import memoizeOne from 'memoize-one'
// Components
import DashboardCard from 'src/dashboards/components/dashboard_index/DashboardCard'
import {TechnoSpinner} from '@influxdata/clockface'
import AssetLimitAlert from 'src/cloud/components/AssetLimitAlert'
// Selectors
import {getSortedResources, SortTypes} from 'src/shared/utils/sort'
// Types
import {Dashboard, RemoteDataState} from 'src/types'
import {AppState, Dashboard, RemoteDataState} from 'src/types'
import {Sort} from 'src/clockface'
import {LimitStatus} from 'src/cloud/actions/limits'
interface Props {
// Utils
import {extractDashboardLimits} from 'src/cloud/utils/limits'
interface StateProps {
limitStatus: LimitStatus
}
interface OwnProps {
dashboards: Dashboard[]
sortKey: string
sortDirection: Sort
@ -21,7 +31,7 @@ interface Props {
onFilterChange: (searchTerm: string) => void
}
export default class DashboardCards extends PureComponent<Props> {
class DashboardCards extends PureComponent<OwnProps & StateProps> {
private _observer
private _spinner
@ -110,6 +120,11 @@ export default class DashboardCards extends PureComponent<Props> {
onFilterChange={onFilterChange}
/>
))}
<AssetLimitAlert
className="dashboards--asset-alert"
resourceName="dashboards"
limitStatus={this.props.limitStatus}
/>
</div>
{windowSize * pages < dashboards.length && (
<div
@ -123,3 +138,15 @@ export default class DashboardCards extends PureComponent<Props> {
)
}
}
const mstp = (state: AppState) => {
const {
cloud: {limits},
} = state
return {
limitStatus: extractDashboardLimits(limits),
}
}
export default connect(mstp)(DashboardCards)

View File

@ -13,9 +13,8 @@ import {Page} from '@influxdata/clockface'
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
import AddResourceDropdown from 'src/shared/components/AddResourceDropdown'
import GetAssetLimits from 'src/cloud/components/GetAssetLimits'
import AssetLimitAlert from 'src/cloud/components/AssetLimitAlert'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
import ResourceSortDropdown from 'src/shared/components/resource_sort_dropdown/ResourceSortDropdown'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
import DashboardImportOverlay from 'src/dashboards/components/DashboardImportOverlay'
import CreateFromTemplateOverlay from 'src/templates/components/createFromTemplateOverlay/CreateFromTemplateOverlay'
import DashboardExportOverlay from 'src/dashboards/components/DashboardExportOverlay'
@ -53,8 +52,9 @@ class DashboardIndex extends PureComponent<Props, State> {
}
public render() {
const {createDashboard, limitStatus, sortOptions} = this.props
const {createDashboard, sortOptions} = this.props
const {searchTerm} = this.state
return (
<>
<Page
@ -63,7 +63,7 @@ class DashboardIndex extends PureComponent<Props, State> {
>
<Page.Header fullWidth={false}>
<Page.Title title="Dashboards" />
<CloudUpgradeButton />
<RateLimitAlert />
</Page.Header>
<Page.ControlBar fullWidth={false}>
<Page.ControlBarLeft>
@ -97,10 +97,6 @@ class DashboardIndex extends PureComponent<Props, State> {
scrollable={true}
>
<GetAssetLimits>
<AssetLimitAlert
resourceName="dashboards"
limitStatus={limitStatus}
/>
<DashboardsIndexContents
searchTerm={searchTerm}
onFilterChange={this.handleFilterDashboards}

View File

@ -79,15 +79,8 @@ class DashboardsIndexContents extends Component<Props> {
}
const mstp = (state: AppState) => {
const {
cloud: {
limits: {status},
},
} = state
return {
dashboards: getAll<Dashboard>(state, ResourceType.Dashboards),
limitStatus: status,
}
}

View File

@ -5,7 +5,6 @@ import {useDispatch} from 'react-redux'
// Components
import TimeMachine from 'src/timeMachine/components/TimeMachine'
import LimitChecker from 'src/cloud/components/LimitChecker'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
// Actions
import {setActiveTimeMachine} from 'src/timeMachine/actions'
@ -28,7 +27,6 @@ const DataExplorer: FC = () => {
return (
<LimitChecker>
<RateLimitAlert />
<div className="data-explorer">
<HoverTimeProvider>
<TimeMachine />

View File

@ -11,7 +11,7 @@ import ViewTypeDropdown from 'src/timeMachine/components/view_options/ViewTypeDr
import GetResources from 'src/resources/components/GetResources'
import TimeZoneDropdown from 'src/shared/components/TimeZoneDropdown'
import DeleteDataButton from 'src/dataExplorer/components/DeleteDataButton'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
import SaveAsOverlay from 'src/dataExplorer/components/SaveAsOverlay'
import DEDeleteDataOverlay from 'src/dataExplorer/components/DeleteDataOverlay'
@ -40,7 +40,7 @@ const DataExplorerPage: FC = () => {
<GetResources resources={[ResourceType.Variables]}>
<Page.Header fullWidth={true} testID="data-explorer--header">
<Page.Title title="Data Explorer" />
<CloudUpgradeButton />
<RateLimitAlert />
</Page.Header>
<Page.ControlBar fullWidth={true}>
<Page.ControlBarLeft>

View File

@ -16,7 +16,7 @@ import {
import Resources from 'src/me/components/Resources'
import Docs from 'src/me/components/Docs'
import GettingStarted from 'src/me/components/GettingStarted'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
// Utils
import {pageTitleSuffixer} from 'src/shared/utils/pageTitles'
@ -39,7 +39,7 @@ export class MePage extends PureComponent<Props> {
<Page titleTag={pageTitleSuffixer(['Home'])}>
<Page.Header fullWidth={false}>
<Page.Title title="Getting Started" testID="home-page--header" />
<CloudUpgradeButton />
<RateLimitAlert />
</Page.Header>
<Page.Contents fullWidth={false} scrollable={true}>
<Grid>

View File

@ -1,18 +1,16 @@
import React, {Component} from 'react'
import React, {FC} from 'react'
// Components
import {Page} from '@influxdata/clockface'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
class LoadDataHeader extends Component {
public render() {
return (
<Page.Header fullWidth={false} testID="load-data--header">
<Page.Title title="Load Data" />
<CloudUpgradeButton />
</Page.Header>
)
}
const LoadDataHeader: FC = () => {
return (
<Page.Header fullWidth={false} testID="load-data--header">
<Page.Title title="Load Data" />
<RateLimitAlert className="load-data--rate-alert" />
</Page.Header>
)
}
export default LoadDataHeader

View File

@ -2,14 +2,14 @@ import React, {Component} from 'react'
// Components
import {Page} from '@influxdata/clockface'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
class SettingsHeader extends Component {
public render() {
return (
<Page.Header fullWidth={false}>
<Page.Title title="Settings" testID="settings-page--header" />
<CloudUpgradeButton />
<RateLimitAlert />
</Page.Header>
)
}

View File

@ -2,8 +2,15 @@
import React, {FC} from 'react'
import {connect} from 'react-redux'
import {get, find} from 'lodash'
import classnames from 'classnames'
// Components
import {
LinkButton,
ComponentColor,
ComponentSize,
ButtonShape,
} from '@influxdata/clockface'
import CloudOnly from 'src/shared/components/cloud/CloudOnly'
// Constants
@ -20,17 +27,32 @@ interface StateProps {
inView: boolean
}
const CloudUpgradeButton: FC<StateProps> = ({inView}) => {
interface OwnProps {
className?: string
buttonText?: string
}
const CloudUpgradeButton: FC<StateProps & OwnProps> = ({
inView,
className,
buttonText = 'Upgrade Now',
}) => {
const cloudUpgradeButtonClass = classnames('upgrade-payg--button', {
[`${className}`]: className,
})
return (
<CloudOnly>
{inView && (
<a
className="cf-button cf-button-sm cf-button-success upgrade-payg--button"
<LinkButton
className={cloudUpgradeButtonClass}
color={ComponentColor.Success}
size={ComponentSize.Small}
shape={ButtonShape.Default}
href={`${CLOUD_URL}${CLOUD_CHECKOUT_PATH}`}
target="_self"
>
Upgrade Now
</a>
text={buttonText}
/>
)}
</CloudOnly>
)

View File

@ -1,20 +1,67 @@
.dashboard--rate-alert {
padding: 0 $page-gutter;
width: 100%;
padding-bottom: 16px;
}
.load-data--rate-alert {
padding: 0 $page-gutter;
padding-bottom: 16px;
max-width: 1608px;
}
.load-data--asset-alert {
padding-bottom: 16px;
margin-bottom: $cf-marg-d;
}
// Might need to remove this eventually
.cf-page-header--fixed {
justify-content: space-between;
.cf-page-control-bar {
+ .rate-alert {
margin: 0 $cf-marg-c $cf-marg-c;
}
}
.rate-alert--content {
display: inline-flex;
flex-direction: column;
font-weight: 500;
.rate-alert--button {
margin-top: $cf-marg-b;
}
}
.cf-page--title {
flex-shrink: 0;
}
.asset-alert {
height: 100%;
background-position: bottom -20px left -20px;
background-size: contain;
background-repeat: no-repeat;
background-image: url('../../assets/images/dashboard-empty--dark.svg');
}
.dashboards--asset-alert {
.asset-alert--contents {
position: absolute;
bottom: 0;
}
}
a.upgrade-payg--button {
@include gradient-diag-up($c-pool, $c-rainforest);
}
@media screen and (min-width: $cf-nav-menu--breakpoint) {
.rate-alert {
margin-left: $cf-marg-d;
}
.rate-alert--content {
flex-direction: row;
width: 100%;
height: 100%;
align-items: center;
justify-content: space-between;
.rate-alert--button {
margin-top: 0;
margin-left: $cf-marg-c;
}
}
.cf-page-control-bar {
+ .rate-alert {
margin: 0 $cf-marg-d $cf-marg-c;
}
}
}

View File

@ -9,7 +9,6 @@ $nav-size: 50px;
$nav-breakpoint: 800px;
$page-header-size: 66px;
$page-max-width: 1608px;
$page-gutter: 54px;
$page-title-size: 21px;
$page-title-weight: 400;
$sidebar--width: 50px; //delete this later

View File

@ -15,7 +15,7 @@ import {
import AddResourceDropdown from 'src/shared/components/AddResourceDropdown'
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
import ResourceSortDropdown from 'src/shared/components/resource_sort_dropdown/ResourceSortDropdown'
import CloudUpgradeButton from 'src/shared/components/CloudUpgradeButton'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
// Types
import {LimitStatus} from 'src/cloud/actions/limits'
@ -63,7 +63,7 @@ export default class TasksHeader extends PureComponent<Props> {
<>
<Page.Header fullWidth={false} testID="tasks-page--header">
<Page.Title title="Tasks" />
<CloudUpgradeButton />
<RateLimitAlert />
</Page.Header>
<Page.ControlBar fullWidth={false}>
<Page.ControlBarLeft>

View File

@ -113,10 +113,6 @@ class TasksPage extends PureComponent<Props, State> {
<Page.Contents fullWidth={false} scrollable={true}>
<GetResources resources={[ResourceType.Tasks, ResourceType.Labels]}>
<GetAssetLimits>
<AssetLimitAlert
resourceName="tasks"
limitStatus={limitStatus}
/>
<Filter
list={this.filteredTasks}
searchTerm={searchTerm}
@ -147,6 +143,10 @@ class TasksPage extends PureComponent<Props, State> {
)}
</Filter>
{this.hiddenTaskAlert}
<AssetLimitAlert
resourceName="tasks"
limitStatus={limitStatus}
/>
</GetAssetLimits>
</GetResources>
</Page.Contents>

View File

@ -10,15 +10,9 @@ import LoadDataHeader from 'src/settings/components/LoadDataHeader'
import Collectors from 'src/telegrafs/components/Collectors'
import GetResources from 'src/resources/components/GetResources'
import LimitChecker from 'src/cloud/components/LimitChecker'
import RateLimitAlert from 'src/cloud/components/RateLimitAlert'
import TelegrafInstructionsOverlay from 'src/telegrafs/components/TelegrafInstructionsOverlay'
import CollectorsWizard from 'src/dataLoaders/components/collectorsWizard/CollectorsWizard'
import {
FlexBox,
FlexDirection,
JustifyContent,
Page,
} from '@influxdata/clockface'
import {Page} from '@influxdata/clockface'
import OverlayHandler, {
RouteOverlay,
} from 'src/overlays/components/RouteOverlay'
@ -39,7 +33,6 @@ const TelegrafOutputOverlay = RouteOverlay(
)
// Utils
import {extractRateLimitResources} from 'src/cloud/utils/limits'
import {pageTitleSuffixer} from 'src/shared/utils/pageTitles'
import {getOrg} from 'src/organizations/selectors'
@ -51,7 +44,6 @@ import {ORGS, ORG_ID, TELEGRAFS} from 'src/shared/constants/routes'
interface StateProps {
org: Organization
limitedResources: string[]
}
const telegrafsPath = `/${ORGS}/${ORG_ID}/load-data/${TELEGRAFS}`
@ -66,14 +58,6 @@ class TelegrafsPage extends PureComponent<StateProps> {
<Page titleTag={pageTitleSuffixer(['Telegraf', 'Load Data'])}>
<LimitChecker>
<LoadDataHeader />
<FlexBox
direction={FlexDirection.Row}
justifyContent={JustifyContent.Center}
>
{this.isCardinalityExceeded && (
<RateLimitAlert className="load-data--rate-alert" />
)}
</FlexBox>
<LoadDataTabbedPage activeTab="telegrafs" orgID={org.id}>
<GetResources
resources={[ResourceType.Buckets, ResourceType.Telegrafs]}
@ -101,21 +85,11 @@ class TelegrafsPage extends PureComponent<StateProps> {
</>
)
}
private get isCardinalityExceeded(): boolean {
const {limitedResources} = this.props
return limitedResources.includes('cardinality')
}
}
const mstp = (state: AppState) => {
const org = getOrg(state)
const {
cloud: {limits},
} = state
const limitedResources = extractRateLimitResources(limits)
return {org, limitedResources}
return {org}
}
export default connect<StateProps>(mstp)(TelegrafsPage)

View File

@ -747,10 +747,10 @@
debug "^3.1.0"
lodash.once "^4.1.1"
"@influxdata/clockface@2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@influxdata/clockface/-/clockface-2.2.0.tgz#73f09f4832d6b6bad53af029844a11dd6562527e"
integrity sha512-pIQPJXjvVgzcryhAjgZPSoC5BRLbQb1sIIY9l6KQCg4DWJkxqFC/sPI7qJItRXd8kiPXbfbHvXGAwqIY+TdWNQ==
"@influxdata/clockface@2.3.1":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@influxdata/clockface/-/clockface-2.3.1.tgz#562a218e62b50ba16cd4a4e1e88b2e335289c595"
integrity sha512-NqPaCT/vUOCEnjAekfECAvUS3OiSwHREwG/5YuawCw5EoswcUc9h6sMSo2spPxXQuiVAB4RcsxeX3+hqP6pU7w==
"@influxdata/flux-lsp-browser@^0.5.11":
version "0.5.11"