feat: tokens empty state (#18060)
* feat(tokens): add TokensEmptyState component * feat: token empty statepull/18095/head
parent
8903c939fe
commit
828302c430
|
|
@ -219,13 +219,52 @@ describe('tokens', () => {
|
|||
cy.getByTestID('table-row')
|
||||
.contains('token test 03')
|
||||
.should('not.exist')
|
||||
|
||||
// Delete remaining tokens
|
||||
cy.getByTestID('table-row')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.getByTestID('delete-token--button').click()
|
||||
})
|
||||
.then(() => {
|
||||
cy.getByTestID('delete-token--popover--contents').within(() => {
|
||||
cy.getByTestID('delete-token--confirm-button').click()
|
||||
})
|
||||
})
|
||||
|
||||
cy.getByTestID('table-row')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.getByTestID('delete-token--button').click()
|
||||
})
|
||||
.then(() => {
|
||||
cy.getByTestID('delete-token--popover--contents').within(() => {
|
||||
cy.getByTestID('delete-token--confirm-button').click()
|
||||
})
|
||||
})
|
||||
|
||||
cy.getByTestID('table-row')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.getByTestID('delete-token--button').click()
|
||||
})
|
||||
.then(() => {
|
||||
cy.getByTestID('delete-token--popover--contents').within(() => {
|
||||
cy.getByTestID('delete-token--confirm-button').click()
|
||||
})
|
||||
})
|
||||
|
||||
// Assert empty state
|
||||
cy.getByTestID('empty-state').within(() => {
|
||||
cy.getByTestID('dropdown--gen-token').should('exist')
|
||||
})
|
||||
})
|
||||
|
||||
it('can generate a read/write token', () => {
|
||||
cy.getByTestID('table-row').should('have.length', 4)
|
||||
|
||||
// create some extra buckets for filters
|
||||
cy.get<Organization>('@org').then(({id, name}) => {
|
||||
cy.get<Organization>('@org').then(({id, name}: Organization) => {
|
||||
cy.createBucket(id, name, 'Magna Carta').then(() => {
|
||||
cy.createBucket(id, name, 'Sicilsky Bull').then(() => {
|
||||
cy.createBucket(id, name, 'A la Carta')
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
import _ from 'lodash'
|
||||
import {withRouter, WithRouterProps} from 'react-router'
|
||||
|
||||
// Components
|
||||
import {Dropdown} from '@influxdata/clockface'
|
||||
|
|
@ -8,14 +8,9 @@ import {Dropdown} from '@influxdata/clockface'
|
|||
// Types
|
||||
import {IconFont, ComponentColor} from '@influxdata/clockface'
|
||||
|
||||
interface OwnProps {
|
||||
onSelectAllAccess: () => void
|
||||
onSelectReadWrite: () => void
|
||||
}
|
||||
type Props = WithRouterProps
|
||||
|
||||
type Props = OwnProps
|
||||
|
||||
export default class GenerateTokenDropdown extends PureComponent<Props> {
|
||||
class GenerateTokenDropdown extends PureComponent<Props> {
|
||||
public render() {
|
||||
return (
|
||||
<Dropdown
|
||||
|
|
@ -74,9 +69,29 @@ export default class GenerateTokenDropdown extends PureComponent<Props> {
|
|||
|
||||
private handleSelect = (selection: string): void => {
|
||||
if (selection === this.allAccessOption) {
|
||||
this.props.onSelectAllAccess()
|
||||
this.handleAllAccess()
|
||||
} else if (selection === this.bucketReadWriteOption) {
|
||||
this.props.onSelectReadWrite()
|
||||
this.handleReadWrite()
|
||||
}
|
||||
}
|
||||
|
||||
private handleAllAccess = () => {
|
||||
const {
|
||||
router,
|
||||
params: {orgID},
|
||||
} = this.props
|
||||
|
||||
router.push(`/orgs/${orgID}/load-data/tokens/generate/all-access`)
|
||||
}
|
||||
|
||||
private handleReadWrite = () => {
|
||||
const {
|
||||
router,
|
||||
params: {orgID},
|
||||
} = this.props
|
||||
|
||||
router.push(`/orgs/${orgID}/load-data/tokens/generate/buckets`)
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter<{}>(GenerateTokenDropdown)
|
||||
|
|
|
|||
|
|
@ -4,17 +4,18 @@ import _ from 'lodash'
|
|||
import memoizeOne from 'memoize-one'
|
||||
|
||||
// Components
|
||||
import {EmptyState, Overlay, IndexList} from '@influxdata/clockface'
|
||||
import {Overlay, IndexList} from '@influxdata/clockface'
|
||||
import TokenRow from 'src/authorizations/components/TokenRow'
|
||||
import ViewTokenOverlay from 'src/authorizations/components/ViewTokenOverlay'
|
||||
|
||||
// Types
|
||||
import {Authorization} from 'src/types'
|
||||
import {SortTypes} from 'src/shared/utils/sort'
|
||||
import {ComponentSize, Sort} from '@influxdata/clockface'
|
||||
import {Sort} from '@influxdata/clockface'
|
||||
|
||||
// Utils
|
||||
import {getSortedResources} from 'src/shared/utils/sort'
|
||||
import TokensEmptyState from './TokensEmptyState'
|
||||
|
||||
type SortKey = keyof Authorization
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ export default class TokenList extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const {sortKey, sortDirection, onClickColumn} = this.props
|
||||
const {sortKey, sortDirection, onClickColumn, searchTerm} = this.props
|
||||
const {isTokenOverlayVisible, authInView} = this.state
|
||||
|
||||
return (
|
||||
|
|
@ -68,7 +69,10 @@ export default class TokenList extends PureComponent<Props, State> {
|
|||
width="50%"
|
||||
/>
|
||||
</IndexList.Header>
|
||||
<IndexList.Body emptyState={this.emptyState} columnCount={2}>
|
||||
<IndexList.Body
|
||||
emptyState={<TokensEmptyState searchTerm={searchTerm} />}
|
||||
columnCount={2}
|
||||
>
|
||||
{this.rows}
|
||||
</IndexList.Body>
|
||||
</IndexList>
|
||||
|
|
@ -112,20 +116,4 @@ export default class TokenList extends PureComponent<Props, State> {
|
|||
const authInView = this.props.auths.find(a => a.id === authID)
|
||||
this.setState({isTokenOverlayVisible: true, authInView})
|
||||
}
|
||||
|
||||
private get emptyState(): JSX.Element {
|
||||
const {searchTerm} = this.props
|
||||
let emptyStateText =
|
||||
'There are not any Tokens associated with this account. Contact your administrator'
|
||||
|
||||
if (searchTerm) {
|
||||
emptyStateText = 'No Tokens match your search term'
|
||||
}
|
||||
|
||||
return (
|
||||
<EmptyState size={ComponentSize.Large}>
|
||||
<EmptyState.Text>{emptyStateText}</EmptyState.Text>
|
||||
</EmptyState>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
// Libraries
|
||||
import React, {FC} from 'react'
|
||||
import {EmptyState, ComponentSize} from '@influxdata/clockface'
|
||||
import GenerateTokenDropdown from './GenerateTokenDropdown'
|
||||
|
||||
interface Props {
|
||||
searchTerm: string
|
||||
}
|
||||
|
||||
const TokensEmptyState: FC<Props> = ({searchTerm}) => {
|
||||
if (searchTerm) {
|
||||
return (
|
||||
<EmptyState size={ComponentSize.Large}>
|
||||
<EmptyState.Text>No Tokens match your search</EmptyState.Text>
|
||||
</EmptyState>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<EmptyState size={ComponentSize.Large}>
|
||||
<EmptyState.Text>
|
||||
Looks like you don't have any <b>Tokens</b>, why not add one?
|
||||
</EmptyState.Text>
|
||||
<GenerateTokenDropdown />
|
||||
</EmptyState>
|
||||
)
|
||||
}
|
||||
|
||||
export default TokensEmptyState
|
||||
|
|
@ -64,12 +64,7 @@ class TokensTab extends PureComponent<Props, State> {
|
|||
/>
|
||||
)
|
||||
|
||||
const rightHeaderItems = (
|
||||
<GenerateTokenDropdown
|
||||
onSelectAllAccess={this.handleGenerateAllAccess}
|
||||
onSelectReadWrite={this.handleGenerateReadWrite}
|
||||
/>
|
||||
)
|
||||
const rightHeaderItems = <GenerateTokenDropdown />
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -109,24 +104,6 @@ class TokensTab extends PureComponent<Props, State> {
|
|||
private get searchKeys(): AuthSearchKeys[] {
|
||||
return [AuthSearchKeys.Status, AuthSearchKeys.Description]
|
||||
}
|
||||
|
||||
private handleGenerateAllAccess = () => {
|
||||
const {
|
||||
router,
|
||||
params: {orgID},
|
||||
} = this.props
|
||||
|
||||
router.push(`/orgs/${orgID}/load-data/tokens/generate/all-access`)
|
||||
}
|
||||
|
||||
private handleGenerateReadWrite = () => {
|
||||
const {
|
||||
router,
|
||||
params: {orgID},
|
||||
} = this.props
|
||||
|
||||
router.push(`/orgs/${orgID}/load-data/tokens/generate/buckets`)
|
||||
}
|
||||
}
|
||||
|
||||
const mstp = (state: AppState) => ({
|
||||
|
|
|
|||
Loading…
Reference in New Issue