Skip to content

Commit

Permalink
chore: convert index list to resource list
Browse files Browse the repository at this point in the history
  • Loading branch information
Rose Parker authored and Rose Parker committed Jun 4, 2020
1 parent 07e351b commit c81c053
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 74 deletions.
37 changes: 7 additions & 30 deletions ui/src/authorizations/components/TokenList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import _ from 'lodash'
import memoizeOne from 'memoize-one'

// Components
import {Overlay, IndexList} from '@influxdata/clockface'
import {Overlay, ResourceList} from '@influxdata/clockface'
import TokenRow from 'src/authorizations/components/TokenRow'
import ViewTokenOverlay from 'src/authorizations/components/ViewTokenOverlay'

Expand All @@ -15,12 +15,12 @@ import {Sort} from '@influxdata/clockface'

// Utils
import {getSortedResources} from 'src/shared/utils/sort'
import TokensEmptyState from './TokensEmptyState'

type SortKey = keyof Authorization

interface Props {
auths: Authorization[]
emptyState: JSX.Element
searchTerm: string
sortKey: string
sortDirection: Sort
Expand All @@ -47,35 +47,16 @@ export default class TokenList extends PureComponent<Props, State> {
}

public render() {
const {sortKey, sortDirection, onClickColumn, searchTerm} = this.props
const {isTokenOverlayVisible, authInView} = this.state

return (
<>
<IndexList>
<IndexList.Header>
<IndexList.HeaderCell
sortKey={this.headerKeys[0]}
sort={sortKey === this.headerKeys[0] ? sortDirection : Sort.None}
columnName="Description"
onClick={onClickColumn}
width="50%"
/>
<IndexList.HeaderCell
sortKey={this.headerKeys[1]}
sort={sortKey === this.headerKeys[1] ? sortDirection : Sort.None}
columnName="Status"
onClick={onClickColumn}
width="50%"
/>
</IndexList.Header>
<IndexList.Body
emptyState={<TokensEmptyState searchTerm={searchTerm} />}
columnCount={2}
>
<ResourceList>
<ResourceList.Body emptyState={this.props.emptyState}>
{this.rows}
</IndexList.Body>
</IndexList>
</ResourceList.Body>
</ResourceList>

<Overlay visible={isTokenOverlayVisible}>
<ViewTokenOverlay
auth={authInView}
Expand All @@ -86,10 +67,6 @@ export default class TokenList extends PureComponent<Props, State> {
)
}

private get headerKeys(): SortKey[] {
return ['description', 'status']
}

private get rows(): JSX.Element[] {
const {auths, sortDirection, sortKey, sortType} = this.props
const sortedAuths = this.memGetSortedResources(
Expand Down
73 changes: 37 additions & 36 deletions ui/src/authorizations/components/TokenRow.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Libraries
import React, {PureComponent, MouseEvent} from 'react'
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'

// Actions
Expand All @@ -11,14 +11,15 @@ import {
// Components
import {
ComponentSize,
FlexBox,
InputLabel,
SlideToggle,
ComponentColor,
IndexList,
Alignment,
ConfirmationButton,
Appearance,
ResourceCard,
IconFont,
} from '@influxdata/clockface'
import EditableName from 'src/shared/components/EditableName'

import {Context} from 'src/clockface'

// Types
import {Authorization} from 'src/types'
Expand All @@ -39,40 +40,43 @@ type Props = DispatchProps & OwnProps
class TokenRow extends PureComponent<Props> {
public render() {
const {description} = this.props.auth

const {auth} = this.props
const labelText = this.isTokenEnabled ? 'Active' : 'Inactive'
return (
<IndexList.Row brighten={true}>
<IndexList.Cell>
<EditableName
name={description}
onUpdate={this.handleUpdateName}
noNameString={DEFAULT_TOKEN_DESCRIPTION}
onEditName={this.handleClickDescription}
/>
</IndexList.Cell>
<IndexList.Cell>
<ResourceCard contextMenu={this.contextMenu}>
<ResourceCard.EditableName
onUpdate={this.handleUpdateName}
onClick={this.handleClickDescription}
name={description}
noNameString={DEFAULT_TOKEN_DESCRIPTION}
/>
<ResourceCard.Meta>
{[<>Created at: {auth.createdAt}</>]}
</ResourceCard.Meta>
<FlexBox margin={ComponentSize.Small}>
<SlideToggle
active={this.isTokenEnabled}
size={ComponentSize.ExtraSmall}
onChange={this.changeToggle}
color={ComponentColor.Success}
testID="check-card--slide-toggle"
/>
</IndexList.Cell>
<IndexList.Cell alignment={Alignment.Right} revealOnHover={true}>
<ConfirmationButton
<InputLabel active={this.isTokenEnabled}>{labelText}</InputLabel>
</FlexBox>
</ResourceCard>
)
}

private get contextMenu(): JSX.Element {
return (
<Context>
<Context.Menu icon={IconFont.Trash} color={ComponentColor.Danger}>
<Context.Item
label="Delete"
action={this.handleDelete}
testID="delete-token"
size={ComponentSize.ExtraSmall}
text="Delete"
confirmationLabel="Really delete this token?"
confirmationButtonText="Confirm"
confirmationButtonColor={ComponentColor.Danger}
popoverAppearance={Appearance.Outline}
popoverColor={ComponentColor.Danger}
color={ComponentColor.Danger}
onConfirm={this.handleDelete}
/>
</IndexList.Cell>
</IndexList.Row>
</Context.Menu>
</Context>
)
}

Expand All @@ -96,11 +100,8 @@ class TokenRow extends PureComponent<Props> {
this.props.onDelete(id, description)
}

private handleClickDescription = (e: MouseEvent<HTMLAnchorElement>) => {
private handleClickDescription = () => {
const {onClickDescription, auth} = this.props

e.preventDefault()

onClickDescription(auth.id)
}

Expand Down
63 changes: 55 additions & 8 deletions ui/src/authorizations/components/TokensTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import {withRouter, WithRouterProps} from 'react-router'
import {isEmpty} from 'lodash'

// Components
import {Sort} from '@influxdata/clockface'
import {Sort, ComponentSize, EmptyState} from '@influxdata/clockface'
import SearchWidget from 'src/shared/components/search_widget/SearchWidget'
import TokenList from 'src/authorizations/components/TokenList'
import FilterList from 'src/shared/components/FilterList'
import TabbedPageHeader from 'src/shared/components/tabbed_page/TabbedPageHeader'
import GenerateTokenDropdown from 'src/authorizations/components/GenerateTokenDropdown'
import ResourceSortDropdown from 'src/shared/components/resource_sort_dropdown/ResourceSortDropdown'

// Types
import {AppState, Authorization, ResourceType} from 'src/types'
Expand All @@ -21,6 +23,7 @@ import {getAll} from 'src/resources/selectors'
enum AuthSearchKeys {
Description = 'description',
Status = 'status',
CreatedAt = 'createdAt',
}

interface State {
Expand Down Expand Up @@ -56,12 +59,22 @@ class TokensTab extends PureComponent<Props, State> {
const {tokens} = this.props

const leftHeaderItems = (
<SearchWidget
searchTerm={searchTerm}
placeholderText="Filter Tokens..."
onSearch={this.handleChangeSearchTerm}
testID="input-field--filter"
/>
<>
<SearchWidget
searchTerm={searchTerm}
placeholderText="Filter Tokens..."
onSearch={this.handleChangeSearchTerm}
testID="input-field--filter"
/>
<ResourceSortDropdown
resourceType={ResourceType.Authorizations}
sortDirection={sortDirection}
sortKey={sortKey}
sortType={sortType}
onSelect={this.handleSort}
width={238}
/>
</>
)

const rightHeaderItems = <GenerateTokenDropdown />
Expand All @@ -80,6 +93,7 @@ class TokensTab extends PureComponent<Props, State> {
{filteredAuths => (
<TokenList
auths={filteredAuths}
emptyState={this.emptyState}
searchTerm={searchTerm}
sortKey={sortKey}
sortDirection={sortDirection}
Expand All @@ -92,6 +106,14 @@ class TokensTab extends PureComponent<Props, State> {
)
}

private handleSort = (
sortKey: SortKey,
sortDirection: Sort,
sortType: SortTypes
): void => {
this.setState({sortKey, sortDirection, sortType})
}

private handleClickColumn = (nextSort: Sort, sortKey: SortKey) => {
const sortType = SortTypes.String
this.setState({sortKey, sortDirection: nextSort, sortType})
Expand All @@ -102,7 +124,32 @@ class TokensTab extends PureComponent<Props, State> {
}

private get searchKeys(): AuthSearchKeys[] {
return [AuthSearchKeys.Status, AuthSearchKeys.Description]
return [
AuthSearchKeys.Status,
AuthSearchKeys.Description,
AuthSearchKeys.CreatedAt,
]
}

private get emptyState(): JSX.Element {
const {searchTerm} = this.state

if (isEmpty(searchTerm)) {
return (
<EmptyState size={ComponentSize.Large}>
<EmptyState.Text>
Looks like there aren't any <b>Tokens</b>, why not generate one?
</EmptyState.Text>
<GenerateTokenDropdown />
</EmptyState>
)
}

return (
<EmptyState size={ComponentSize.Large}>
<EmptyState.Text>No Tokens match your query</EmptyState.Text>
</EmptyState>
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Bucket,
Telegraf,
Scraper,
Authorization,
} from 'src/types'

export type DashboardSortKey = keyof Dashboard | 'meta.updatedAt'
Expand All @@ -20,6 +21,7 @@ export type TemplateSortKey = keyof Template | 'meta.name' | 'meta.description'
export type BucketSortKey = keyof Bucket | 'retentionRules[0].everySeconds'
export type TelegrafSortKey = keyof Telegraf
export type ScraperSortKey = keyof Scraper
export type AuthorizationSortKey = keyof Authorization

export type SortKey =
| DashboardSortKey
Expand All @@ -30,6 +32,7 @@ export type SortKey =
| BucketSortKey
| TelegrafSortKey
| ScraperSortKey
| AuthorizationSortKey

export interface SortDropdownItem {
label: string
Expand Down Expand Up @@ -294,5 +297,44 @@ export const generateSortItems = (
sortDirection: Sort.Descending,
},
]
case ResourceType.Authorizations:
return [
{
label: 'Description (A → Z)',
sortKey: 'description',
sortType: SortTypes.String,
sortDirection: Sort.Ascending,
},
{
label: 'Description (Z → A)',
sortKey: 'description',
sortType: SortTypes.String,
sortDirection: Sort.Descending,
},
{
label: 'Status (Active)',
sortKey: 'status',
sortType: SortTypes.String,
sortDirection: Sort.Ascending,
},
{
label: 'Status (Inactive)',
sortKey: 'status',
sortType: SortTypes.String,
sortDirection: Sort.Descending,
},
{
label: 'Date Created (Oldest)',
sortKey: 'createdAt',
sortType: SortTypes.String,
sortDirection: Sort.Ascending,
},
{
label: 'Date Created (Newest)',
sortKey: 'createdAt',
sortType: SortTypes.String,
sortDirection: Sort.Descending,
},
]
}
}

0 comments on commit c81c053

Please sign in to comment.