Skip to content

Commit

Permalink
feat(ui): Enhance resource creation experience when limits are reached (
Browse files Browse the repository at this point in the history
#19103)

* feat(ui): add AssetLimitOverlay

* feat(ui): enable create bucket button

* feat(ui): enable create dashboard and task buttons

* feat(ui): add reusable AssetLimitButton

* feat(ui): change alerts limit experience

* feat(ui): update changelog

* feat(ui): address review comments
  • Loading branch information
mavarius authored Jul 30, 2020
1 parent 48814ab commit bc4c19d
Show file tree
Hide file tree
Showing 17 changed files with 374 additions and 124 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@
### Breaking

1. [19066](https://github.com/influxdata/influxdb/pull/19066): Drop deprecated /packages route tree
1. [19116](https://github.com/influxdata/influxdb/pull/19116): Support more types for template envRef default value and require explicit default values
1. [19116](https://github.com/influxdata/influxdb/pull/19116): Support more types for template envRef default value and require explicit default values

### Features

1. [19075](https://github.com/influxdata/influxdb/pull/19075): Add resource links to a stack's resources from public HTTP API list/read calls
1. [19103](https://github.com/influxdata/influxdb/pull/19103): Enhance resource creation experience when limits are reached

### Bug Fixes

1. [19043](https://github.com/influxdata/influxdb/pull/19043): Enforce all influx CLI flag args are valid


## v2.0.0-beta.15 [2020-07-23]

### Breaking

1. [19004](https://github.com/influxdata/influxdb/pull/19004): Removed the `migrate` command from the `influxd` binary.
1. [18921](https://github.com/influxdata/influxdb/pull/18921): Restricted UI variable names to not clash with Flux reserved words

Expand All @@ -41,7 +42,6 @@
1. [18989](https://github.com/influxdata/influxdb/pull/18989): Stopped fetching tags in the advanced builder
1. [19044](https://github.com/influxdata/influxdb/pull/19044): Graph customization: X and Y axis properly accept values


## v2.0.0-beta.14 [2020-07-08]

### Features
Expand Down
46 changes: 35 additions & 11 deletions ui/src/alerting/components/AlertsColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import React, {FC, ReactChild, useState} from 'react'
import {connect} from 'react-redux'

// Types
import {AppState, ResourceType} from 'src/types'
import {LimitStatus} from 'src/cloud/actions/limits'
import {AppState, ResourceType, ColumnTypes} from 'src/types'
import {LimitStatus, MonitoringLimits} from 'src/cloud/actions/limits'

// Components
import {
Expand All @@ -20,14 +20,17 @@ import {
ComponentColor,
} from '@influxdata/clockface'
import AssetLimitAlert from 'src/cloud/components/AssetLimitAlert'
import AssetLimitButton from 'src/cloud/components/AssetLimitButton'

// Utils
import {extractMonitoringLimitStatus} from 'src/cloud/utils/limits'
import {
extractChecksLimits,
extractRulesLimits,
extractEndpointsLimits,
} from 'src/cloud/utils/limits'

type ColumnTypes =
| ResourceType.NotificationRules
| ResourceType.NotificationEndpoints
| ResourceType.Checks
// Constants
import {CLOUD} from 'src/shared/constants'

interface OwnProps {
type: ColumnTypes
Expand All @@ -38,7 +41,7 @@ interface OwnProps {
}

interface StateProps {
limitStatus: LimitStatus
limitStatus: MonitoringLimits
}

const AlertsColumnHeader: FC<OwnProps & StateProps> = ({
Expand All @@ -53,6 +56,20 @@ const AlertsColumnHeader: FC<OwnProps & StateProps> = ({

const formattedTitle = title.toLowerCase().replace(' ', '-')
const panelClassName = `alerting-index--column alerting-index--${formattedTitle}`
const resourceName = title.substr(0, title.length - 1)

const isLimitExceeded =
CLOUD &&
limitStatus[type] === LimitStatus.EXCEEDED &&
type !== ResourceType.Checks

const assetLimitButton = (
<AssetLimitButton
color={ComponentColor.Secondary}
buttonText="Create"
resourceName={resourceName}
/>
)

return (
<Panel
Expand All @@ -70,7 +87,7 @@ const AlertsColumnHeader: FC<OwnProps & StateProps> = ({
tooltipContents={questionMarkTooltipContents}
/>
</FlexBox>
{createButton}
{isLimitExceeded ? assetLimitButton : createButton}
</Panel.Header>
<div className="alerting-index--search">
<Input
Expand All @@ -88,7 +105,10 @@ const AlertsColumnHeader: FC<OwnProps & StateProps> = ({
>
<div className="alerting-index--list">
{children(searchTerm)}
<AssetLimitAlert resourceName={title} limitStatus={limitStatus} />
<AssetLimitAlert
resourceName={title}
limitStatus={limitStatus[type]}
/>
</div>
</DapperScrollbars>
</div>
Expand All @@ -98,7 +118,11 @@ const AlertsColumnHeader: FC<OwnProps & StateProps> = ({

const mstp = ({cloud: {limits}}: AppState) => {
return {
limitStatus: extractMonitoringLimitStatus(limits),
limitStatus: {
[ResourceType.Checks]: extractChecksLimits(limits),
[ResourceType.NotificationRules]: extractRulesLimits(limits),
[ResourceType.NotificationEndpoints]: extractEndpointsLimits(limits),
},
}
}

Expand Down
37 changes: 12 additions & 25 deletions ui/src/buckets/components/CreateBucketButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@ import React, {FC, useEffect} from 'react'
import {connect, ConnectedProps, useDispatch} from 'react-redux'

// Components
import {
Button,
IconFont,
ComponentColor,
ComponentStatus,
} from '@influxdata/clockface'
import {Button, IconFont, ComponentColor} from '@influxdata/clockface'
import AssetLimitButton from 'src/cloud/components/AssetLimitButton'

// Actions
import {checkBucketLimits, LimitStatus} from 'src/cloud/actions/limits'
Expand All @@ -20,10 +16,12 @@ import {extractBucketLimits} from 'src/cloud/utils/limits'
// Types
import {AppState} from 'src/types'

// Constants
import {CLOUD} from 'src/shared/constants'

type ReduxProps = ConnectedProps<typeof connector>
type Props = ReduxProps

const CreateBucketButton: FC<Props> = ({
const CreateBucketButton: FC<ReduxProps> = ({
limitStatus,
onShowOverlay,
onDismissOverlay,
Expand All @@ -34,33 +32,22 @@ const CreateBucketButton: FC<Props> = ({
dispatch(checkBucketLimits())
}, [dispatch])

const limitExceeded = limitStatus === LimitStatus.EXCEEDED
const text = 'Create Bucket'
let titleText = 'Click to create a bucket'
let buttonStatus = ComponentStatus.Default

if (limitExceeded) {
titleText = 'This account has the maximum number of buckets allowed'
buttonStatus = ComponentStatus.Disabled
}

const handleItemClick = (): void => {
if (limitExceeded) {
return
}

onShowOverlay('create-bucket', null, onDismissOverlay)
}

if (CLOUD && limitStatus === LimitStatus.EXCEEDED) {
return <AssetLimitButton resourceName="Bucket" />
}

return (
<Button
icon={IconFont.Plus}
color={ComponentColor.Primary}
text={text}
titleText={titleText}
text="Create Bucket"
titleText="Click to create a bucket"
onClick={handleItemClick}
testID="Create Bucket"
status={buttonStatus}
/>
)
}
Expand Down
10 changes: 10 additions & 0 deletions ui/src/checks/components/ChecksColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import {
ResourceType,
} from 'src/types'

// Utils
import {extractChecksLimits} from 'src/cloud/utils/limits'

type ReduxProps = ConnectedProps<typeof connector>
type Props = ReduxProps & RouteComponentProps<{orgID: string}>

Expand All @@ -34,6 +37,7 @@ const ChecksColumn: FunctionComponent<Props> = ({
},
rules,
endpoints,
limitStatus,
}) => {
const handleCreateThreshold = () => {
history.push(`/orgs/${orgID}/alerting/checks/new-threshold`)
Expand Down Expand Up @@ -66,6 +70,7 @@ const ChecksColumn: FunctionComponent<Props> = ({

const createButton = (
<CreateCheckDropdown
limitStatus={limitStatus}
onCreateThreshold={handleCreateThreshold}
onCreateDeadman={handleCreateDeadman}
/>
Expand All @@ -92,6 +97,10 @@ const ChecksColumn: FunctionComponent<Props> = ({
}

const mstp = (state: AppState) => {
const {
cloud: {limits},
} = state

const checks = getAll<Check>(state, ResourceType.Checks)

const endpoints = getAll<NotificationEndpoint>(
Expand All @@ -108,6 +117,7 @@ const mstp = (state: AppState) => {
checks: sortChecksByName(checks),
rules: sortRulesByName(rules),
endpoints: sortEndpointsByName(endpoints),
limitStatus: extractChecksLimits(limits),
}
}

Expand Down
32 changes: 29 additions & 3 deletions ui/src/checks/components/CreateCheckDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,41 @@
// Libraries
import React, {FunctionComponent, MouseEvent} from 'react'
import {connect, ConnectedProps} from 'react-redux'

// Components
import {Dropdown, ComponentColor, IconFont} from '@influxdata/clockface'

// Actions
import {showOverlay, dismissOverlay} from 'src/overlays/actions/overlays'

// Types
import {CheckType} from 'src/types'
import {LimitStatus} from 'src/cloud/actions/limits'

// Constants
import {CLOUD} from 'src/shared/constants'

interface Props {
interface OwnProps {
onCreateThreshold: () => void
onCreateDeadman: () => void
limitStatus: LimitStatus
}

const CreateCheckDropdown: FunctionComponent<Props> = ({
type ReduxProps = ConnectedProps<typeof connector>

const CreateCheckDropdown: FunctionComponent<OwnProps & ReduxProps> = ({
onCreateThreshold,
onCreateDeadman,
onDismissOverlay,
onShowOverlay,
limitStatus,
}) => {
const handleItemClick = (type: CheckType): void => {
if (CLOUD && limitStatus === LimitStatus.EXCEEDED) {
onShowOverlay('asset-limit', {asset: 'Checks'}, onDismissOverlay)
return
}

if (type === 'threshold') {
onCreateThreshold()
}
Expand Down Expand Up @@ -69,4 +88,11 @@ const CreateCheckDropdown: FunctionComponent<Props> = ({
)
}

export default CreateCheckDropdown
const mdtp = {
onShowOverlay: showOverlay,
onDismissOverlay: dismissOverlay,
}

const connector = connect(null, mdtp)

export default connector(CreateCheckDropdown)
5 changes: 5 additions & 0 deletions ui/src/cloud/actions/limits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Limits,
RemoteDataState,
ResourceType,
ColumnTypes,
} from 'src/types'

// Selectors
Expand All @@ -36,6 +37,10 @@ export enum LimitStatus {
EXCEEDED = 'exceeded',
}

export type MonitoringLimits = {
[type in ColumnTypes]: LimitStatus
}

export enum ActionTypes {
SetLimits = 'SET_LIMITS',
SetLimitsStatus = 'SET_LIMITS_STATUS',
Expand Down
48 changes: 48 additions & 0 deletions ui/src/cloud/components/AssetLimitButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Libraries
import React, {FC} from 'react'
import {connect, ConnectedProps} from 'react-redux'

// Components
import {Button, ComponentColor, IconFont} from '@influxdata/clockface'

// Actions
import {showOverlay, dismissOverlay} from 'src/overlays/actions/overlays'

interface OwnProps {
color?: ComponentColor
resourceName: string
buttonText?: string
}

type ReduxProps = ConnectedProps<typeof connector>

const AssetLimitButton: FC<OwnProps & ReduxProps> = ({
color = ComponentColor.Primary,
buttonText,
resourceName,
onShowOverlay,
onDismissOverlay,
}) => {
const handleClick = () => {
onShowOverlay('asset-limit', {asset: `${resourceName}s`}, onDismissOverlay)
}
return (
<Button
icon={IconFont.Plus}
text={buttonText || `Create ${resourceName}`}
color={color}
titleText={`Click to create ${resourceName}`}
onClick={handleClick}
testID={`create-${resourceName.toLowerCase()}`}
/>
)
}

const mdtp = {
onShowOverlay: showOverlay,
onDismissOverlay: dismissOverlay,
}

const connector = connect(null, mdtp)

export default connector(AssetLimitButton)
Loading

0 comments on commit bc4c19d

Please sign in to comment.