fix(bucket-list): wrapped DWP in featureFlag and sorted bucket list (#15769)
* fix(bucket-list): wrapped DWP in featureFlag and sorted bucket list * chore(changelog): updated the changelog to reflect PR changes * fix(e2e): skipping tests until featureflag removed from DWP * chore(tests): refactoring to use selector and add tests * chore(refactor): created selector for ordering bucketlist and added tests * fix(bucketsort): updated func and var names to accurately reflect intent * fix(bucket/selector): renamed func for accuracypull/15790/head
parent
bb6aa1df3b
commit
afb4667b15
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
1. [15777](https://github.com/influxdata/influxdb/pull/15777): Fix long startup when running 'influx help'
|
||||
1. [15731](https://github.com/influxdata/influxdb/pull/15731): Ensure array cursor iterator stats accumulate all cursor stats
|
||||
1. [15766](https://github.com/influxdata/influxdb/pull/15766): Reset delete with predicate state after submission
|
||||
|
||||
## v2.0.0-alpha.19 [2019-10-30]
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,54 @@ describe('Buckets', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('delete with predicate', () => {
|
||||
// skipping until feature flag feature is removed for deleteWithPredicate
|
||||
describe.skip('should alphabetize buckets in dropdown', () => {
|
||||
beforeEach(() => {
|
||||
cy.get<Organization>('@org').then(({id, name}) => {
|
||||
cy.createBucket(id, name, 'Funky Town').then(() => {
|
||||
cy.createBucket(id, name, 'ABC').then(() => {
|
||||
cy.createBucket(id, name, 'Jimmy Mack')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('alphabetizes buckets', () => {
|
||||
cy.getByTestID('bucket-delete-task')
|
||||
.first()
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.getByTestID('dropdown--button')
|
||||
.contains('ABC')
|
||||
.click()
|
||||
.then(() => {
|
||||
// get the bucket list
|
||||
cy.get('.cf-dropdown-item--children')
|
||||
.should('have.length', 6)
|
||||
.then(el => {
|
||||
const results = []
|
||||
// output in an array
|
||||
el.text((index, currentContent) => {
|
||||
results[index] = currentContent
|
||||
})
|
||||
const expectedOrder = [
|
||||
'ABC',
|
||||
'defbuck',
|
||||
'Funky Town',
|
||||
'Jimmy Mack',
|
||||
'_tasks',
|
||||
'_monitoring',
|
||||
]
|
||||
// check the order
|
||||
expect(results).to.deep.equal(expectedOrder)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// skipping until feature flag feature is removed for deleteWithPredicate
|
||||
describe.skip('delete with predicate', () => {
|
||||
beforeEach(() => {
|
||||
cy.getByTestID('bucket-delete-task').click()
|
||||
cy.getByTestID('overlay--container').should('have.length', 1)
|
||||
|
|
|
|||
|
|
@ -417,7 +417,8 @@ describe('DataExplorer', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('delete with predicate', () => {
|
||||
// skipping until feature flag feature is removed for deleteWithPredicate
|
||||
describe.skip('delete with predicate', () => {
|
||||
beforeEach(() => {
|
||||
cy.getByTestID('delete-data-predicate').click()
|
||||
cy.getByTestID('overlay--container').should('have.length', 1)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
} from '@influxdata/clockface'
|
||||
import BucketContextMenu from 'src/buckets/components/BucketContextMenu'
|
||||
import BucketAddDataButton from 'src/buckets/components/BucketAddDataButton'
|
||||
import {FeatureFlag} from 'src/shared/utils/featureFlag'
|
||||
|
||||
// Constants
|
||||
import {isSystemBucket} from 'src/buckets/constants/index'
|
||||
|
|
@ -114,12 +115,14 @@ class BucketRow extends PureComponent<Props & WithRouterProps> {
|
|||
size={ComponentSize.ExtraSmall}
|
||||
onClick={this.handleRenameBucket}
|
||||
/>
|
||||
<Button
|
||||
text="Delete Data By Filter"
|
||||
testID="bucket-delete-task"
|
||||
size={ComponentSize.ExtraSmall}
|
||||
onClick={this.handleDeleteData}
|
||||
/>
|
||||
<FeatureFlag name="deleteWithPredicate">
|
||||
<Button
|
||||
text="Delete Data By Filter"
|
||||
testID="bucket-delete-task"
|
||||
size={ComponentSize.ExtraSmall}
|
||||
onClick={this.handleDeleteData}
|
||||
/>
|
||||
</FeatureFlag>
|
||||
</FlexBox>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,175 @@
|
|||
// Funcs
|
||||
import {isSystemBucket, getSortedBucketNames, SYSTEM} from './index'
|
||||
|
||||
// Types
|
||||
import {Bucket} from 'src/types'
|
||||
|
||||
describe('Bucket Selector', () => {
|
||||
it('should return true when a default bucket is passed', () => {
|
||||
expect(isSystemBucket(SYSTEM)).toEqual(true)
|
||||
})
|
||||
it('should return false when no default bucket is passed', () => {
|
||||
expect(isSystemBucket(`_${SYSTEM}`)).toEqual(false)
|
||||
expect(isSystemBucket(`naming_${SYSTEM}`)).toEqual(false)
|
||||
expect(isSystemBucket('SYSTEM')).toEqual(false)
|
||||
})
|
||||
it('should sort the bucket names alphabetically', () => {
|
||||
const buckets: Bucket[] = [
|
||||
{
|
||||
id: '7902bd683453c00c',
|
||||
orgID: 'e483753c9bdb47bf',
|
||||
type: 'user',
|
||||
name: 'alpha',
|
||||
retentionRules: [],
|
||||
createdAt: '2019-11-05T08:57:54.459819-08:00',
|
||||
updatedAt: '2019-11-05T08:58:09.593805-08:00',
|
||||
links: {
|
||||
labels: '/api/v2/buckets/7902bd683453c00c/labels',
|
||||
logs: '/api/v2/buckets/7902bd683453c00c/logs',
|
||||
members: '/api/v2/buckets/7902bd683453c00c/members',
|
||||
org: '/api/v2/orgs/e483753c9bdb47bf',
|
||||
owners: '/api/v2/buckets/7902bd683453c00c/owners',
|
||||
self: '/api/v2/buckets/7902bd683453c00c',
|
||||
write: '/api/v2/write?org=e483753c9bdb47bf&bucket=7902bd683453c00c',
|
||||
},
|
||||
labels: [],
|
||||
},
|
||||
{
|
||||
id: '7f44462ac794c7c1',
|
||||
orgID: 'e483753c9bdb47bf',
|
||||
type: 'user',
|
||||
name: 'bucket1',
|
||||
retentionRules: [],
|
||||
createdAt: '2019-10-15T11:10:27.970567-07:00',
|
||||
updatedAt: '2019-10-15T11:10:27.970567-07:00',
|
||||
links: {
|
||||
labels: '/api/v2/buckets/7f44462ac794c7c1/labels',
|
||||
logs: '/api/v2/buckets/7f44462ac794c7c1/logs',
|
||||
members: '/api/v2/buckets/7f44462ac794c7c1/members',
|
||||
org: '/api/v2/orgs/e483753c9bdb47bf',
|
||||
owners: '/api/v2/buckets/7f44462ac794c7c1/owners',
|
||||
self: '/api/v2/buckets/7f44462ac794c7c1',
|
||||
write: '/api/v2/write?org=e483753c9bdb47bf&bucket=7f44462ac794c7c1',
|
||||
},
|
||||
labels: [],
|
||||
},
|
||||
{
|
||||
id: 'a8fee6b433c16f86',
|
||||
orgID: 'e483753c9bdb47bf',
|
||||
type: 'user',
|
||||
name: 'zebra',
|
||||
retentionRules: [],
|
||||
createdAt: '2019-11-05T08:57:59.280485-08:00',
|
||||
updatedAt: '2019-11-05T08:57:59.280486-08:00',
|
||||
links: {
|
||||
labels: '/api/v2/buckets/a8fee6b433c16f86/labels',
|
||||
logs: '/api/v2/buckets/a8fee6b433c16f86/logs',
|
||||
members: '/api/v2/buckets/a8fee6b433c16f86/members',
|
||||
org: '/api/v2/orgs/e483753c9bdb47bf',
|
||||
owners: '/api/v2/buckets/a8fee6b433c16f86/owners',
|
||||
self: '/api/v2/buckets/a8fee6b433c16f86',
|
||||
write: '/api/v2/write?org=e483753c9bdb47bf&bucket=a8fee6b433c16f86',
|
||||
},
|
||||
labels: [],
|
||||
},
|
||||
{
|
||||
id: 'adbb0107da2d7d38',
|
||||
orgID: 'e483753c9bdb47bf',
|
||||
type: 'user',
|
||||
name: 'buck2',
|
||||
retentionRules: [],
|
||||
createdAt: '2019-10-18T14:05:24.838291-07:00',
|
||||
updatedAt: '2019-10-18T14:05:24.838292-07:00',
|
||||
links: {
|
||||
labels: '/api/v2/buckets/adbb0107da2d7d38/labels',
|
||||
logs: '/api/v2/buckets/adbb0107da2d7d38/logs',
|
||||
members: '/api/v2/buckets/adbb0107da2d7d38/members',
|
||||
org: '/api/v2/orgs/e483753c9bdb47bf',
|
||||
owners: '/api/v2/buckets/adbb0107da2d7d38/owners',
|
||||
self: '/api/v2/buckets/adbb0107da2d7d38',
|
||||
write: '/api/v2/write?org=e483753c9bdb47bf&bucket=adbb0107da2d7d38',
|
||||
},
|
||||
labels: [],
|
||||
},
|
||||
{
|
||||
id: 'e2871ad8f92e752a',
|
||||
orgID: 'e483753c9bdb47bf',
|
||||
type: 'user',
|
||||
name: 'disco inferno',
|
||||
retentionRules: [],
|
||||
createdAt: '2019-11-05T08:58:16.873502-08:00',
|
||||
updatedAt: '2019-11-05T08:58:16.873502-08:00',
|
||||
links: {
|
||||
labels: '/api/v2/buckets/e2871ad8f92e752a/labels',
|
||||
logs: '/api/v2/buckets/e2871ad8f92e752a/logs',
|
||||
members: '/api/v2/buckets/e2871ad8f92e752a/members',
|
||||
org: '/api/v2/orgs/e483753c9bdb47bf',
|
||||
owners: '/api/v2/buckets/e2871ad8f92e752a/owners',
|
||||
self: '/api/v2/buckets/e2871ad8f92e752a',
|
||||
write: '/api/v2/write?org=e483753c9bdb47bf&bucket=e2871ad8f92e752a',
|
||||
},
|
||||
labels: [],
|
||||
},
|
||||
{
|
||||
id: '000000000000000a',
|
||||
type: 'system',
|
||||
description: 'System bucket for task logs',
|
||||
name: '_tasks',
|
||||
retentionRules: [
|
||||
{
|
||||
type: 'expire',
|
||||
everySeconds: 259200,
|
||||
},
|
||||
],
|
||||
createdAt: '0001-01-01T00:00:00Z',
|
||||
updatedAt: '0001-01-01T00:00:00Z',
|
||||
links: {
|
||||
labels: '/api/v2/buckets/000000000000000a/labels',
|
||||
logs: '/api/v2/buckets/000000000000000a/logs',
|
||||
members: '/api/v2/buckets/000000000000000a/members',
|
||||
org: '/api/v2/orgs/',
|
||||
owners: '/api/v2/buckets/000000000000000a/owners',
|
||||
self: '/api/v2/buckets/000000000000000a',
|
||||
write: '/api/v2/write?org=&bucket=000000000000000a',
|
||||
},
|
||||
labels: [],
|
||||
},
|
||||
{
|
||||
id: '000000000000000b',
|
||||
type: 'system',
|
||||
description: 'System bucket for monitoring logs',
|
||||
name: '_monitoring',
|
||||
retentionRules: [
|
||||
{
|
||||
type: 'expire',
|
||||
everySeconds: 604800,
|
||||
},
|
||||
],
|
||||
createdAt: '0001-01-01T00:00:00Z',
|
||||
updatedAt: '0001-01-01T00:00:00Z',
|
||||
links: {
|
||||
labels: '/api/v2/buckets/000000000000000b/labels',
|
||||
logs: '/api/v2/buckets/000000000000000b/logs',
|
||||
members: '/api/v2/buckets/000000000000000b/members',
|
||||
org: '/api/v2/orgs/',
|
||||
owners: '/api/v2/buckets/000000000000000b/owners',
|
||||
self: '/api/v2/buckets/000000000000000b',
|
||||
write: '/api/v2/write?org=&bucket=000000000000000b',
|
||||
},
|
||||
labels: [],
|
||||
},
|
||||
]
|
||||
|
||||
const results = getSortedBucketNames(buckets)
|
||||
const expectedResult = [
|
||||
'alpha',
|
||||
'buck2',
|
||||
'bucket1',
|
||||
'disco inferno',
|
||||
'zebra',
|
||||
'_monitoring',
|
||||
'_tasks',
|
||||
]
|
||||
expect(results).toEqual(expectedResult)
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// Types
|
||||
import {Bucket} from 'src/types'
|
||||
|
||||
export const SYSTEM = 'system'
|
||||
|
||||
export const isSystemBucket = (type: string): boolean => type === SYSTEM
|
||||
|
||||
export const getSortedBucketNames = (buckets: Bucket[]) =>
|
||||
buckets
|
||||
.sort((a, b) => {
|
||||
const firstBucket = `${a.name}`.toLowerCase()
|
||||
const secondBucket = `${b.name}`.toLowerCase()
|
||||
if (firstBucket === secondBucket) {
|
||||
return 0
|
||||
}
|
||||
if (isSystemBucket(a.type)) {
|
||||
// ensures that the default system types are the last buckets
|
||||
return 1
|
||||
}
|
||||
if (isSystemBucket(b.type)) {
|
||||
// ensures that the default system types are the last buckets
|
||||
return -1
|
||||
}
|
||||
if (firstBucket < secondBucket) {
|
||||
return -1
|
||||
}
|
||||
if (firstBucket > secondBucket) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
.map(bucket => bucket.name)
|
||||
|
|
@ -4,6 +4,7 @@ import {withRouter, WithRouterProps} from 'react-router'
|
|||
|
||||
// Components
|
||||
import {Button} from '@influxdata/clockface'
|
||||
import {FeatureFlag} from 'src/shared/utils/featureFlag'
|
||||
|
||||
const DeleteDataButton: FunctionComponent<WithRouterProps> = ({
|
||||
location: {pathname},
|
||||
|
|
@ -12,12 +13,14 @@ const DeleteDataButton: FunctionComponent<WithRouterProps> = ({
|
|||
const onClick = () => router.push(`${pathname}/delete-data`)
|
||||
|
||||
return (
|
||||
<Button
|
||||
testID="delete-data-predicate"
|
||||
text="Delete Data"
|
||||
onClick={onClick}
|
||||
titleText="Filter and mark data for deletion"
|
||||
/>
|
||||
<FeatureFlag name="deleteWithPredicate">
|
||||
<Button
|
||||
testID="delete-data-predicate"
|
||||
text="Delete Data"
|
||||
onClick={onClick}
|
||||
titleText="Filter and mark data for deletion"
|
||||
/>
|
||||
</FeatureFlag>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,13 @@ import {connect} from 'react-redux'
|
|||
import {SelectDropdown} from '@influxdata/clockface'
|
||||
|
||||
// Types
|
||||
import {AppState, Bucket} from 'src/types'
|
||||
import {AppState} from 'src/types'
|
||||
|
||||
// Selectors
|
||||
import {getSortedBucketNames} from 'src/buckets/selectors/index'
|
||||
|
||||
interface StateProps {
|
||||
buckets: Bucket[]
|
||||
bucketNames: string[]
|
||||
}
|
||||
|
||||
interface OwnProps {
|
||||
|
|
@ -18,11 +21,10 @@ interface OwnProps {
|
|||
type Props = StateProps & OwnProps
|
||||
|
||||
const BucketsDropdown: FunctionComponent<Props> = ({
|
||||
buckets,
|
||||
bucketNames,
|
||||
bucketName,
|
||||
onSetBucketName,
|
||||
}) => {
|
||||
const bucketNames = buckets.map(bucket => bucket.name)
|
||||
return (
|
||||
<SelectDropdown
|
||||
options={bucketNames}
|
||||
|
|
@ -32,8 +34,12 @@ const BucketsDropdown: FunctionComponent<Props> = ({
|
|||
)
|
||||
}
|
||||
|
||||
const mstp = (state: AppState): StateProps => ({
|
||||
buckets: state.buckets.list,
|
||||
})
|
||||
const mstp = (state: AppState): StateProps => {
|
||||
// map names and sort via a selector
|
||||
const buckets = getSortedBucketNames(state.buckets.list)
|
||||
return {
|
||||
bucketNames: buckets,
|
||||
}
|
||||
}
|
||||
|
||||
export default connect<StateProps, {}, OwnProps>(mstp)(BucketsDropdown)
|
||||
|
|
|
|||
Loading…
Reference in New Issue