diff --git a/CHANGELOG.md b/CHANGELOG.md index 1167048791..6e457323dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## v2.0.0-beta.9 +## v2.0.0-beta.9 [unreleased] ### Features @@ -7,6 +7,7 @@ ### UI Improvements 1. [17714](https://github.com/influxdata/influxdb/pull/17714): Cloud environments no longer render markdown images, for security reasons. +1. [17321](https://github.com/influxdata/influxdb/pull/17321): Improve UI for sorting resources ## v2.0.0-beta.8 [2020-04-10] diff --git a/ui/cypress/e2e/buckets.test.ts b/ui/cypress/e2e/buckets.test.ts index b41f9383b5..ea50bd14c0 100644 --- a/ui/cypress/e2e/buckets.test.ts +++ b/ui/cypress/e2e/buckets.test.ts @@ -75,8 +75,11 @@ describe('Buckets', () => { describe('Searching and Sorting', () => { it('can sort by name and retention', () => { const buckets = ['defbuck', '_tasks', '_monitoring'] - cy.getByTestID('name-sorter') + cy.getByTestID('resource-sorter--button') .click() + .then(() => { + cy.getByTestID('resource-sorter--name-desc').click() + }) .then(() => { cy.get('[data-testid*="bucket-card"]').each((val, index) => { const testID = val.attr('data-testid') @@ -84,8 +87,13 @@ describe('Buckets', () => { }) }) - cy.getByTestID('name-sorter') + cy.getByTestID('resource-sorter--button') .click() + .then(() => { + cy.getByTestID( + 'resource-sorter--retentionRules[0].everySeconds-desc' + ).click() + }) .then(() => { const asc_buckets = buckets.slice().sort() cy.get('[data-testid*="bucket-card"]').each((val, index) => { diff --git a/ui/cypress/e2e/collectors.test.ts b/ui/cypress/e2e/collectors.test.ts index e58ce04db2..c0d0ab85dd 100644 --- a/ui/cypress/e2e/collectors.test.ts +++ b/ui/cypress/e2e/collectors.test.ts @@ -225,8 +225,11 @@ describe('Collectors', () => { }) }) - cy.getByTestID('name-sorter') + cy.getByTestID('resource-sorter--button') .click() + .then(() => { + cy.getByTestID('resource-sorter--name-desc').click() + }) .then(() => { // NOTE: this then is just here to let me scope this variable (alex) const teletubbies = telegrafs diff --git a/ui/cypress/e2e/labels.test.ts b/ui/cypress/e2e/labels.test.ts index d92a249fbb..ef3ac5b69b 100644 --- a/ui/cypress/e2e/labels.test.ts +++ b/ui/cypress/e2e/labels.test.ts @@ -284,7 +284,11 @@ describe('labels', () => { } }) - cy.getByTestID('sorter--name').click() + cy.getByTestID('resource-sorter--button') + .click() + .then(() => { + cy.getByTestID('resource-sorter--name-desc').click() + }) // check sort desc cy.getByTestIDSubStr('label--pill').then(labels => { @@ -296,7 +300,11 @@ describe('labels', () => { }) // reset to asc - cy.getByTestID('sorter--name').click() + cy.getByTestID('resource-sorter--button') + .click() + .then(() => { + cy.getByTestID('resource-sorter--name-asc').click() + }) cy.getByTestIDSubStr('label--pill').then(labels => { for (let i = 0; i < labels.length; i++) { @@ -332,27 +340,32 @@ describe('labels', () => { a.description < b.description ? -1 : a.description > b.description ? 1 : 0 ) // check sort asc - cy.getByTestID('sorter--desc').click() + cy.getByTestID('resource-sorter--button') + .click() + .then(() => { + cy.getByTestID('resource-sorter--properties.description-asc').click() + }) - cy.getByTestIDSubStr('resource-card').then(labels => { + cy.getByTestID('label-card').then(labels => { for (let i = 0; i < labels.length; i++) { - cy.getByTestIDSubStr('resource-card') + cy.getByTestID('label-card--description') .eq(i) - .should('have.text', 'Description: ' + names[i].description) + .should('have.text', names[i].description) } }) // check sort desc - cy.getByTestID('sorter--desc').click() + cy.getByTestID('resource-sorter--button') + .click() + .then(() => { + cy.getByTestID('resource-sorter--properties.description-desc').click() + }) - cy.getByTestIDSubStr('resource-card').then(labels => { + cy.getByTestID('label-card').then(labels => { for (let i = 0; i < labels.length; i++) { - cy.getByTestIDSubStr('resource-card') + cy.getByTestID('label-card--description') .eq(i) - .should( - 'have.text', - 'Description: ' + names[labels.length - (i + 1)].description - ) + .should('have.text', names[labels.length - (i + 1)].description) } }) }) diff --git a/ui/cypress/e2e/variables.test.ts b/ui/cypress/e2e/variables.test.ts index 64125540a7..8674c822c3 100644 --- a/ui/cypress/e2e/variables.test.ts +++ b/ui/cypress/e2e/variables.test.ts @@ -42,7 +42,7 @@ describe('Variables', () => { }) it('keeps user input in text area when attempting to import invalid JSON', () => { - cy.get('.tabbed-page-section--header').within(() => { + cy.getByTestID('tabbed-page--header').within(() => { cy.contains('Create').click() }) diff --git a/ui/src/authorizations/components/TokensTab.tsx b/ui/src/authorizations/components/TokensTab.tsx index 32d8d8d08b..2a346d2bbe 100644 --- a/ui/src/authorizations/components/TokensTab.tsx +++ b/ui/src/authorizations/components/TokensTab.tsx @@ -55,20 +55,28 @@ class TokensTab extends PureComponent { const {searchTerm, sortKey, sortDirection, sortType} = this.state const {tokens} = this.props + const leftHeaderItems = ( + + ) + + const rightHeaderItems = ( + + ) + return ( <> - - - - + ( - +
What is a Bucket?
diff --git a/ui/src/buckets/components/BucketList.tsx b/ui/src/buckets/components/BucketList.tsx index 51701c7f0d..92b06c7bf6 100644 --- a/ui/src/buckets/components/BucketList.tsx +++ b/ui/src/buckets/components/BucketList.tsx @@ -18,8 +18,6 @@ import {Sort} from '@influxdata/clockface' // Utils import {SortTypes} from 'src/shared/utils/sort' -type SortKey = keyof Bucket | 'retentionRules[0].everySeconds' - interface Props { buckets: Bucket[] emptyState: JSX.Element @@ -29,9 +27,6 @@ interface Props { sortKey: string sortDirection: Sort sortType: SortTypes - onClickColumn: ( - sortType: SortTypes - ) => (nextSort: Sort, sortKey: SortKey) => void } class BucketList extends PureComponent { @@ -40,38 +35,15 @@ class BucketList extends PureComponent { ) public render() { - const {sortKey, sortDirection, onClickColumn} = this.props return ( - <> - - - - - - - {this.listBuckets} - - - + + + {this.listBuckets} + + ) } - private get headerKeys(): SortKey[] { - return ['name', 'retentionRules[0].everySeconds'] - } - private get listBuckets(): JSX.Element[] { const { buckets, diff --git a/ui/src/buckets/components/BucketsTab.tsx b/ui/src/buckets/components/BucketsTab.tsx index 0c56d0831a..1d1d894e16 100644 --- a/ui/src/buckets/components/BucketsTab.tsx +++ b/ui/src/buckets/components/BucketsTab.tsx @@ -18,13 +18,15 @@ import { Overlay, } from '@influxdata/clockface' import SearchWidget from 'src/shared/components/search_widget/SearchWidget' -import SettingsTabbedPageHeader from 'src/settings/components/SettingsTabbedPageHeader' +import TabbedPageHeader from 'src/shared/components/tabbed_page/TabbedPageHeader' import FilterList from 'src/shared/components/FilterList' import BucketList from 'src/buckets/components/BucketList' import CreateBucketOverlay from 'src/buckets/components/CreateBucketOverlay' import AssetLimitAlert from 'src/cloud/components/AssetLimitAlert' import BucketExplainer from 'src/buckets/components/BucketExplainer' import DemoDataDropdown from 'src/buckets/components/DemoDataDropdown' +import {FeatureFlag} from 'src/shared/utils/featureFlag' +import ResourceSortDropdown from 'src/shared/components/resource_sort_dropdown/ResourceSortDropdown' // Actions import { @@ -58,6 +60,7 @@ import { ResourceType, OwnBucket, } from 'src/types' +import {BucketSortKey} from 'src/shared/components/resource_sort_dropdown/generateSortItems' interface StateProps { org: Organization @@ -78,15 +81,13 @@ interface DispatchProps { interface State { searchTerm: string overlayState: OverlayState - sortKey: SortKey + sortKey: BucketSortKey sortDirection: Sort sortType: SortTypes } type Props = DispatchProps & StateProps -type SortKey = keyof Bucket - const FilterBuckets = FilterList() @ErrorHandling @@ -126,6 +127,46 @@ class BucketsTab extends PureComponent { sortType, } = this.state + const leftHeaderItems = ( + <> + + + + ) + + const rightHeaderItems = ( + <> + + {demoDataBuckets.length > 0 && ( + + )} + +